困った時の自分用メモ

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

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申請関係のコスト・リスクは度外視のお話ですので、あしからず