一个简单的游戏框架:tolua相关

一个简单的游戏框架:tolua相关

代码:https://github.com/HushengStudent/myGameFramework

1.tolua集成

下载tolua:https://github.com/topameng/tolua

关于tolua的集成主要参考LuaFramework_UGUI,实现自己的LuaMgr。

//参考(https://github.com/jarjin/LuaFramework_UGUI)集成tolua;
    public class LuaMgr : MonoSingleton<LuaMgr> 
	{
        private LuaState lua;
        private LuaLoaderUtility loader;
        private LuaLooper loop = null;

        public override void Init()
        {
            base.Init();
            //...
        }

        public override void AwakeEx()
        {
            base.AwakeEx();
            //初始化LuaMgr;
            loader = new LuaLoaderUtility();//TODO:Lua AssetBundle的使用;
            lua = new LuaState();
            this.OpenLibs();
            lua.LuaSetTop(0);
            LuaBinder.Bind(lua);
            DelegateFactory.Init();
            LuaCoroutine.Register(lua, this);
        }
        
        /// <summary>
        /// 初始化加载第三方库;
        /// </summary>
        void OpenLibs()
        {
            lua.OpenLibs(LuaDLL.luaopen_pb);
            //lua.OpenLibs(LuaDLL.luaopen_sproto_core);
            //lua.OpenLibs(LuaDLL.luaopen_protobuf_c);
            lua.OpenLibs(LuaDLL.luaopen_lpeg);
            lua.OpenLibs(LuaDLL.luaopen_bit);
            lua.OpenLibs(LuaDLL.luaopen_socket_core);
            this.OpenCJson();
        }

        //cjson比较特殊,只new了一个table,没有注册库,这里注册一下;
        protected void OpenCJson()
        {
            lua.LuaGetField(LuaIndexes.LUA_REGISTRYINDEX, "_LOADED");
            lua.OpenLibs(LuaDLL.luaopen_cjson);
            lua.LuaSetField(-2, "cjson");
            lua.OpenLibs(LuaDLL.luaopen_cjson_safe);
            lua.LuaSetField(-2, "cjson.safe");
        }

        public void StartLuaMgr()
        {
            InitLuaPath();
            InitLuaBundle();
            this.lua.Start();    //启动LUAVM;
            this.StartMain();
            this.StartLooper();
        }

        /// <summary>
        /// 初始化Lua代码加载路径;
        /// </summary>
        void InitLuaPath()
        {
            lua.AddSearchPath(LuaConst.luaDir);
            lua.AddSearchPath(LuaConst.luaResDir);
        }

        /// <summary>
        /// 初始化LuaBundle;
        /// </summary>
        void InitLuaBundle()
        {
            if (loader.beZip)
            {
                //loader.AddBundle("lua/lua.unity3d");
            }
        }

        void StartLooper()
        {
            loop = gameObject.AddComponent<LuaLooper>();
            loop.luaState = lua;
        }

        void StartMain()
        {
            lua.DoFile("Main.lua");
            LuaFunction main = lua.GetFunction("Main");
            main.Call();
            main.Dispose();
            main = null;
        }

        public void DoFile(string filename)
        {
            lua.DoFile(filename);
        }

        // Update is called once per frame;
        public object[] CallFunction(string funcName, params object[] args)
        {
            LuaFunction func = lua.GetFunction(funcName);
            if (func != null)
            {
                return func.LazyCall(args);
            }
            return null;
        }

        public void CallLuaModuleMethod(string funcName, params object[] args)
        {
            LuaFunction func = lua.GetFunction(funcName);
            if (func != null)
            {
                func.Call(args);
            }
        }

        public void CallLuaTableMethod(string module, string funcName, params object[] args)
        {
            LuaFunction func = lua.GetFunction(module+"."+ funcName);
            LuaTable table = lua.GetTable(module);
            if(func!=null && table != null)
            {
                func.Call(table,args);
            }
        }

        public void LuaGC()
        {
            lua.LuaGC(LuaGCOptions.LUA_GCCOLLECT);
        }

        public void Close()
        {
            loop.Destroy();
            loop = null;

            lua.Dispose();
            lua = null;
            loader = null;
        }
	}

2.C#调用Lua

①在C#中调用Lua的方法:

C#调用Lua文件的方法:如 xxx.func() 这种形式:LuaMgr:

public void CallLuaModuleMethod(string funcName, params object[] args)
        {
            LuaFunction func = lua.GetFunction(funcName);
            if (func != null)
            {
                func.Call(args);
            }
        }

C#调用Lua类中的的成员方法,如 xxx:func() 这种形式:LuaMgr:

需要先拿到对应对Table:

public void CallLuaTableMethod(string module, string funcName, params object[] args)
        {
            LuaFunction func = lua.GetFunction(module+"."+ funcName);
            LuaTable table = lua.GetTable(module);
            if(func!=null && table != null)
            {
                func.Call(table,args);
            }
        }
这是两者调用时,点号和冒号的区别。

3.Lua调用C#

在CustomSettings中配置需要被Lua调用的类并导出,在Lua中就可以直接调用。

如参考logUtility的使用。

4.tolua中的事件系统

源文件:myGameFramework\Client\Assets\LuaFramework\ToLua\Lua\event.lua

5.tolua中的定时器

源文件:myGameFramework\Client\Assets\LuaFramework\ToLua\Lua\System\Timer.lua

简单示例:

function Game.Test()
    
end

function Game.Init()
    tim = Timer.New(Game.FunTest,1, -1, true) 
--参数1为调用的方法名,参数2为间隔时间,参数3为循环次数(当为-1时无限循环)
--参数4为是否忽略时间的Scale,scale false 采用deltaTime计时,true 采用 unscaledDeltaTime计时
    tim:Start()
end

5.protoc-gen-lua使用

tolua自带pblua,使用pblua生成lua代码需要配置相关环境:

⑴.解压myGameFramework\File\Source\pblua\protobuff\protobuf-python-3.0.0.zip 到C盘。
⑵.解压myGameFramework\File\Source\pblua\protobuff\protoc-3.0.0-win32.zip 把Protoc放到protobuf/src下。
⑶.使用protobuf的python版本必须在2.6以上,protoc的版本要与protobuf的版本保持一致。
⑷.如果python2.7的版本大于2.7.9,在安装python时setuptools已自动安装,否则则需要手动。
⑸.cmd进入到protobuf/python 执行以下命令:
python setup.py build
python setup.py install
⑹.致此pblua环境搭建完成。
⑺.myGameFramework\Tools\protoc-gen-lua-master 为pblua工作目录,已经解压好了。
⑻.参考代码:PbLuaEditor.cs:

public static void BuildPb2Lua()
        {
            paths.Clear();
            files.Clear();
            Recursive(pbluaDir);
            int index = 0;
            foreach (string f in files)
            {
                index++;
                string name = Path.GetFileName(f);
                string ext = Path.GetExtension(f);
                string workPath = Path.GetDirectoryName(f);
                if (!ext.Equals(".proto")) continue;
                EditorUtility.DisplayProgressBar("Build PbLua File", "gen proto to lua:" + name, index / files.Count);
                ProcessStartInfo info = new ProcessStartInfo();
                info.FileName = protoc;
                info.Arguments = " --lua_out=./ --plugin=protoc-gen-lua=" + protoc_gen_dir + " " + name;
                info.WindowStyle = ProcessWindowStyle.Hidden;
                info.UseShellExecute = true;
                info.WorkingDirectory = workPath;
                info.ErrorDialog = true;
                LogUtility.Print("gen proto to lua:" + name);
                Process pro = Process.Start(info);
                pro.WaitForExit();
            }
            EditorUtility.ClearProgressBar();
            AssetDatabase.Refresh();
        }

执行该方法,就能生成pb文件对应的lua文件。

6.protogen使用

pb可以生成Lua代码,当然同时也需要生成对应对C#文件,供服务器使用,部分协议客户端也需要使用到C#形式的协议文件:

pb生成C#使用到了protogen:

⑴.解压myGameFramework\File\Source\pblua\protobuff-net\protobuf-net-r668.zip。
⑵.打开项目下protobuff-net工程,生成。
⑶.打开ProtoGen工程,生成。
⑷.其中ProtoGen工程生成的protogen.exe即可以拿来用proto文件生成C#代码。

⑸.参考代码:PbLuaEditor.cs:

public static void BuildPb2Csharp()
        {
            paths.Clear();
            files.Clear();
            Recursive(pbluaDir);
            int index = 0;
            foreach (string f in files)
            {
                index++;
                string name = Path.GetFileName(f);
                string ext = Path.GetExtension(f);
                string workPath = Path.GetDirectoryName(f);
                if (!ext.Equals(".proto")) continue;
                //输出目录;
                string outPath = GetCsharpPath(f);
                if (null == outPath) continue;
                if (!Directory.Exists(outPath))
                {
                    Directory.CreateDirectory(outPath);
                }
                string fileName = Path.GetFileNameWithoutExtension(f);
                EditorUtility.DisplayProgressBar("Build PbLua File", "gen proto to c#:" + name, index / files.Count);
                ProcessStartInfo info = new ProcessStartInfo();
                info.FileName = protogen;
                info.Arguments = "-i:" + name + " -o:" + outPath + "/" + fileName + ".cs -p:detectMissing";
                info.WindowStyle = ProcessWindowStyle.Hidden;
                info.UseShellExecute = true;
                info.WorkingDirectory = workPath;
                info.ErrorDialog = true;
                LogUtility.Print("gen proto to c#:" + name);
                Process pro = Process.Start(info);
                pro.WaitForExit();
            }
            EditorUtility.ClearProgressBar();
            AssetDatabase.Refresh();
        }

也是使用C#函数调用应用程序根据一定的参数生成对应的C#文件。

客户端与服务器之间通信使用protobuf-net,导入protobuf-net会报错,存在不安全代码,只需要在Asset目录加入mcs.rsp文件即可:

-unsafe

猜你喜欢

转载自blog.csdn.net/husheng0/article/details/79491458