• Lua------------------unity关于lua的使用


    关于Lua在Unity 中的使用

     

    对于手机游戏,如果可以在线更新以实现bug修复、新功能添加等等,其好处自不必多说。

    通过C#的反射机制,也可以实现某种程度上的脚本级更新,具体可以参考

    http://docs.unity3d.com/Documentation/Manual/scriptsinassetbundles.html

    但其中也明确指出了在iOS上不支持反射。所以很自然的,想到使用Lua、Python等脚本语言来解决需求。撇开Python不讲(感兴趣的可以搜索UniPython),来看Lua。

    因为Lua本身使用C语言实现,具有良好的跨平台特性,但我们使用C#来作为主要开发语言,要实现与Lua的混合开发,最好是有一个C#版的Lua。万能的google的帮我找到了UniLua(https://github.com/xebecnan/UniLua),特别感谢其作者xebecnan。PS:xebecnan貌似是云风(云风BLOG)团队的,当看到UniLua是国人实现的,且云风的Unity3d项目也在使用时,便立刻决定试一下:)

    在现在这个项目之前,几乎没有任何的Lua使用经验,完全是从开始。国内关于Lua的书籍和资料貌似都很少,书的话官方的《Lua程序设计》必读,《Lua游戏开发实践指南》也可以快速翻一翻。个人觉得有用的资源还有:

    官方的参考手册-居家旅行必备:http://www.lua.org/manual/5.2/

    简明教程 http://coolshell.cn/articles/10739.html 

    Lua与C++的混合编程入门 http://blog.csdn.net/jason3/article/details/5653487

    关于如何在Unity3d中使用UniLua,wiki上面已经讲的非常清晰了。其中也讲到了如何在Lua中调用C#,不过仅给出了调用静态成员函数的示例,而我仅在此记录一下如何在Lua调用C#中的非静态成员函数。

    现有C#中的People类如下

    复制代码
     1 public class People 
     2 {    
     3     public People(int age)
     4     {
     5         Age = age;
     6     }
     7     
     8     public int Age
     9     {
    10         get;
    11         set;
    12     }
    13     
    14     public bool IsYounger(People other)
    15     {
    16         return (Age < other.Age);
    17     }
    18 }
    复制代码

    如何在lua中调用People的成员函数IsYounger? 

    1. 如何访问C#的对象:使用 light userdata,即使用UniLua提供的 PushLightUserData() 和 ToUserData()

    2. 如何访问C#的成员函数:主要是利用PushCSharpFunction() 接口,但过程略麻烦一些。

      2.1 将C#类中的成员函数都封装为静态成员函数(后附示例代码)

      2.2 将上面的静态成员函数设置为lua的全局变量,以在lua中调用

     示例代码:

    复制代码
     1 public class PeopleLuaWrapper
     2 {
     3     const string CLASS_NAME = "People";
     4     
     5     public static void RegisterCSharpMethod(ILuaState lua)
     6     {
     7         lua.NewTable();
     8         int method_table = lua.GetTop();
     9         
    10         lua.PushString("IsYounger");
    11         lua.PushCSharpFunction(IsYounger);
    12         lua.SetTable(method_table);    //将函数设置为table的一个元素
    13         
    14         lua.SetGlobal(CLASS_NAME);    //设置名为CLASS_NAME的全局表
    15     }
    16     
    17         //! 将原成员函数重新封装为静态成员函数
    18     private static int IsYounger(ILuaState lua)
    19     {
    20         People invoker = (People)lua.ToUserData(1);    //获取成员函数的调用者
    21         People other = (People)lua.ToUserData(2);    //获取成员函数的参数
    22         lua.Pop(2);
    23         
    24         bool is_younger = invoker.IsYounger(other);
    25         lua.PushBoolean(is_younger);    //将函数结果压栈
    26         
    27         return 1;
    28     }
    29 }
    复制代码

    lua中调用C#成员函数:

    复制代码
     1 local function Lua_IsYounger(pa, pb)
     2     is_younger = People.IsYounger(pa, pb)
     3     return is_younger
     4 end
     5 
     6 
     7 return
     8 {
     9     Lua_IsYounger = Lua_IsYounger, 
    10 }
    复制代码

    在C#中调用lua代码:

    复制代码
     1         ILuaState lua = LuaAPI.NewState();
     2         lua.L_OpenLibs();
     3         
     4         PeopleLuaWrapper.RegisterCSharpMethod(lua);
     5         
     6         People pa = new People(12);
     7         People pb = new People(123);        
     8         
     9         var status = lua.L_DoFile("People.lua");
    10         
    11         lua.GetField(-1, "Lua_IsYounger");
    12         lua.PushLightUserData(pa);
    13         lua.PushLightUserData(pb);
    14         lua.Call(2, 1);
    15         
    16         bool is_younger = lua.ToBoolean(-1);
    复制代码

    示例代码毫无实用意义,但应该足以说明如何实现C#与Lua之间的互相调用。

    本人纯粹Lua新手,这种做法也不知是否合理,或者有更简便的实现方法,请指教。

  • 相关阅读:
    java集合部分原材料
    java--Collection继承结构图
    java--类与类之间的关系
    java--BigDecimal类
    java--生成随机数
    java--枚举类型
    java--数字格式化
    Java--包装类型
    Java--StringBuffer和StringBuilder
    Java--String
  • 原文地址:https://www.cnblogs.com/w-wfy/p/7716484.html
Copyright © 2020-2023  润新知