困った時の自分用メモ

読んだ本を考察してメモったり、自分でいじった物の感想をメモったりする場。週1更新を目指します。

Unityの話~Lua形式のファイルをアセットバンドル化しようとして、速攻躓いた件~

Unrecognized assets cannot be included in AssetBundles: "Assets/StreamingAssets/EnemyManager.lua".

 

このように出て、アセットバンドルに入れられない。.lua拡張子は対応していないようだ。

 

〇StreamingAssets内に入っていると、拡張子がtxtでもダメ

〇Resources以下にtxt形式にすればOK

〇Resources以下でも、拡張子がluaだとNG

〇ただ、マニフェストファイルを見ると、含まれているような挙動をみせる

〇ロードしようとすると、やっぱり読めない

〇Unity上では、lua形式のファイルはDefaultAssetとして認識されているようだ

CSVはテキストアセット扱いのようである

 

最初からtxt拡張子にしてもいいのだが、そうするとVIM上でシンタックスが効かなくなるので、作業ディレクトリでは拡張子luaで作業し、アセットバンドルフォルダにコピーして拡張子をtxtに変えるbatファイルを作って対処。

 

del "..\Resources\ForAssetbundle\*.txt"
copy "*.lua" "..\Resources\ForAssetbundle"
rename "..\Resources\ForAssetbundle\*.lua" "*.txt"
pause

Unityの話~StreamingAssets以下に全角文字のファイル名のファイルがあると、Android実機転送が失敗する話~

StreamingAssetsフォルダ以下に、全角文字が入ったファイル名を置くと、Android実機転送時に、

 

C:\****\cocos_android\android-sdk-windows\build-tools\build-tools-23.0.1\aapt.exe package -v -f -F raw.ap_ -A raw -0 ""

stderr[
raw\����������.lua: error: Invalid filename.  Unable to add.
]
stdout[
Found 67 custom asset files in raw
]

 

とか言われて、怒られる。注意されたし。

Luaの話~処理をLuaに移して感じた事~

〇便利だと感じる事

スクリプトの修正をしても、コンパイルが走らない
⇒Unity側も、マルチスレッドコンパイル?とか、待ち時間軽減しようと頑張っているけど、Luaなら待ち時間0。マジで0。修正して即プレイボタン押せる。
っていうか、Lua側の設計や使い方次第で実行中に読み込む処理のリロードも可能だと思われる。

 

〇不便だと感じる事

・ブレイクポイントデバッグが不可能
⇒ログ出力デバッグになる。ただ、実行時エラーは、Unity側から読み込んだ物は行数、doFileで追加したスクリプトに関しては、ファイル名と行数がUnity上にログ出力されるので、そこまでエラー箇所が意味不明な状態にはなりにくい。

・self関係がめんどくさい
⇒関数呼び出す時に、Class.Func()とClass:Func()で、引数に渡るものが変わってしまい、これ関係でバグ調査難航が何回もあったので、ルール決めとかないとアカンと思う。

・Utility機能系皆無。ほぼ自作
⇒あんまりLuaの書籍読んだり情報調べたりしてないから、もしかしたらそういうのあるのかもしれないけど、今のところ生のLuaのみで頑張って処理を書いている。

 

※パフォーマンスやApple申請関係のコスト・リスクは度外視のお話ですので、あしからず

 

Luaの話~データ設定でCSVを使う事が無くなるかも?~

ゲーム開発をした事がある人なら、誰しも一度はデータ設定の事について悩んだことがあると思う。
恐らく、大抵は「表計算ソフト」で入力されたものを、「プログラム上で扱える形式」に変換し、「変換された物を読み込んでパースし管理する」処理を記述する、
といった事をしたことがあるのではないかと思う。

しかし、Luaを使う場合は、
Luaスクリプトが、そもそも「プログラムで読み込める形式」(プレーンテキスト)で記述されている
・プレーンテキストなので、当然アセットバンドルにも組み込める(はず)なので、後から更新可能
Luaスクリプトで記述した物は、そのままオブジェクトとして利用可能←ここ重要

上記の特性から、変換とパースという作業が必要なくなる。
特に、3番目の記述した物が即利用可能というのが大きい。

例えば、こんな感じだ。

-----

EnemyConfig.lua

Enemy0001 = {
    ID = "0001",
    Name = "スライム",
    Hp = 3,
    Mp = 0,
    Attack = 1,
    EXP = 1,
}

Enemy0002 = {
    ID = "0002",
    Name = "ゴブリン",
    Hp = 5,
    Mp = 0,
    Attack = 3,
    EXP = 3,
}

GameMain.lua

function SpawnEnemy()
    local enemy1 = Enemy0001
    Print("名前"..enemy1.Name)--こんな関数はないけど、何か画面に表示する処理だと思ってもらえれば
    Print("HP"..enemy1.Hp)
    
    local enemy2 = Enemy0002
    Print("名前"..enemy2.Name)--こんな関数はないけど、何か画面に表示する処理だと思ってもらえれば
    Print("HP"..enemy2.Hp)
end

-----

UnityC#側だと、ScriptableObjectが似たような機能になるのかな?使った事ないんだけど(殴

もちろん、設定する要素数が増えたり、設定項目が複雑だったりすると、表計算を一次入力として利用し、
Luaスクリプト形式に変換する、といった事をやった方がいいと思うけど、
それでも、いちいちパース処理や管理クラス、読み込みマネージャを作る必要が無いのがいいかなと思う。
C#側でそれやろうとすると、それらを自動で作成するコードジェネレータを作らなければならなくなるのだが、
型のメタデータとか設計するのが非常にめんどくさいし、追加・保守も面倒だ(経験談

Luaなら、配列・小数・関数呼び出し設定からオブジェクト保持すらできるので、柔軟性は高い

-----
EnemyConfig.lua

-- クラス定義
EnemyParameter = {}
function EnemyParameter.new(hp, mp, atk, exp)
    local this = {
        LocalHp = hp,
        LocalMp = mp,
        LocalAttack = atk,
        LocalExp = exp,
    }
    
    this.Hp = function(self)
        return self.LocalHp
    end
    --以下、MPなども書く
    return this
end


Enemy0001 = {
    ID = "0001",
    Name = "スライム",
    Parameter = EnemyParameter.new(3, 0, 1, 1),--オブジェクトを持たせる事も可能
    FloatValue = 1.11,--小数も可能だし
    TableValue = {1,2,3,4,5},--配列(Luaではテーブルというけど)も可能
}

Enemy0002 = {
    ID = "0002",
    Name = "ゴブリン",
    Parameter = EnemyParameter.new(5, 0, 3, 3),
    FloatValue = 1.11,--小数も可能だし
    TableValue = {1,2,3,4,5},--配列(Luaではテーブルというけど)も可能
}

GameMain.lua

function SpawnEnemy()
    local enemy1 = Enemy0001
    Print("名前"..enemy1.Name)--こんな関数はないけど、何か画面に表示する処理だと思ってもらえれば
    Print("HP"..enemy1.Parameter:Hp())
    
    local enemy2 = Enemy0002
    Print("名前"..enemy2.Name)--こんな関数はないけど、何か画面に表示する処理だと思ってもらえれば
    Print("HP"..enemy2.Parameter:Hp())
end

-----

Lua側に全て処理を逃がすと、こういう事もできるようになるよ、というより「僕はそうやっているよ」というお話でした。

※パフォーマンスやApple申請関係のコスト・リスクは度外視のお話ですので、あしからず

Luaの話〜IOS実機で動かす際に、ネイティブプラグイン化する時の注意点〜

ぶっちゃけ、なんでこれで上手くいくかわからんけど、LUAのネイティブプラグインを作る時に、そのXCodeプロジェクトでいくつか設定が必要。

 

◯BuildSettings

・Architectures

→arm64 とだけにする

・Build Active Architexture Only

→No

◯Build Options

・Enable BitCode

→Yes

 

この辺やらないで作ったDLLでUnityのIOSビルドすると、XCode側のビルド終了間際に、そのDLLはarm64対応してる?だとか、BitCode EnableはYesになってる?的なことを指摘されるエラーが出るので、注意。

Luaの話~ブロック内のスコープ関係の話~

やらかしたミス

for i = 1, #skillTable do
    local table = skillTable[i]
    local val = #table
    LuaUnityDebugLog(#this.SkillMaxLevelList)
    table.insert(this.SkillMaxLevelList, val)
end

これをやると、table.insertの部分で「insertがnilっす」というエラーになる。
(正確には、attempt to call field 'insert' (a nil value))

理由は恐らく、local tableによって、このブロック内のtableは、skillTable[i]を指してしまっている為だろう。
んじゃ、本家のtableにアクセスしたい場合ってどうすればいいの?

シラネ^p^

 

とりあえず、tableって名前付けない事が一番。

Unityの話〜IOS実機にアプリを入れる時の注意点メモ〜

とりあえず、

MACのOSのバージョンを最新に(OS X El Capitan)(10.11.6)

XCodeのバージョンを最新に(8.1)

・UnityからXCodeプロジェクトを作成できて、ビルドが正常に通る、というところまでは上手くいくとする

 

詰まったところ。

・コードサインニング周り

→予め、AppleIDを作っておいて、プロジェクトメニューのGeneral→Signing→Teamを、その作ったアカウントに紐付ける。これは、毎回手動で設定する必要がある(Jenkinsからコマンドラインでビルドする場合は、何かしら方法はあると思う)。

・デバイス設定周り

→ビルド成功しても、このアプリは信頼されてないよ的なことを言われるので、デバイスの設定→一般→デバイス管理→登録してあるメアド?→信頼するを行う