Unity中C#對象與Lua之間交互的原理


lua與其他語言交互,都是通過操作虛擬棧交流的。而操作虛擬棧最原始的方法就是通過lua與c語言的api,由於直接操作lua與c比較繁瑣而且容易出錯。因此tolua作為中間層而存在。

那么unity要把一個C#對象傳遞到lua里面,要怎么做呢?

1. 調用接口Tolua.Push(L,obj);這里的L指的是對應的luastate,obj就是c#對象;

• luastate 中放的是lua虛擬機中環境表、注冊表、運行堆棧、虛擬機的上下文等數據。

•從一個主線程(特指lua虛擬機中的線程,即coroutine)中創建出來的新的luaState會共享大部分數據,但會擁有一個獨立的運行堆棧。所以一個線程對象擁有一個luaState。

2. 如果 obj == null,會調用原生api(lua_pushnil(L,-1))把一個nil值壓入棧頂,所以c#這邊為null,lua那邊會接收到一個nil值;如果obj 不為null,通過obj.GetTYpe()獲取obj的類型,為了便於理解,姑且把這個obj認為是GameObject類型;

3. 接下來tolua會去字典查找GameObject在lua中對應的metatable的ref,這個字典的類型為Dictionary<Type,int>,所以ref是一個int類型的值。說到這里,可能會有兩個疑點,a.這個metatable是什么東西?b. 這個metatable的ref又是什么東西?

我們都知道,如果在lua中使用C#對象,要生成對應的xxxwrap.cs文件,這些wrap文件都是一些static方法,用來和luastate進行綁定,然后就可以在lua中調用c#對象了。在綁定一個C# Class

的時候,會調用BeginClass(tolua_beginclass)來告訴lua我要綁定一個class。

其實在beginclass之前,會先調用beginmodule,比如beginmodule(“UnityEngine”),意思是在lua創建一個全局table,這個table名字就叫UnityEngine。並設置package.load["UnityEngine"] = UnityEngine

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM