项目后期Lua接入笔记08--Lua面向对象及LuaBehaviour的再设计

来源:互联网 发布:跨界歌王 潘粤明 知乎 编辑:程序博客网 时间:2024/04/30 09:57

lua类创建和继承的关键是metatable的使用,这里直接使用云风大大的代码(部分修改)

local _class={}function class(super)    local class_type={}    class_type.ctor=false    class_type.super=super    class_type.new=function(...)             local obj={}            do                local create                create = function(c,...)                    if c.super then                        create(c.super,...)                    end                    if c.ctor then                        c.ctor(obj,...)                    end                end                create(class_type,...)            end            setmetatable(obj,{ __index=_class[class_type] })            return obj        end    local vtbl={}    _class[class_type]=vtbl     setmetatable(class_type,{__newindex=        function(t,k,v)            vtbl[k]=v        end    })    if super then               _class[super].base = _class[super];        setmetatable(vtbl,{__index=            function(t,k)                               local ret=_class[super][k]                vtbl[k]=ret                return ret            end        })    end    return class_typeend-----------------------base_type=class()     -- 定义一个基类 base_type--function base_type:ctor(x)    -- 定义 base_type 的构造函数--  print("base_type ctor")--  self.x=x--end--function base_type:print_x()  -- 定义一个成员函数 base_type:print_x--  print(self.x)--end--function base_type:hello()    -- 定义另一个成员函数 base_type:hello--  print("hello base_type")--end---------------------------------test=class(base_type) -- 定义一个类 test 继承于 base_type--function test:ctor()  -- 定义 test 的构造函数--  print("test ctor")--end--function test:hello() -- 重写 base_type:hello 为 test:hello--  test.base.hello(self);  --  print("hello test")--end-----------------------------------------a=test.new(1) -- 输出两行,base_type ctor 和 test ctor 。这个对象被正确的构造了。--a:print_x()   -- 输出 1 ,这个是基类 base_type 中的成员函数。--a:hello() -- 输出 hello test ,这个函数被重载了。 

lua中的使用可以参考上面的注释代码,在c#中我们需要改下以前的luamono类,代码如下

using UnityEngine;using LuaInterface;public class LuaMono : MonoBehaviour{    public string ModualName;    public LuaTable Table { get; private set; }    private bool m_isClass = false;    private LuaFunction m_awakeFunc;    private LuaFunction m_startFunc;    private LuaFunction m_enableFunc;    private LuaFunction m_disableFunc;    private LuaFunction m_destroyFunc;    private LuaFunction m_clickFunc;    private void Awake()    {        if (Table == null)        {            object[] objs = LuaManager.Instance.DoFile(ModualName);            Table = objs[0] as LuaTable;            if (Table == null)            {                Debug.LogError("cant find lua table");            }        }        GetFunction();        if (m_awakeFunc != null)        {            if (m_isClass)            {                m_awakeFunc.Call(Table, gameObject);            }            else            {                m_awakeFunc.Call(gameObject);            }        }    }    protected virtual void GetFunction()    {        m_awakeFunc = Table.GetLuaFunction("Awake");        m_startFunc = Table.GetLuaFunction("Start");        m_enableFunc = Table.GetLuaFunction("OnEnable");        m_disableFunc = Table.GetLuaFunction("OnDisable");        m_destroyFunc = Table.GetLuaFunction("OnDestroy");        m_clickFunc = Table.GetLuaFunction("OnClick");    }    private void Start()    {        if (m_startFunc != null)        {            if (m_isClass)            {                m_startFunc.Call(Table);            }            else            {                m_startFunc.Call();            }        }    }    private void OnEnable()    {        if (m_enableFunc != null)        {            if (m_isClass)            {                m_enableFunc.Call(Table);            }            else            {                m_enableFunc.Call();            }        }    }    private void OnDisable()    {        if (m_disableFunc != null)        {            if (m_isClass)            {                m_disableFunc.Call(Table);            }            else            {                m_disableFunc.Call();            }        }    }    private void OnClick()    {        if (m_clickFunc != null)        {            if (m_isClass)            {                m_clickFunc.Call(Table);            }            else            {                m_clickFunc.Call();            }        }    }    private void OnDestroy()    {        LuaUtils.ClearMemory();        if (m_destroyFunc != null)        {            if (m_isClass)            {                m_destroyFunc.Call(Table);            }            else            {                m_destroyFunc.Call();            }        }    }    private void Reset()    {        ModualName = gameObject.name;    }    public void SetTable(LuaTable lt)    {        Table = lt;        m_isClass = true;    }}

使用方法和以前一样,不过在lua中实例化预制体后需要调用SetTable方法手动赋值。

0 0