Unity ToLua 中Update的调用流程

1.首先注册Lua中的update函数

LuaState.cs

其中的OpenBaseLuaLibs()

        public void Start()
        {
#if UNITY_EDITOR
            beStart = true;
#endif
            Debugger.Log("LuaState start");
            OpenBaseLuaLibs();
#if ENABLE_LUA_INJECTION
            Push(LuaDLL.tolua_tag());
            LuaSetGlobal("tolua_tag");
#if UNITY_EDITOR
            if (UnityEditor.EditorPrefs.GetInt(Application.dataPath + "InjectStatus") == 1)
            { 
#endif
                DoFile("System/Injection/LuaInjectionStation.lua");
                bInjectionInited = true;
#if UNITY_EDITOR
            }
#endif
#endif
            PackBounds = GetFuncRef("Bounds.New");
            UnpackBounds = GetFuncRef("Bounds.Get");
            PackRay = GetFuncRef("Ray.New");
            UnpackRay = GetFuncRef("Ray.Get");
            PackRaycastHit = GetFuncRef("RaycastHit.New");
            PackTouch = GetFuncRef("Touch.New");
        }

        void OpenBaseLuaLibs()
        {
            DoFile("tolua.lua");            //tolua table名字已经存在了,不能用require
            LuaUnityLibs.OpenLuaLibs(L);
        }

 

LuaUnityLibs.cs

其中的LuaDLL.tolua_openlualibs()

        public static void OpenLuaLibs(IntPtr L)
        {                        
            if (LuaDLL.tolua_openlualibs(L) != 0)
            {
                string error = LuaDLL.lua_tostring(L, -1);
                LuaDLL.lua_pop(L, 1);
                throw new LuaException(error);
            }

            SetOutMethods(L, "Vector3", GetOutVector3);
            SetOutMethods(L, "Vector2", GetOutVector2);
            SetOutMethods(L, "Vector4", GetOutVector4);
            SetOutMethods(L, "Color", GetOutColor);
            SetOutMethods(L, "Quaternion", GetOutQuaternion);
            SetOutMethods(L, "Ray", GetOutRay);
            SetOutMethods(L, "Bounds", GetOutBounds);
            SetOutMethods(L, "Touch", GetOutTouch);
            SetOutMethods(L, "RaycastHit", GetOutRaycastHit);
            SetOutMethods(L, "LayerMask", GetOutLayerMask);            
        }

 

tolua.c

static int _openlualibs(lua_State *L)
{
    tolua_openvaluetype(L);
    tolua_openluavec3(L);
    tolua_openluavec2(L);
    tolua_openluavec4(L);
    tolua_openluaclr(L);
    tolua_openluaquat(L);   
    tolua_openlualayermask(L);
    tolua_openupdate(L);
    return 0;
}

LUALIB_API int tolua_openlualibs(lua_State *L)
{    
    lua_pushcfunction(L, _openlualibs);
    return lua_pcall(L, 0, -1, 0);    
}

void tolua_openupdate(lua_State *L)
{
    lua_getglobal(L, "Update");

    if (!lua_isfunction(L, 1))
    {
        luaL_error(L, "Update function does not exist or not be loaded");
        return;
    }
    
    //我们使用伪索引LUA_REGISTRYINDEX来取得lua的注册表,然后在注册表中添加成员
    //Register[LUA_RIDX_UPDATE] = Update,这个Update是在event.lua中
    lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_UPDATE);    
    lua_getglobal(L, "LateUpdate");

    if (!lua_isfunction(L, 1))
    {
        luaL_error(L, "LateUpdate function does not exist or not be loaded");
        return;
    }

    lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_LATEUPDATE);  
    lua_getglobal(L, "FixedUpdate");

    if (!lua_isfunction(L, 1))
    {
        luaL_error(L, "FixedUpdate function does not exist or not be loaded");
        return;
    }

    lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_FIXEDUPDATE);      
}

 

event.lua

function event(name, safe)
	safe = safe or false
	return setmetatable({name = name, keepSafe = safe, lock = false, opList = {}, list = list:new()}, _event)				
end

UpdateBeat 		= event("Update", true)
LateUpdateBeat	= event("LateUpdate", true)
FixedUpdateBeat	= event("FixedUpdate", true)
CoUpdateBeat	= event("CoUpdate")				--只在协同使用

local Time = Time
local UpdateBeat = UpdateBeat
local LateUpdateBeat = LateUpdateBeat
local FixedUpdateBeat = FixedUpdateBeat
local CoUpdateBeat = CoUpdateBeat

--逻辑update
function Update(deltaTime, unscaledDeltaTime)
	Time:SetDeltaTime(deltaTime, unscaledDeltaTime)				
	UpdateBeat()	
end

function LateUpdate()	
	LateUpdateBeat()		
	CoUpdateBeat()		
	Time:SetFrameCount()		
end

--物理update
function FixedUpdate(fixedDeltaTime)
	Time:SetFixedDelta(fixedDeltaTime)
	FixedUpdateBeat()
end

function PrintEvents()
	UpdateBeat:Dump()
	FixedUpdateBeat:Dump()
end

由上面的流程我们知道,我们最终将event.lua中的update函数我们放置到了lua中的注册表Registry[LUA_RIDX_UPDATE]中,等待被访问

 

2.调用lua中的update函数

LuaLooper.cs

由unity的Update()来触发每次的调用

    void Update()
    {
#if UNITY_EDITOR
        if (luaState == null)
        {
            return;
        }
#endif
        if (luaState.LuaUpdate(Time.deltaTime, Time.unscaledDeltaTime) != 0)
        {
            ThrowException();
        }

        luaState.LuaPop(1);
        luaState.Collect();
#if UNITY_EDITOR
        luaState.CheckTop();
#endif
    }

LuaState.cs

        public int LuaUpdate(float delta, float unscaled)
        {
            return LuaDLL.tolua_update(L, delta, unscaled);
        }

 

tolua.c

//这里获取了在注册表中的Update函数,然后传入了两个参数,最后调用该函数
LUALIB_API int tolua_update(lua_State *L, float deltaTime, float unscaledTime)
{
    int top = tolua_beginpcall(L, LUA_RIDX_UPDATE);
    lua_pushnumber(L, deltaTime);
    lua_pushnumber(L, unscaledTime);
    return lua_pcall(L, 2, -1, top);
}

LUALIB_API int tolua_beginpcall(lua_State *L, int reference)
{
    lua_getref(L, LUA_RIDX_CUSTOMTRACEBACK);
    int top = lua_gettop(L);
    lua_getref(L, reference);
    return top;
}

 

 

你可能感兴趣的:(LUA)