Unity3d ulua c#与lua交互+wrap文件理解

来源:互联网 发布:qq视频录像软件免费版 编辑:程序博客网 时间:2024/05/16 10:03

上次已经搭建好了框架,这里开始使用框架,本文会比较长~~因为我搞了一天,也遇到了好多坑

今天主要记录一下 c# 与 lua 的交互~~ 然后配以demo

C# 调用 lua 这个很简单,之前也有说过,这里不废话,直接贴

LuaScriptMgr mgr = new LuaScriptMgr ();mgr.Start ();mgr.DoFile ("LoginUI.lua");


难点其实是Lua调用c#,以及效率问题

>> 最古老的是使用反射调用,不过由于反射的性能问题,目前基本上不怎么用了

>>wrap调用提升了反射在效率上的不足,但是必须自己去wrap,所以大版本更新是可以用到的,小版本更新目前还是得用到反射

ok~~ 肯定一头雾水,什么是wrap,怎么生成wrap,wrap工作原理是怎样的?(在今天之前我也是如此多的疑惑)


什么是wrap: wrap是对c#类的成员函数,成员变量,通过映射的方式。这里对比一下两个文件


这个是c#文件

using UnityEngine;using System.Collections;public class LoginData  {public string username;public string password;public int id;public LoginData(){}public LoginData(string username, string password, int id){this.username = username;this.password = password;this.id = id;}public void Equip(string username, string password, int id){Debug.Log ("logindata equip log");if (this.username.Equals (username) && password.Equals (password) && this.id == id) {Debug.Log ("C# >>> LoginData = {username = " + this.username + ", password =" + this.password + ", id = " + this.id + " check ok!!!");} else {Debug.Log ("C# >>> LoginData = {username = " + this.username + ", password =" + this.password + ", id = " + this.id + " check error!!!");}}}
这个是wrap过后的文件

using System;using LuaInterface;public class LoginDataWrap{public static void Register(IntPtr L){LuaMethod[] regs = new LuaMethod[]{new LuaMethod("Equip", Equip),new LuaMethod("New", _CreateLoginData),new LuaMethod("GetClassType", GetClassType),};LuaField[] fields = new LuaField[]{new LuaField("username", get_username, set_username),new LuaField("password", get_password, set_password),new LuaField("id", get_id, set_id),};LuaScriptMgr.RegisterLib(L, "LoginData", typeof(LoginData), regs, fields, typeof(object));}[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]static int _CreateLoginData(IntPtr L){int count = LuaDLL.lua_gettop(L);if (count == 0){LoginData obj = new LoginData();LuaScriptMgr.PushObject(L, obj);return 1;}else if (count == 3){string arg0 = LuaScriptMgr.GetString(L, 1);string arg1 = LuaScriptMgr.GetString(L, 2);int arg2 = (int)LuaScriptMgr.GetNumber(L, 3);LoginData obj = new LoginData(arg0,arg1,arg2);LuaScriptMgr.PushObject(L, obj);return 1;}else{LuaDLL.luaL_error(L, "invalid arguments to method: LoginData.New");}return 0;}static Type classType = typeof(LoginData);[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]static int GetClassType(IntPtr L){LuaScriptMgr.Push(L, classType);return 1;}[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]static int get_username(IntPtr L){object o = LuaScriptMgr.GetLuaObject(L, 1);LoginData obj = (LoginData)o;if (obj == null){LuaTypes types = LuaDLL.lua_type(L, 1);if (types == LuaTypes.LUA_TTABLE){LuaDLL.luaL_error(L, "unknown member name username");}else{LuaDLL.luaL_error(L, "attempt to index username on a nil value");}}LuaScriptMgr.Push(L, obj.username);return 1;}[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]static int get_password(IntPtr L){object o = LuaScriptMgr.GetLuaObject(L, 1);LoginData obj = (LoginData)o;if (obj == null){LuaTypes types = LuaDLL.lua_type(L, 1);if (types == LuaTypes.LUA_TTABLE){LuaDLL.luaL_error(L, "unknown member name password");}else{LuaDLL.luaL_error(L, "attempt to index password on a nil value");}}LuaScriptMgr.Push(L, obj.password);return 1;}[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]static int get_id(IntPtr L){object o = LuaScriptMgr.GetLuaObject(L, 1);LoginData obj = (LoginData)o;if (obj == null){LuaTypes types = LuaDLL.lua_type(L, 1);if (types == LuaTypes.LUA_TTABLE){LuaDLL.luaL_error(L, "unknown member name id");}else{LuaDLL.luaL_error(L, "attempt to index id on a nil value");}}LuaScriptMgr.Push(L, obj.id);return 1;}[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]static int set_username(IntPtr L){object o = LuaScriptMgr.GetLuaObject(L, 1);LoginData obj = (LoginData)o;if (obj == null){LuaTypes types = LuaDLL.lua_type(L, 1);if (types == LuaTypes.LUA_TTABLE){LuaDLL.luaL_error(L, "unknown member name username");}else{LuaDLL.luaL_error(L, "attempt to index username on a nil value");}}obj.username = LuaScriptMgr.GetString(L, 3);return 0;}[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]static int set_password(IntPtr L){object o = LuaScriptMgr.GetLuaObject(L, 1);LoginData obj = (LoginData)o;if (obj == null){LuaTypes types = LuaDLL.lua_type(L, 1);if (types == LuaTypes.LUA_TTABLE){LuaDLL.luaL_error(L, "unknown member name password");}else{LuaDLL.luaL_error(L, "attempt to index password on a nil value");}}obj.password = LuaScriptMgr.GetString(L, 3);return 0;}[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]static int set_id(IntPtr L){object o = LuaScriptMgr.GetLuaObject(L, 1);LoginData obj = (LoginData)o;if (obj == null){LuaTypes types = LuaDLL.lua_type(L, 1);if (types == LuaTypes.LUA_TTABLE){LuaDLL.luaL_error(L, "unknown member name id");}else{LuaDLL.luaL_error(L, "attempt to index id on a nil value");}}obj.id = (int)LuaScriptMgr.GetNumber(L, 3);return 0;}[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]static int Equip(IntPtr L){LuaScriptMgr.CheckArgsCount(L, 4);LoginData obj = (LoginData)LuaScriptMgr.GetNetObjectSelf(L, 1, "LoginData");string arg0 = LuaScriptMgr.GetLuaString(L, 2);string arg1 = LuaScriptMgr.GetLuaString(L, 3);int arg2 = (int)LuaScriptMgr.GetNumber(L, 4);obj.Equip(arg0,arg1,arg2);return 0;}}

当lua虚拟机启动的时候,会将此wrap文件加载进lua虚拟机,然后lua就可以识别此调用了,最后就形成了

Lua 调用 Wrap , Wrap调用C#的模式,实现了Lua调用C#


那么我们怎么来生成Wrap 呢 ? 

生成Wrap文件需要使用者自己手动的去WrapFile 文件填写需要Wrap的文件,大概像下面这个样子

_GT(typeof(LoginData)),

为啥需要添加这个呢? 其实很简单,这个要从Wrap文件是生成说起。

来到BindLua.cs 文件,你会发现里面有个叫Binding的函数,函数大概是这样的


生成的Wrap文件会放到Lua/Source/LuaWrap 这个目录下面, 具体可以参考生成过程。


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Lua文件如下,并没有什么特别的,只是一个简单的验证,并回调C#

local transform;local gameObject;LoginUI = {};local this = LoginUI;-- c# 向lua 传入参数, 然后lua创建c#对象,并调用c#方法(wrap方式调用)function LoginUI.CheckUserName(username)if username=="pdw" thenlocal loginData = LoginData.New();loginData:Equip(username, "123456", 1);else return "unknown username" end;end-- c# 向 lua传入对象,然后lua 调用本对象function LoginUI.CheckUserNameByData(data)data:Equip("pdw", "123456", 1);end
UI 类如下,logindata上面已经贴了~这里不在贴了~
using UnityEngine;using System.Collections;public class LoginUIPanel : MonoBehaviour {void OnGUI(){if (GUILayout.Button ("login")) {LoginData data = new LoginData ("pdw", "123456", 1);LuaScriptMgr mgr = new LuaScriptMgr ();mgr.Start ();mgr.DoFile ("LoginUI.lua");//mgr.CallLuaFunction ("LoginUI.CheckUserName", "pdw"); //传入lua字符串,并通过Wrap 创建对象返回mgr.CallLuaFunction ("LoginUI.CheckUserNameByData", data); //传入lua对象}}}






2 0
原创粉丝点击