ToLua基於LuaInterface,LuaInterface是一個實現lua和微軟.Net平臺的CLR混合編程的開源庫,使得lua腳本可以實例化CLR對象,訪問屬性,調用方法甚至使用lua函數來處理事件。
ToLua保留了LuaInterface基本形式,重寫或移除了部分內容,使代碼更加簡潔,提供了對Unity的支持、拓展了lua5.1.4源碼。而最大的改進在於,LuaInterface中lua訪問CLR需要運行時反射,對於遊戲應用來說效率不夠理想,ToLua則提供了一套中間層導出工具,對於需要訪問的CLR、Unity及自定義類預生成wrap文件,lua訪問時只訪問wrap文件,wrap文件接收lua傳遞來的參數,進行類型(值、對象、委託)轉換,再調用真正工作的CLR對象和函數,最後將返回值返回給lua,有效地提高了效率。
Figure 1. Assets 先開頭,不定時更。
GameObject: tolua-masterAssetsToLuaExamples12_GameObject
public class TestGameObject : MonoBehaviour
{
private string script =
@ "
local Color = UnityEngine.Color
local GameObject = UnityEngine.GameObject
local ParticleSystem = UnityEngine.ParticleSystem
function OnComplete()
print(OnComplete CallBack)
end
local go = GameObject(go)
go:AddComponent(typeof(ParticleSystem))
local node = go.transform
node.position = Vector3.one
print(gameObject is: ..tostring(go))
--go.transform:DOPath({Vector3.zero, Vector3.one * 10}, 1, DG.Tweening.PathType.Linear, DG.Tweening.PathMode.Full3D, 10, nil)
--go.transform:DORotate(Vector3(0,0,360), 2, DG.Tweening.RotateMode.FastBeyond360):OnComplete(OnComplete)
GameObject.Destroy(go, 2)
go.name = 123
--print(delay destroy gameobject is: ..go.name)
" ;
public LuaState lua = null ;
void Start ()
{
# if UNITY_5 || UNITY_2017
Application.logMessageReceived += ShowTips ;
# else
Application.RegisterLogCallback ( ShowTips );
# endif
new LuaResLoader ();
lua = new LuaState ();
lua.LogGC = true ;
lua.Start ();
LuaBinder.Bind ( lua );
lua.DoString ( script , "TestGameObject.cs" );
}
void Update ()
{
lua.CheckTop ();
lua.Collect ();
}
string tips = "" ;
void ShowTips ( string msg , string stackTrace , LogType type )
{
tips += msg ;
tips += "
" ;
}
void OnApplicationQuit ()
{
lua.Dispose ();
lua = null ;
# if UNITY_5 || UNITY_2017
Application.logMessageReceived -= ShowTips ;
# else
Application.RegisterLogCallback ( null );
# endif
}
void OnGUI ()
{
GUI.Label ( new Rect ( Screen.width / 2 - 300 , Screen.height / 2 - 300 , 600 , 600 ), tips );
}
}
lua腳本實現最主要的部分代碼:
lua.Start ();
LuaBinder.Bind ( lua );
lua.DoString ( script , "TestGameObject.cs" );
在private string script中,通過下面的代碼,將lua與C#對應。
local Color = UnityEngine.Color
local GameObject = UnityEngine.GameObject
local ParticleSystem = UnityEngine.ParticleSystem
local go = GameObject ( go )
對於Exmaple12給出的實例,通過GetType(), BaseType等函數,遍歷ObjectPool中的所有object並得到其類型。
LuaState lua = go.lua ;
foreach ( var item in lua.translator . objectsBackMap )
{
object obj = item.Key ;
Type s = obj.GetType ();
Type z = s.BaseType ;
}
通過循環判斷,實現遍歷。
z == typeof ( System.Object );
// or
// z.ToString == System.Object ;
// or
// z.BaseType == null ;
在console中顯示實現,類似於下圖:
figure 2. Console
LuaObjectPool & objectsBackMap ;
public readonly Dictionary < object , int > objectsBackMap = new Dictionary < object , int > ( new CompareObject ());
public readonly LuaObjectPool objects = new LuaObjectPool ();
ObjectPool:
public class LuaObjectPool
{
class PoolNode
{
public int index ;
public object obj ;
public PoolNode ( int index , object obj )
{
this.index = index ;
this.obj = obj ;
}
}
private List < PoolNode > list ;
private PoolNode head = null ;
private int count = 0 ;
public LuaObjectPool ()
{
list = new List < PoolNode > ( 1024 );
head = new PoolNode ( 0 , null );
list.Add ( head );
list.Add ( new PoolNode ( 1 , null ));
count = list.Count ;
}
public object this [ int i ]
{
get
{
if ( i > 0 && i < count )
{
return list [ i ]. obj ;
}
return null ;
}
}
public void Clear ()
{
list.Clear ();
head = null ;
count = 0 ;
}
public int Add ( object obj )
{
int pos = - 1 ;
if ( head.index ! = 0 )
{
pos = head.index ;
list [ pos ]. obj = obj ;
head.index = list [ pos ]. index ;
}
else
{
pos = list.Count ;
list.Add ( new PoolNode ( pos , obj ));
count = pos + 1 ;
}
return pos ;
}
public object TryGetValue ( int index )
{
if ( index > 0 && index < count )
{
return list [ index ]. obj ;
}
return null ;
}
public object Remove ( int pos )
{
if ( pos > 0 && pos < count )
{
object o = list [ pos ]. obj ;
list [ pos ]. obj = null ;
list [ pos ]. index = head.index ;
head.index = pos ;
return o ;
}
return null ;
}
public object Destroy ( int pos )
{
if ( pos > 0 && pos < count )
{
object o = list [ pos ]. obj ;
list [ pos ]. obj = null ;
return o ;
}
return null ;
}
public object Replace ( int pos , object o )
{
if ( pos > 0 && pos < count )
{
object obj = list [ pos ]. obj ;
list [ pos ]. obj = o ;
return obj ;
}
return null ;
}
}
相關補充:
C# Memory Management for Unity Developers
Unity3D之對象池(Object Pool)
待補:
tolua-masterAssetsToLuaExamples 1-24 ;
new LuaState() ; Update(){...} ;
ObjectTranslator ;
各類error: xxxx ;
[del] GetType() & TypeOf() , BaseType ; [/del]
C# Dictionary & Lua id ;
......
推薦閱讀: