【Unity】scriptableobjectのリストをExcelに表示してみた

Unity

Unity初心者です。

初心者の為、いろいろな場所で躓くので、備忘録として実施した技術についてブログに記載するようにしています。

現在作成しているゲームのゲームデータの管理をUnity標準のscriptableobjectを使用して行っているのですが、そのファイルが増えすぎてしまい収集がつかなくなってしまいました

暫定対策として、scriptableobjectのリストをExcelで表示するVBAで作ってみたので紹介したいと思います。

scriptableobjectが増えすぎてリスト化必須になった

現在、カードゲームを作成しているのですが、そのカードデータをscriptableobjectを使用して管理しています。

最初は「scriptableobjectで作るのはすごい便利だなあ」と思っていたのですが、データが増えるにつれてメンテンナンスが面倒になってきました。

現在は…

こんな感じになってしまっておりまして、データを変更するにも、どのデータがどのカードかわからなくなってしまいました。

ファイル名をオブジェクトを特定できるようなものにしてしまうと、ファイルをロードする時にIDでロードできなくなってしまうのでやりたく有りません。

例えば「薬草」というアイテムのデータに「薬草.asset」というファイル名をつけてしまうと、「薬草」という文字列をセーブデータ内で持ちたくなります。

そうするとアイテム名を変更したい時に非常に困ります。

なのでファイル名はID(数値)のままで見分けがつくような方法を検討する必要があります。

暫定対策でExcelでscriptableobjectのリストを書き出してみた

とりあえず、どのファイルが何なのか確認するのが先決だったので、Excelに一覧を書き出してみることにしました

↓こんな感じでExcelにscriptableobjectを書き出します。

iconは正直復元するのが難しかったのでAssetに記載されているものをそのまま転記しています。

また配列の項目は、[]内に値を書いてみる感じにしました。上記画像で言うとskillsという項目が配列項目です。

書き出しに使ったVBAマクロが以下になります。

Private Const startRow = 3
Private Const startCol = 2

Public Sub readAsset()
    Dim path As String
    Dim fso As Object
    Dim file As Object
    Dim files As Object
    Dim i As Integer
    Dim sh As Worksheet
    Dim row As Long
    Dim col As Integer
    Dim dic As Object
    
    Set sh = ThisWorkbook.ActiveSheet
    row = startRow
    Application.ScreenUpdating = False
    
    i = MsgBox("現在開いているシートに書き込みます。処理を実行しますか?", vbYesNo + vbQuestion, "確認")
    If i <> vbYes Then Exit Sub
    
    With Application.FileDialog(msoFileDialogFolderPicker)
        If .Show = True Then
            path = .SelectedItems(1)
        Else
            Exit Sub
        End If
    End With

    Set fso = CreateObject("Scripting.FileSystemObject")
    Set files = fso.GetFolder(path).files
    sh.Cells.Clear

    For Each file In files
        If fso.GetExtensionName(file.path) = "asset" Then
            Call readFile(file.path, file.Name, dic)
            col = startCol
            If row = startRow Then
                For Each Key In dic.Keys
                    sh.Cells(row, col) = Key
                    col = col + 1
                Next
                row = row + 1
                col = startCol
            End If
            
            For Each Key In dic.Keys
                sh.Cells(row, col) = dic.Item(Key)
                col = col + 1
            Next
            row = row + 1
        End If
    Next file

    Application.ScreenUpdating = True

End Sub

Private Sub readFile(ByVal path As String, ByVal fileName As String, ByRef dic As Object)
    Dim buf As String
    Dim tmp As Variant
    Dim tmp2 As Variant
    Dim monoflg As Boolean
    Dim prevKey As String
    
    Set dic = CreateObject("Scripting.Dictionary")
    
    Open path For Input As #1
        Do Until EOF(1)
            Line Input #1, buf
        Loop
    Close #1
    
    tmp = Split(buf, vbLf)
    monoflg = False
    dic.Add "ファイル名", Replace(fileName, "asset", "")
    For i = 0 To UBound(tmp) - 1
        tmp(i) = Trim(tmp(i))
        If monoflg And Not dic.Exists(tmp(i)) And Len(tmp(i)) > 2 And Left(tmp(i), 2) <> "m_" Then
            tmp2 = Split(tmp(i), ":", 2)
            If UBound(tmp2) > 0 Then
                tmp2(1) = Replace(tmp2(1), """", "")
                tmp2(1) = unicodeEscape(CStr(tmp2(1)))
                dic.Add tmp2(0), tmp2(1)
                prevKey = tmp2(0)
            ElseIf Left(tmp2(0), 2) = "- " And dic.Exists(prevKey) Then
                tmp2(0) = Replace(tmp2(0), "- ", "")
                If dic.Item(prevKey) = "" Then
                    dic.Item(prevKey) = "[" & tmp2(0) & "]"
                Else
                    dic.Item(prevKey) = Replace(dic.Item(prevKey), "]", "") & "," & tmp2(0) & "]"
                End If
            End If
        End If
        If tmp(i) = "MonoBehaviour:" Then monoflg = True
    Next i
    
End Sub

Function unicodeEscape(src As String)
    Dim v As Variant
    Dim i As Integer
    Dim ret As String
    Dim re As Object

    Set re = CreateObject("VBScript.RegExp")
    With re
        .Global = True
        .IgnoreCase = True
        .Pattern = "\u([a-fA-F0-9]{4})"
        If .test(src) Then
            v = Split(src, "\u")
            ret = ""
            For i = 1 To UBound(v)
                ret = ret & ChrW(Val("&H" & v(i)))
            Next
            unicodeEscape = ret
        Else
            unicodeEscape = src
        End If
    End With
End Function

男気あふれるコメント0。

まあUnityのブログなのでVBAの細かい解説は良いかなあと思いまして…。

文字列がUnicodeだったり、改行がLfだったり、配列項目が「- 」だったりして複雑なのでコードもかなりごちゃごちゃしてしまいました。

scriptableobjectをエディタで開くと以下のような感じになっていまして、これを無理やりExcelの連想配列に直している感じです

上記マクロを含んだExcelファイルも以下にアップロードしてみました。

https://unitygame.slavesystems.com/game/scriptableobject取得.xlsm

使い方

1.Excelを開いて「取得」ボタンをクリックします

2.確認ダイアログで「はい」をクリックします

3.scriptableobjectが存在するフォルダをクリックします

4.指定したフォルダ内のscriptableobjectがExcelに書き出されます

scriptableobjectを使用した事による反省点

ゲームデータの作成だと、scriptableobjectをおすすめしている方が多いので、自分の使い方が悪い可能性は高いのですが、正直管理が難しいと思いました。

(データを複製したりするのは非常に便利でしたが)

今後ゲームのデータを作るときはJson形式にしようかなあと思っています。

Jsonを読み込む形式であれば、Excelで管理してデータをJsonでエクスポートするとかも出来そうです。

デバッグで変更できない点と、画像ファイル等の指定だけは面倒くさそうですが…。

もしくは、scriptableobjectの使い方をもっと勉強したいですね。

コメント

タイトルとURLをコピーしました