【Unity】【xLua】LuaとC#をまたいでオブジェクト指向な実装をする

xLuaでLuaC#をまたいでオブジェクト指向な実装をする方法についてまとめました。

Unity2020.2.6
xLua 2.1.15

xLua?

xLuaはUnityでLuaを取り扱うためのライブラリです。
Tencentが開発しており、MITライセンスで利用することができます。

github.com

基本的な使い方は以下の記事にまとめていますので必要に応じて参照してください。

light11.hatenadiary.com

課題

さてxLuaでは以下のようにグローバルな変数にC#から値を代入できます。

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;

public class Example : MonoBehaviour
{
    private LuaEnv _luaEnv;

    [SerializeField] private TextAsset _lua;
    
    void Awake()
    {
        // Luaのグローバル変数fooValに値を代入
        _luaEnv = new LuaEnv();
        _luaEnv.Global.Set("fooVal", 123);
        _luaEnv.DoString(_lua.text);
    }

    private void Update()
    {
        if (_luaEnv != null)
        {
            _luaEnv.Tick();
        }
    }

    private void OnDestroy()
    {
        _luaEnv.Dispose();
    }
}

しかしこの方法では複数のLuaスクリプトを読み込んだ際に全てのスクリプトに同じ値が代入されます。
また、それらのスクリプトからrequireで読み込んだスクリプトにも同じ値が代入されます。

Luaにおけるオブジェクト指向

このような場合にはクラスのインスタンスを作成して、そのインスタンスにのみ値を設定します。
つまり、テーブルを作ってメタテーブルでグローバル環境との継承関係を作り、そのテーブルの変数に値を代入します。

この辺りのLuaにおけるオブジェクト指向の基礎知識については以下の記事にまとめているので、必要に応じて参照してください。

light11.hatenadiary.com

特定の環境の変数にだけ値を代入する

さてそれでは実際にC#からLuaのテーブルやメタテーブルを作ってオブジェクト指向を実装してみます。
以下ではスクリプト実行用にテーブルを用意し、そのスクリプトの変数に値を受け渡しています。

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;

public class Example : MonoBehaviour
{
    private LuaEnv _luaEnv;
    private LuaTable _scriptEnv;

    [SerializeField] private TextAsset _lua;
    
    void Awake()
    {
        _luaEnv = new LuaEnv();
        // テーブルを作る
        _scriptEnv = _luaEnv.NewTable();

        // メタテーブルを設定する
        var meta = _luaEnv.NewTable();
        meta.Set("__index", _luaEnv.Global);
        _scriptEnv.SetMetaTable(meta);
        meta.Dispose();

        // scriptEnvに対してだけ値を設定
        _scriptEnv.Set("fooVal", 123);

        _luaEnv.DoString(_lua.text, "example", _scriptEnv);
    }

    private void Update()
    {
        if (_luaEnv != null)
        {
            _luaEnv.Tick();
        }
    }

    private void OnDestroy()
    {
        _scriptEnv.Dispose();
        _luaEnv.Dispose();
    }
}

関連

light11.hatenadiary.com

light11.hatenadiary.com