tolua# is a Unity lua static binder solution. the first solution that analyzes code by reflection and generates wrapper classes.

It is a Unity plugin that greatly simplifies the integration of C# code with Lua. which can automatically generate the binding code to access Unity from Lua and map c# constants, variables, functions, properties, classes, and enums to Lua.tolua# grows up from cstolua. its goal is to be a powerful development environment for Unity.

github/tolua

All problems in computer science can be solved by another level of indirection, except of course for the problem of too many indirections

tolua - CSDN博客


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 ;
  • ......

推薦閱讀:

相關文章