【Unity】Luaの関数を実行する【Fungus】


複数のLuaファイルの中から、特定の会話パートを再生したい場合を解決するスクリプトを紹介したいと思います。

FungusのLuaScriptを拡張したLuaScriptExになります。

インスペクターに複数のLuaファイルを登録し、関数OnExecuteでLuaの関数を実行します。

using UnityEngine;
using MoonSharp.Interpreter;
using Debug = UnityEngine.Debug;
using System.Text;
using System.Collections.Generic;

namespace Fungus
{
    /// <summary>
    /// Executes Lua script defined in a string property or in an external file.
    /// </summary>
    public class LuaScriptEx : MonoBehaviour
    {
        [SerializeField] protected LuaEnvironment luaEnvironment;

        /// <summary>
        /// Run the script as a Lua coroutine so execution can be yielded for asynchronous operations.
        /// </summary>
        [Tooltip("Run the script as a Lua coroutine so execution can be yielded for asynchronous operations.")]
        [SerializeField] protected bool runAsCoroutine = true;

        [SerializeField] protected List<TextAsset> luaFiles;

        protected string _friendlyName = "";

        protected bool _initialised;

        // This is public so the editor code can force the component to reinitialise
        public bool Initialised { set { _initialised = value; } }

        // Stores the compiled Lua code for fast execution later.
        protected Closure _luaFunction;

        private string _loadLuaFile = string.Empty;

        // Recursively build the full hierarchy path to this game object
        protected static string GetPath(Transform current)
        {
            if (current.parent == null)
            {
                return current.name;
            }
            return GetPath(current.parent) + "." + current.name;
        }

        protected virtual void Start()
        {
            InitLuaScript();
        }

        /// <summary>
        /// Initialises the Lua environment and compiles the Lua string for execution later on.
        /// </summary>
        protected virtual void InitLuaScript()
        {
            if (_initialised)
            {
                return;
            }

            if (luaEnvironment == null)
            {
                // Create a Lua Environment if none exists yet
                luaEnvironment = LuaEnvironment.GetLua();
            }

            if (luaEnvironment == null)
            {
                Debug.LogError("No Lua Environment found");
                return;
            }

            // Ensure the LuaEnvironment is initialized before trying to execute code
            luaEnvironment.InitEnvironment();

            // Cache a descriptive name to use in Lua error messages
            _friendlyName = GetPath(transform) + ".LuaScript";

            _initialised = true;
        }

        /// <summary>
        /// Returns the Lua string to be executed. 
        /// This is the contents of the Lua script appended to the contents of the Lua file.
        /// </summary>
        /// <returns>The lua string.</returns>
        protected virtual string GetLuaString()
        {
            StringBuilder sb = new StringBuilder();

            if (luaFiles != null && luaFiles.Count > 0)
            {
                foreach (var luaFile in luaFiles)
                {
                    sb.AppendLine(luaFile.text);
                }

            }

            return sb.ToString();
        }

        #region Public members

        public virtual void OnExecute(string excuteLuaString)
        {
            // Make sure the script and Lua environment are initialised before executing
            InitLuaScript();

            StringBuilder sb = new StringBuilder();

            if (string.IsNullOrEmpty(_loadLuaFile))
            {
                _loadLuaFile = GetLuaString();
            }

            sb.AppendLine(_loadLuaFile);

            sb.AppendLine(excuteLuaString);

            luaEnvironment.DoLuaString(sb.ToString(), _friendlyName, runAsCoroutine);
        }

        #endregion
    }
}