/// <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"; string s = GetLuaString(); luaFunction = luaEnvironment.LoadLuaString(s, friendlyName); initialised = true; }
/// <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"; string s = GetLuaString(); luaFunction = luaEnvironment.LoadLuaFunction(s, friendlyName); initialised = true; }
/// <summary> /// Callback to bind this LuaStore component with the "unity" table in a LuaEnvironment component. /// </summary> public override void AddBindings(LuaEnvironment luaEnvironment) { if (!Init()) { return; } MoonSharp.Interpreter.Script interpreter = luaEnvironment.Interpreter; Table globals = interpreter.Globals; if (globals == null) { Debug.LogError("Lua globals table is null"); return; } // If the fungus global table is defined then add the store to it Table fungusTable = globals.Get("fungus").Table; if (fungusTable != null) { fungusTable["store"] = primeTable; } else { // Add the store as a global globals["store"] = primeTable; } }
/// <summary> /// Initialises the Lua environment and compiles the Lua string for execution later on. /// </summary> protected virtual void InitExecuteLua() { if (initialised) { return; } // Cache a descriptive name to use in Lua error messages friendlyName = gameObject.name + "." + parentBlock.blockName + "." + "ExecuteLua #" + commandIndex.ToString(); if (luaEnvironment == null) { luaEnvironment = LuaEnvironment.GetLua(); } string s = GetLuaString(); luaFunction = luaEnvironment.LoadLuaString(s, friendlyName); // Always initialise when playing in the editor. // Allows the user to edit the Lua script while the game is playing. if (!(Application.isPlaying && Application.isEditor)) { initialised = true; } }
public override void AddBindings(LuaEnvironment luaEnv) { if (!Init()) { return; } MoonSharp.Interpreter.Script interpreter = luaEnv.Interpreter; Table globals = interpreter.Globals; if (globals == null) { Debug.LogError("Lua globals table is null"); return; } // If the fungus global table is defined then add the store to it Table fungusTable = globals.Get("fungus").Table; if (fungusTable != null) { fungusTable["store"] = primeTable; } else { // Add the store as a global globals["store"] = primeTable; } }
protected IEnumerator CallLuaClosure(LuaEnvironment luaEnv, Closure callback) { yield return new WaitForEndOfFrame(); if (callback != null) { luaEnv.RunLuaFunction(callback, true); } }
protected IEnumerator CallLuaClosure(LuaEnvironment luaEnv, Closure callback) { yield return(new WaitForEndOfFrame()); if (callback != null) { luaEnv.RunLuaFunction(callback, true); } }
/// <summary> /// Returns the first Lua Environment found in the scene, or creates one if none exists. /// This is a slow operation, call it once at startup and cache the returned value. /// </summary> public static LuaEnvironment GetLua() { LuaEnvironment luaEnvironment = GameObject.FindObjectOfType <LuaEnvironment>(); if (luaEnvironment == null) { GameObject prefab = Resources.Load <GameObject>("Prefabs/LuaEnvironment"); if (prefab != null) { GameObject go = Instantiate(prefab) as GameObject; go.name = "LuaEnvironment"; luaEnvironment = go.GetComponent <LuaEnvironment>(); } } return(luaEnvironment); }
/// <summary> /// Initialises the Lua environment and compiles the Lua string for execution later on. /// </summary> protected virtual void InitExecuteLua() { if (initialised) { return; } // Cache a descriptive name to use in Lua error messages friendlyName = gameObject.name + "." + ParentBlock.BlockName + "." + this.GetType().ToString() + " #" + CommandIndex.ToString(); Flowchart flowchart = GetFlowchart(); // See if a Lua Environment has been assigned to this Flowchart if (luaEnvironment == null) { luaEnvironment = flowchart.LuaEnv; } // No Lua Environment specified so just use any available or create one. if (luaEnvironment == null) { luaEnvironment = LuaEnvironment.GetLua(); } string s = GetLuaString(); luaFunction = luaEnvironment.LoadLuaFunction(s, friendlyName); // Add a binding to the parent flowchart if (flowchart.LuaBindingName != "") { Table globals = luaEnvironment.Interpreter.Globals; if (globals != null) { globals[flowchart.LuaBindingName] = flowchart; } } // Always initialise when playing in the editor. // Allows the user to edit the Lua script while the game is playing. if (!(Application.isPlaying && Application.isEditor)) { initialised = true; } }
/// <summary> /// Initialises the Lua environment and compiles the Lua string for execution later on. /// </summary> protected virtual void InitExecuteLua() { if (initialised) { return; } // Cache a descriptive name to use in Lua error messages friendlyName = gameObject.name + "." + parentBlock.blockName + "." + "ExecuteLua #" + commandIndex.ToString(); Flowchart flowchart = GetFlowchart(); // See if a Lua Environment has been assigned to this Flowchart if (luaEnvironment == null) { luaEnvironment = flowchart.luaEnvironment; } // No Lua Environment specified so just use any available or create one. if (luaEnvironment == null) { luaEnvironment = LuaEnvironment.GetLua(); } string s = GetLuaString(); luaFunction = luaEnvironment.LoadLuaString(s, friendlyName); // Add a binding to the parent flowchart if (flowchart.luaBindingName != "") { Table globals = luaEnvironment.Interpreter.Globals; if (globals != null) { globals[flowchart.luaBindingName] = flowchart; } } // Always initialise when playing in the editor. // Allows the user to edit the Lua script while the game is playing. if ( !(Application.isPlaying && Application.isEditor) ) { initialised = true; } }
/// <summary> /// Adds the option to the list of displayed options, calls a Lua function when selected. /// Will cause the Menu dialog to become visible if it is not already visible. /// </summary> /// <returns><c>true</c>, if the option was added successfully.</returns> public virtual bool AddOption(string text, bool interactable, LuaEnvironment luaEnv, Closure callBack) { gameMgr.awaitingUIFeedback = true; if (!gameObject.activeSelf) { gameObject.SetActive(true); } bool addedOption = false; for (int i = 0; i < CachedButtons.Length; i++) { var button = CachedButtons[i]; if (!button.gameObject.activeSelf) { button.gameObject.SetActive(true); button.interactable = interactable; var textComponent = button.GetComponentInChildren <Text>(); if (textComponent != null) { textComponent.text = text; } // Copy to local variables LuaEnvironment env = luaEnv; Closure call = callBack; button.onClick.AddListener(delegate { StopAllCoroutines(); // Stop timeout Clear(); HideSayDialog(); // Use a coroutine to call the callback on the next frame StartCoroutine(CallLuaClosure(env, call)); }); addedOption = true; break; } } return(addedOption); }
/// <summary> /// Show a timer during which the player can select an option. Calls a Lua function when the timer expires. /// </summary> public virtual IEnumerator ShowTimer(float duration, LuaEnvironment luaEnv, Closure callBack) { if (CachedSlider == null || duration <= 0f) { yield break; } // 显示,时间条 CachedSlider.gameObject.SetActive(true); StopAllCoroutines(); float elapsedTime = 0; Slider timeoutSlider = CachedSlider; while (elapsedTime < duration) { // 更新进度 if (timeoutSlider != null) { float t = 1f - elapsedTime / duration; timeoutSlider.value = t; } // 更新流逝时间 elapsedTime += Time.deltaTime; yield return(null); } Clear(); // 隐藏菜单界面 gameObject.SetActive(false); // 隐藏对话界面?! HideSayDialog(); // 回调Lua函数 if (callBack != null) { luaEnv.RunLuaFunction(callBack, true); } }
/// <summary> /// Called by LuaEnvironment when initializing. /// </summary> public override void Initialize() { luaEnvironment = GetComponent <LuaEnvironment>(); if (luaEnvironment == null) { UnityEngine.Debug.LogError("No Lua Environment found"); return; } if (luaEnvironment.Interpreter == null) { UnityEngine.Debug.LogError("No Lua interpreter found"); return; } InitTypes(); InitFungusModule(); InitBindings(); }
/// <summary> /// Called by LuaEnvironment when initializing. /// </summary> public override void Initialize() { luaEnvironment = GetComponent<LuaEnvironment>(); if (luaEnvironment == null) { UnityEngine.Debug.LogError("No Lua Environment found"); return; } if (luaEnvironment.Interpreter == null) { UnityEngine.Debug.LogError("No Lua interpreter found"); return; } InitTypes(); InitFungusModule(); InitBindings(); }
/// <summary> /// Extension for MenuDialog that allows AddOption to call a Lua function when an option is selected. /// </summary> public static bool AddOption(this MenuDialog menuDialog, string text, bool interactable, LuaEnvironment luaEnvironment, Closure callBack) { if (!menuDialog.gameObject.activeSelf) { menuDialog.gameObject.SetActive(true); } bool addedOption = false; foreach (Button button in menuDialog.cachedButtons) { if (!button.gameObject.activeSelf) { button.gameObject.SetActive(true); button.interactable = interactable; Text textComponent = button.GetComponentInChildren<Text>(); if (textComponent != null) { textComponent.text = text; } button.onClick.AddListener(delegate { menuDialog.StopAllCoroutines(); // Stop timeout menuDialog.Clear(); menuDialog.HideSayDialog(); if (callBack != null) { luaEnvironment.RunLuaFunction(callBack, true); } }); addedOption = true; break; } } return addedOption; }
/// <summary> /// Adds the option to the list of displayed options, calls a Lua function when selected. /// Will cause the Menu dialog to become visible if it is not already visible. /// </summary> /// <returns><c>true</c>, if the option was added successfully.</returns> public virtual bool AddOption(string text, bool interactable, LuaEnvironment luaEnv, Closure callBack) { if (!gameObject.activeSelf) { gameObject.SetActive(true); } // Copy to local variables LuaEnvironment env = luaEnv; Closure call = callBack; UnityEngine.Events.UnityAction action = delegate { StopAllCoroutines(); // Stop timeout Clear(); HideSayDialog(); // Use a coroutine to call the callback on the next frame StartCoroutine(CallLuaClosure(env, call)); }; return(AddOption(text, interactable, false, action)); }
/// <summary> /// Extension for MenuDialog that allows ShowTimer to call a Lua function when the timer expires. /// </summary> public static IEnumerator ShowTimer(this MenuDialog menuDialog, float duration, LuaEnvironment luaEnvironment, Closure callBack) { if (menuDialog.cachedSlider == null || duration <= 0f) { yield break; } menuDialog.cachedSlider.gameObject.SetActive(true); menuDialog.StopAllCoroutines(); float elapsedTime = 0; Slider timeoutSlider = menuDialog.GetComponentInChildren<Slider>(); while (elapsedTime < duration) { if (timeoutSlider != null) { float t = 1f - elapsedTime / duration; timeoutSlider.value = t; } elapsedTime += Time.deltaTime; yield return null; } menuDialog.Clear(); menuDialog.gameObject.SetActive(false); menuDialog.HideSayDialog(); if (callBack != null) { luaEnvironment.RunLuaFunction(callBack, true); } }
/// <summary> /// Show a timer during which the player can select an option. Calls a Lua function when the timer expires. /// </summary> public virtual IEnumerator ShowTimer(float duration, LuaEnvironment luaEnv, Closure callBack) { if (CachedSlider == null || duration <= 0f) { yield break; } CachedSlider.gameObject.SetActive(true); StopAllCoroutines(); float elapsedTime = 0; Slider timeoutSlider = GetComponentInChildren <Slider>(); while (elapsedTime < duration) { if (timeoutSlider != null) { float t = 1f - elapsedTime / duration; timeoutSlider.value = t; } elapsedTime += Time.deltaTime; yield return(null); } Clear(); gameObject.SetActive(false); HideSayDialog(); if (callBack != null) { luaEnv.RunLuaFunction(callBack, true); } }
public virtual bool SubstituteStrings(StringBuilder input) { // This method could be called from the Start of another component, so // we need to ensure that the LuaEnvironment has been initialized. if (luaEnvironment == null) { luaEnvironment = GetComponent<LuaEnvironment>(); if (luaEnvironment != null) { luaEnvironment.InitEnvironment(); } } if (luaEnvironment == null) { UnityEngine.Debug.LogError("No Lua Environment found"); return false; } if (luaEnvironment.Interpreter == null) { UnityEngine.Debug.LogError("No Lua interpreter found"); return false; } MoonSharp.Interpreter.Script interpreter = luaEnvironment.Interpreter; // Instantiate the regular expression object. Regex r = new Regex("\\{\\$.*?\\}"); bool modified = false; // Match the regular expression pattern against a text string. var results = r.Matches(input.ToString()); foreach (Match match in results) { string key = match.Value.Substring(2, match.Value.Length - 3); // Match against string table and active language (if specified) if (stringTable != null) { DynValue stringTableVar = stringTable.Get(key); if (stringTableVar.Type == DataType.Table) { DynValue languageEntry = stringTableVar.Table.Get(activeLanguage); if (languageEntry.Type == DataType.String) { input.Replace(match.Value, languageEntry.String); modified = true; } continue; } } // Match against global variables DynValue globalVar = interpreter.Globals.Get(key); if (globalVar.Type != DataType.Nil) { input.Replace(match.Value, globalVar.ToPrintString()); modified = true; continue; } } return modified; }
/// <summary> /// Extension for MenuDialog that allows AddOption to call a Lua function when an option is selected. /// </summary> public static bool AddOption(this MenuDialog menuDialog, string text, bool interactable, LuaEnvironment luaEnvironment, Closure callBack) { bool addedOption = false; foreach (Button button in menuDialog.cachedButtons) { if (!button.gameObject.activeSelf) { button.gameObject.SetActive(true); button.interactable = interactable; Text textComponent = button.GetComponentInChildren <Text>(); if (textComponent != null) { textComponent.text = text; } button.onClick.AddListener(delegate { menuDialog.StopAllCoroutines(); // Stop timeout menuDialog.Clear(); menuDialog.HideSayDialog(); menuDialog.gameObject.SetActive(false); if (callBack != null) { luaEnvironment.RunLuaFunction(callBack, true); } }); addedOption = true; break; } } return(addedOption); }
/// <summary> /// Adds the option to the list of displayed options, calls a Lua function when selected. /// Will cause the Menu dialog to become visible if it is not already visible. /// </summary> /// <returns><c>true</c>, if the option was added successfully.</returns> public virtual bool AddOption(string text, bool interactable, LuaEnvironment luaEnv, Closure callBack) { if (!gameObject.activeSelf) { gameObject.SetActive(true); } bool addedOption = false; for (int i = 0; i < CachedButtons.Length; i++) { var button = CachedButtons[i]; if (!button.gameObject.activeSelf) { button.gameObject.SetActive(true); button.interactable = interactable; var textComponent = button.GetComponentInChildren<Text>(); if (textComponent != null) { textComponent.text = text; } // Copy to local variables LuaEnvironment env = luaEnv; Closure call = callBack; button.onClick.AddListener(delegate { StopAllCoroutines(); // Stop timeout Clear(); HideSayDialog(); // Use a coroutine to call the callback on the next frame StartCoroutine(CallLuaClosure(env, call)); }); addedOption = true; break; } } return addedOption; }
/// <summary> /// Registers all listed c# types for interop with Lua. /// You can also register types directly in the Awake method of any /// monobehavior in your scene using UserData.RegisterType(). /// </summary> protected virtual void InitTypes() { // Always register these FungusLua utilities LuaEnvironment.RegisterType("Fungus.PODTypeFactory"); LuaEnvironment.RegisterType("Fungus.FungusPrefs"); foreach (TextAsset textFile in registerTypes) { if (textFile == null) { continue; } // Parse JSON file JSONObject jsonObject = new JSONObject(textFile.text); if (jsonObject == null || jsonObject.type != JSONObject.Type.OBJECT) { UnityEngine.Debug.LogError("Error parsing JSON file " + textFile.name); continue; } // Register types with MoonSharp JSONObject registerTypesArray = jsonObject.GetField("registerTypes"); if (registerTypesArray != null && registerTypesArray.type == JSONObject.Type.ARRAY) { foreach (JSONObject entry in registerTypesArray.list) { if (entry != null && entry.type == JSONObject.Type.STRING) { string typeName = entry.str.Trim(); if (Type.GetType(typeName) == null) { continue; } LuaEnvironment.RegisterType(typeName); } } } // Register extension types with MoonSharp JSONObject extensionTypesArray = jsonObject.GetField("extensionTypes"); if (extensionTypesArray != null && extensionTypesArray.type == JSONObject.Type.ARRAY) { foreach (JSONObject entry in extensionTypesArray.list) { if (entry != null && entry.type == JSONObject.Type.STRING) { string typeName = entry.str.Trim(); if (Type.GetType(typeName) == null) { continue; } LuaEnvironment.RegisterType(typeName, true); } } } } }
/// <summary> /// Registers all listed c# types for interop with Lua. /// You can also register types directly in the Awake method of any /// monobehavior in your scene using UserData.RegisterType(). /// </summary> protected virtual void InitTypes() { bool isFungusInstalled = (Type.GetType("Fungus.Flowchart") != null); foreach (TextAsset textFile in registerTypes) { if (textFile == null) { continue; } // Parse JSON file JSONObject jsonObject = new JSONObject(textFile.text); if (jsonObject == null || jsonObject.type != JSONObject.Type.OBJECT) { UnityEngine.Debug.LogError("Error parsing JSON file " + textFile.name); continue; } // Register types with MoonSharp JSONObject registerTypesArray = jsonObject.GetField("registerTypes"); if (registerTypesArray != null && registerTypesArray.type == JSONObject.Type.ARRAY) { foreach (JSONObject entry in registerTypesArray.list) { if (entry != null && entry.type == JSONObject.Type.STRING) { string typeName = entry.str.Trim(); // Don't register fungus types if the Fungus library is not present if (!isFungusInstalled && typeName.StartsWith("Fungus.")) { continue; } LuaEnvironment.RegisterType(typeName); } } } // Register extension types with MoonSharp JSONObject extensionTypesArray = jsonObject.GetField("extensionTypes"); if (extensionTypesArray != null && extensionTypesArray.type == JSONObject.Type.ARRAY) { foreach (JSONObject entry in extensionTypesArray.list) { if (entry != null && entry.type == JSONObject.Type.STRING) { string typeName = entry.str.Trim(); // Don't register fungus types if the Fungus library is not present if (!isFungusInstalled && typeName.StartsWith("Fungus.")) { continue; } LuaEnvironment.RegisterType(typeName, true); } } } } }
public virtual bool SubstituteStrings(StringBuilder input) { // This method could be called from the Start of another component, so // we need to ensure that the LuaEnvironment has been initialized. if (luaEnvironment == null) { luaEnvironment = GetComponent <LuaEnvironment>(); if (luaEnvironment != null) { luaEnvironment.InitEnvironment(); } } if (luaEnvironment == null) { UnityEngine.Debug.LogError("No Lua Environment found"); return(false); } if (luaEnvironment.Interpreter == null) { UnityEngine.Debug.LogError("No Lua interpreter found"); return(false); } MoonSharp.Interpreter.Script interpreter = luaEnvironment.Interpreter; // Instantiate the regular expression object. Regex r = new Regex("\\{\\$.*?\\}"); bool modified = false; // Match the regular expression pattern against a text string. var results = r.Matches(input.ToString()); foreach (Match match in results) { string key = match.Value.Substring(2, match.Value.Length - 3); // Match against string table and active language (if specified) if (stringTable != null) { DynValue stringTableVar = stringTable.Get(key); if (stringTableVar.Type == DataType.Table) { DynValue languageEntry = stringTableVar.Table.Get(activeLanguage); if (languageEntry.Type == DataType.String) { input.Replace(match.Value, languageEntry.String); modified = true; } continue; } } // Match against global variables DynValue globalVar = interpreter.Globals.Get(key); if (globalVar.Type != DataType.Nil) { input.Replace(match.Value, globalVar.ToPrintString()); modified = true; continue; } } return(modified); }
/// <summary> /// Adds the required bindings to the Lua environment. /// </summary> public abstract void AddBindings(LuaEnvironment luaEnv);
/// <summary> /// Add all declared bindings to the globals table. /// </summary> public override void AddBindings(LuaEnvironment luaEnv) { if (!allEnvironments && (luaEnvironment != null && !luaEnvironment.Equals(luaEnv))) { // Don't add bindings to this environment return; } MoonSharp.Interpreter.Script interpreter = luaEnv.Interpreter; Table globals = interpreter.Globals; Table bindingsTable = null; if (tableName == "") { // Add directly to globals table bindingsTable = globals; } else { DynValue res = globals.Get(tableName); if (res.Type == DataType.Table) { // Add to an existing table bindingsTable = res.Table; } else { // Create a new table bindingsTable = new Table(globals.OwnerScript); globals[tableName] = bindingsTable; } } if (bindingsTable == null) { Debug.LogError("Bindings table must not be null"); } // Register types of bound objects with MoonSharp if (registerTypes) { foreach (string typeName in boundTypes) { LuaEnvironment.RegisterType(typeName); } } for (int i = 0; i < boundObjects.Count; ++i) { // Ignore empty keys string key = boundObjects[i].key; if (key == null || key == "") { continue; } // Check for keys used multiple times if (bindingsTable.Get(key).Type != DataType.Nil) { Debug.LogWarning("An item already exists with the same key as binding '" + key + "'. This binding will be ignored."); continue; } // Ignore bindings with no object set GameObject go = boundObjects[i].obj as GameObject; if (go != null) { // Register as gameobject / components Component component = boundObjects[i].component; if (component == null) { // Bind the key to the gameobject bindingsTable[key] = go; } else { // Bind the key to the component bindingsTable[key] = component; } } else { // Register as other UnityEngine.Object type bindingsTable[key] = boundObjects[i].obj; } } }