美文网首页
ToLua的Example示例学习笔记17_Inherit

ToLua的Example示例学习笔记17_Inherit

作者: 凌枫望星月 | 来源:发表于2020-05-13 15:26 被阅读0次

    展示了Lua继承Unity中的Transform类——新建的LuaTransform类。

    1」代码

    操作代码如下:

            LuaTransform = 
            {                          
            }                                                   
    
            function LuaTransform.Extend(u)         
                local t = {}                        
                local _position = u.position      
                tolua.setpeer(u, t)     
    
                t.__index = t
                local get = tolua.initget(t)
                local set = tolua.initset(t)   
    
                local _base = u.base            
    
                --重写同名属性获取        
                get.position = function(self)                              
                    return _position                
                end            
    
                --重写同名属性设置
                set.position = function(self, v)                                                                
                    if _position ~= v then         
                        _position = v                    
                        _base.position = v                                                                                      
                    end
                end
    
                --重写同名函数
                function t:Translate(...)            
                    print('child Translate')
                    _base:Translate(...)                   
                end    
                               
                return u
            end
            
            
            --既保证支持继承函数,又支持go.transform == transform 这样的比较
            function Test(node)        
                local v = Vector3.one           
                local transform = LuaTransform.Extend(node)                                                         
    
                local t = os.clock()            
                for i = 1, 200000 do
                    transform.position = transform.position
                end
                print('LuaTransform get set cost', os.clock() - t)
    
                transform:Translate(1,1,1)                                                                     
                            
                local child = transform:Find('child')
                print('child is: ', tostring(child))
                
                if child.parent == transform then            
                    print('LuaTransform compare to userdata transform is ok')
                end
    
                transform.xyz = 123
                transform.xyz = 456
                print('extern field xyz is: '.. transform.xyz)
            end
    

    c#代码如下:

            new LuaResLoader();
            lua = new LuaState();        
            lua.Start();
            LuaBinder.Bind(lua);
            lua.DoString(script, "TestInherit.cs");
    
            float time = Time.realtimeSinceStartup;
    
            for (int i = 0; i < 200000; i++)
            {
                Vector3 v = transform.position;            
                transform.position = v;
            }
    
            time = Time.realtimeSinceStartup - time;
            Debugger.Log("c# Transform get set cost time: " + time);        
            lua.Call("Test", transform, true);        
            lua.Dispose();
            lua = null;                
    

    2」需要了解的部分

    • 首先创建空表LuaTransform,LuaTransform.Extend(u)方法用于重写同名属性的get和set,还可以重写同名函数,最后return u。
    • 那么如何写这个Extend方法呢?首先参数和返回值都是u,相当于创建了u的peer表t,在t里加东西:
                local t = {}                        
                local _position = u.position      
                tolua.setpeer(u, t)     
    
                t.__index = t
                local get = tolua.initget(t)
                local set = tolua.initset(t)   
    
                local _base = u.base 
    

    tolua.setpeer(cs_obj,lua_table)将lua_table设置为cs_obj的peer表。此后,在对应c++_obj进行访问的时候,会先去peer表中查询,然后再去对应的metatable中查询。
    tolua.setpeerr(csobj, peer)设置csobj的peer表
    csobj: C#对象在lua中对应的userdata
    peer: 一个lua table
    _base = u.base,理解为base就是原来的还没改动过的那个u,方法,属性都是原来的。
    这样,在重写方法的时候,我们可以先让其执行原来的步骤,再加新语句:

                --重写同名函数
                function t:Translate(...)            
                    print('child Translate')
                    _base:Translate(...)                   
                end  
    

    那这样做有什么好处呢?
    好处就在于速度提升了很多,每次找transform不必去找node的position,而是自己的_position,岂不美哉。
    看一下速度对比:

                t = os.clock()            
                for i = 1, 200000 do
                    node.position = node.position
                end
    
                print('No use LuaTransform get set cost', os.clock() - t)
    
                local transform = LuaTransform.Extend(node)                                                         
    
                local t = os.clock()            
                for i = 1, 200000 do
                    transform.position = transform.position
                end
                print('LuaTransform get set cost', os.clock() - t)
    
    速度对比

    在没有扩展之前,当我们访问或设置userdata不存在的成员的时候,程序就会出错,但是在扩展之后,我们便可以扩展对象的成员。
    访问和设置position的时候就会调用到get.position和set.position。

        function t:AddComponentIfNil(comp)
            if nil == _base:GetComponent(t) then
                _base:AddComponent(comp)
            end
        end
    

    我们还可以修改GameObject的同名方法,例如我们可以将上面的AddComponentIfNil修改为AddComponent。
    参考了Unity3D开发小贴士(七)Lua里扩展C#对象

    相关文章

      网友评论

          本文标题:ToLua的Example示例学习笔记17_Inherit

          本文链接:https://www.haomeiwen.com/subject/czunnhtx.html