zoukankan      html  css  js  c++  java
  • ULUA的简洁用法

    《ULUA的简洁用法》
    作者: 游蓝海
    文章链接:http://blog.csdn.net/you_lan_hai/article/details/51059510
    转载请注明出处

    2017.4.23修改:看到不少朋友关注本篇文章,我又总结了另外一套更简单的用法,见《ULUA的简洁用法(二)》


    ULUA(http://www.ulua.org/index.html)所推荐的几种framework虽然功能强大,但是结构比较复杂,对于unity初学者来说太过麻烦和冗余。因此我自己总结了一套很简洁的用法,抛开MVC和各种框架,直接使用tolua(https://github.com/topameng/tolua)实现Unity和LUA的交互。
    本文介绍的所以代码,我已经上传到了GitHub,链接见文章末尾。下面介绍实现的详细步骤。

    1.原理

    给GameObject添加上一个C#脚本组件作为中间层,在中间层上绑定上一个LUA脚本,将Unity的所有回调接口通过中间层传递到LUA。同时,LUA脚本也可以通过中间层操作GameObject。

    2.准备

    1. 获取tolua:https://github.com/topameng/tolua
      tolua是一个工具,将Unity的C#代码包装之后导出给LUA,同时提供了一些访问LUA的接口,使得Unity和LUA可以相互调用。
    2. 简单起见,直接用Unity编辑器打开tolua工程。
      本文使用的tolua版本是1.0.4,Unity版本是5.2.2。

    3.添加C#中间层

    新建C#脚本,命名为LuaBehaviourScript.cs。下面是文件的核心内容(无关紧要的代码已经删除,可在文章末尾链接中获得完整代码):

    public class LuaBehaviourScript : MonoBehaviour {
        //记录LUA模块名称
        public string           ScriptName;
        //记录LUA脚本对象
        protected LuaTable      self_;
    
        protected void Awake()
        {
            //require lua文件,得到返回的LUA类
            LuaTable metatable = (LuaTable)LuaMainInstance.Instance.require(ScriptName);
    
            //从类中找到New函数
            LuaFunction lnew = (LuaFunction)metatable["New"];
    
            //执行New函数生成脚本对象
            object[] results = lnew.Call(metatable, this);
    
            //存贮脚本对象
            self_ = (LuaTable)results[0];
    
            //给脚本对象设置上常用的属性
            self_["transform"] = transform;
            self_["gameObject"] = gameObject;
    
            //尝试调用脚本对象的Awake函数
            CallMethod("Awake");
        }
        protected object[] CallMethod(string func, params object[] args)
        {
            //查找LUA函数
            LuaFunction lfunc = (LuaFunction)self_[func];
            if(lfunc == null)
            {
                return null;
            }
    
            //调用LUA函数。等价于lua语句“self:func(...)”
            int oldTop = lfunc.BeginPCall();
            lfunc.Push(self_); //将self作为第一个参数传入
            lfunc.PushArgs(args);
            lfunc.PCall();
            object[] objs = luaState_.CheckObjects(oldTop);
            lfunc.EndPCall();
            return objs;
        }
    }

    4.添加LUA脚本层

    在Assets/Lua目录下新建LUA脚本Test.lua,核心代码如下:

    --构造Test类
    local Test = {}
    Test.__index = Test --让实例对象的__get方法指向Test类
    
    --给Test类实例化一个对象
    function Test.New(cls)
        local self = {}
        setmetatable(self, cls)
        return self
    end
    
    --Awake方法
    function Test:Awake()
        print("Test:Awake", self)
    end
    
    --将类Test返回。通过require函数的返回值就可以获取到此值了。
    return Test

    5.辅助脚本

    由于各个GameObject的初始化先后顺序不好统一,而且考虑到多个场景切换的情况,tolua提供的LuaClient就没那么好使了。所以我增加了一个LuaMainInstance的单例类,在其构造的时候就初始化一个全局的LuaState,供LUA脚本使用。
    由于不使用LuaClient,所以LuaLooper也无法直接使用了,我就添加了一个派生类LuaWatchdog,用于启动LuaLooper

    6.总结

    将LuaBehaviourScript.cs添加给GameObject之后,并设置上要绑定的Lua模块名称。当GameObject Awake的时候,会自动加载绑定的LUA脚本文件,并创建出脚本对象。后续所有的Untity回调函数,都会通过脚本对象传递到LUA层。
    完整代码下载地址:https://github.com/youlanhai/tolua
    打开Test场景,点击播放,你会看到立方体在垂直方向上下移动。移动的逻辑,就是在Test.lua中实现的。

  • 相关阅读:
    每天一篇文献:A SURVEY OF LEARNING FROM DEMONSTRATION USED IN ROBOTICS
    PyBullet(七)在PyBullet中使用VR
    期刊模板搜索网址
    论文阅读:Robot Program Parameter Inference via Differentiable Shadow Program Inversion
    visio画图如何插入到latex中
    win10下TensorFlow-GPU安装(GTX1660+CUDA10+CUDNN7.4)
    Object detection with localization using Unity Barracuda and ARFoundation
    论文阅读:Design and Implementation of a Virtual Reality Application for Mechanical Assembly Training
    Qt开发经验小技巧151-155
    Qt开发经验小技巧146-150
  • 原文地址:https://www.cnblogs.com/ygxsk/p/7693973.html
Copyright © 2011-2022 走看看