using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
using System;
using System.IO;
using System.Text;
//lua入口
public class MyLuaBehavior : MonoBehaviour
{
#region instance
static MyLuaBehavior _instance;
public static MyLuaBehavior Instance
{
get
{
if (!_instance)
{
print("查找对象");
_instance = FindObjectOfType<MyLuaBehavior>();
if (!_instance)
{
print("创建对象");
GameObject go = new GameObject(typeof(MyLuaBehavior).ToString());
_instance = go.AddComponent<MyLuaBehavior>();
DontDestroyOnLoad(go);
}
}
return _instance;
}
}
#endregion
public int a = 9;
public LuaEnv LuaEnv { get { return luaEnv; } }
internal static LuaEnv luaEnv;//全局唯一
internal static float lastGCTime = 0;
internal const float GCInterval = 1;//回收间隔1s
private Action luaAwake;
private Action luaStart;
private Action luaUpdate;
private Action luaOnDestory;
private Action<string> luaSceneLoaded;
private Action<string> luaSceneUnloaded;
private Action<bool> onApplicationFocusLua;
private Action<bool> onApplicationPauseLua;
private Action onApplicationQuitLua;
private LuaTable scriptEnv;
private void Awake()
{
gameObject.tag = "LuaEnv";
luaEnv = new LuaEnv();
scriptEnv = luaEnv.NewTable();
//luaEnv.AddBuildin("rapidjson", XLua.LuaDLL.Lua.loadRapidJson); --第三方库
//为每一个脚本设置一个独立的环境,可在一定程度上防止脚本间全局变量 函数冲突
LuaTable meta = luaEnv.NewTable();
meta.Set("__index", luaEnv.Global);
scriptEnv.SetMetaTable(meta);
meta.Dispose();
scriptEnv.Set("self", this);
luaEnv.AddLoader((ref string filePath) =>
{
string[] p = filePath.Split('.');//例如 require ("EventManager.EventManager")
#if UNITY_EDTIOR
string subPath = Path.Combine(Application.dataPath, "GameRes/Lua");
#else //assets/GameRes/Lua 目录下都是lua脚本
string subPath = Path.Combine(Application.dataPath, "GameRes/Lua");
#endif
StringBuilder sb = new StringBuilder(subPath);
for (int i = 0; i < p.Length; ++i)
{
sb.AppendFormat("/{0}", p[i]);
}
sb.Append(".lua"); //GameRes/Lua/EventManager/EventManager.lua
string fullPath = sb.ToString();
//Debug.Log(fullPath);
var bytes = File.ReadAllBytes(fullPath);
return bytes;
});
luaEnv.DoString("require 'main'"); //main.lua位于Assets/GameRes/Lua/main.lua
luaAwake = scriptEnv.Get<Action>("Awake");
scriptEnv.Get("Start", out luaStart);
scriptEnv.Get("Update", out luaUpdate);
scriptEnv.Get("OnDestroy", out luaOnDestory);
scriptEnv.Get("SceneLoaded", out luaSceneLoaded);
scriptEnv.Get("SceneUnloaded", out luaSceneUnloaded);
scriptEnv.Get("OnApplicationFocus", out onApplicationFocusLua);
scriptEnv.Get("OnApplicationPause", out onApplicationPauseLua);
scriptEnv.Get("OnApplicationQuit", out onApplicationQuitLua);
luaAwake?.Invoke();
UnityEngine.SceneManagement.SceneManager.sceneLoaded += sceneLoaded;
UnityEngine.SceneManagement.SceneManager.sceneUnloaded += sceneUnloaded;
DontDestroyOnLoad(gameObject);
}
private void sceneUnloaded(UnityEngine.SceneManagement.Scene arg0)
{
luaSceneUnloaded(arg0.name);
}
private void sceneLoaded(UnityEngine.SceneManagement.Scene arg0, UnityEngine.SceneManagement.LoadSceneMode arg1)
{
luaSceneLoaded(arg0.name);
}
// Start is called before the first frame update
void Start()
{
luaStart?.Invoke();
}
// Update is called once per frame
void Update()
{
luaUpdate?.Invoke();
if (Time.time - lastGCTime > GCInterval)
{
luaEnv.Tick();
lastGCTime = Time.time;
}
}
private void OnDestroy()
{
luaOnDestory?.Invoke();
luaOnDestory = null;
luaUpdate = null;
luaStart = null;
luaAwake = null;
luaEnv = null;
scriptEnv.Dispose();
}
private void OnApplicationFocus(bool focus)
{
onApplicationFocusLua?.Invoke(focus);
}
private void OnApplicationPause(bool pause)
{
onApplicationPauseLua?.Invoke(pause);
}
private void OnApplicationQuit()
{
onApplicationQuitLua?.Invoke();
}
}