LUA框架说明与使用

发表于2017-03-16
评论1 1.28w浏览

Unity热更新就会需要使用LUA,但是有些开发者在项目开发中对LUA框架的使用不是很清楚,为此,下面就给大家介绍下LUA框架的说明和使用。

基本设计理念

·                     类和实例,面向对象

·                     组件(Component)

·                     事件化

·                     类似MonoBehaviour,减少学习成本

实现

详见Framework/LuaBehaviour.lua

Class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
local classic = require 'classic'
local UIUtil = require 'Framework.UIUtil'
 
local LuaBehaviour = classic.class("LuaBehaviour")
 
function LuaBehaviour:_init(target, setting)
  self._target = target
  self._targetID = target:GetInstanceID()
  self._luaOperation = target:GetComponent("LuaOperation")
  self._setting = setting
  self._visibleScope = GScope.Scope.Create("globe.ui." .. self._targetID .. ".visible")
 
  UIUtil.BindElements(self)
end
 
return LuaBehaviour

注意点:

classic

A class system for Lua.
实现了Lua端的继承虚函数的概念

require

使用LuaBehaviour的代码,不要添加在GamePath.lua

return

必须要return,要把脚本中定义的class的原型return出来,以供BehaviourManager来进行实例化
BehaviourManager中的相关代码:

1
2
3
4
5
function BehaviourManager:CreateBehaviour(typename, go)
    local path = typename
    local Class = require(path)
 
    local lb = Class(go)

self, super

1
2
this -> self
  base -> super


C#/C++中的概念是一致的

实例化

脚本中定义的是,而我们实际使用时,使用的实例。这个是和老的Lua代码的本质的区别
由于我们在使用时,使用的是实例,就可以实现组件的概念,可以在一个
Prefab上挂一个脚本,而这个Prefab可以实例化(GameObject.Instantiate)出很多个
示例:


每一个
ExampleListItem(Clone)都有一个Lua那边定义ExampleListItem类的一个实例,是完全独立的,和MonoBehaviour的概念是一致的

有了组件化的支持后,我们就可以把一个复杂的界面,拆解成多个组件,以方便管理重用

事件

·                     OnAwake

·                     OnStart

·                     OnEnable

·                     OnVisible

·                     OnDisable

·                     OnDestroy
这些事件的调用时机和MonoBehaviour一致

OnVisible是一个特殊的自己加的一个函数,用于规避Unity无法控制Awake的顺序的问题
Prefab第一次实例化的时候,OnVisible会在MonoBehaviourStart调用时调用,当一个实例被SetActive时,OnVisible会在MonoBehaviourOnEnable时调用
这种调用次序,可以保证
Setting中所有的ElementsBehaviours都被绑定上了

如果你使用了FrameMediatorUsePool参数,或者自己的类似的Pool的实现,你应该在OnVisible中做UIRefresh操作

如果没有使用池/Pool,直接在OnStartRefresh就好了

Setting

Elements

绑定指定的C#端定义的MonoBehaviour以及GameObject自身

1
2
3
4
5
6
7
8
-- Element支持的参数:
        -- Name      GameObject的Path
        -- Alias     便利访问的名字
        -- Count     一次绑定多个控件,从1开始
        -- Type      需要的MonoBehaviour类型, 不指定则绑定GameObject
        -- Necessary 是否必须找到,Necessary = false时可以不报错
        -- Handles   回调函数
        -- Hide      是否默认隐藏掉

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Elements =
   {
       -- 一次注册多个控件,自动通过数字下标去查找
       -- Item1, Item2, Item3
       {
           Name = "Item",
           Count = 3,
           Type = CS.UIButton,
           Handles =
           {
               onClick = "OnCloseButtonClick",
           }
       },
   },



提供了一个编辑器扩展,可以自动获取到GameObjectPath,获取到的Path保存在剪切板中,粘贴到Lua脚本中即可

Behaviours

绑定Lua端定义的LuaBehaviour

1
2
3
-- Behaviour支持的参数:
        -- Name      GameObject的Path
        -- Alias     便利访问的名字

示例:

1
2
3
4
5
6
Behaviours =
    {
        {
            Name = "PlayerInfo",
        },
    },

Events

预定义,直接绑定的事件,通过FireEvent来触发LuaBehaviour中的成员函数

1
2
3
4
Events =
  {
      ["Event1"] = "OnEvent1"
  },

Timers

预定的Timer绑定,回调也是成员函数

1
2
3
4
5
6
7
8
Timers =
   {
       {
           Name = "SceneLoadedTimer",
           Timer = Timer:Always(1),
           Handler = "CheckSceneLoaded"
       }
   },

StaticActions

提供便利地绑定方式,可以自动绑定C#端的staticevent

1
public static event Action TeammateNumChange;

示例

1
2
3
4
StaticActions =
   {
       BagModel.InfoRefreshEvent = "OnInfoRefreshEvent"
   }

也是成员函数

Coroutine

C#中,我们可以使用Unity提供的Coroutine来方便的执行异步逻辑,Lua中也提供了一个Coroutine的机制,但是,要和Unity配合起来方便使用,还需要做些工作

示例:

1
2
3
4
5
6
7
8
9
10
local co = self:StartCoroutine(function()
        local s = os.time()
        print('start to wait')
        yield_return(CS.UnityEngine.WaitForSeconds(3))
        print('wait interval:', os.time() - s)
 
        local www = CS.UnityEngine.WWW('http://www.baidu.com')
        yield_return(www)
        print(www.bytes)
    end)

接口:

1
2
3
4
5
6
7
8
function LuaBehaviour:StartCoroutine(func)
end
 
function LuaBehaviour:StopCoroutine(co)
end
 
function LuaBehaviour:StopAllCoroutine()
end

实现:

自动封装掉Luacoroutine.yieldcoroutine.resume两个函数调用,IEnumerator的实际等待行为,在LuaOperation上执行

Lua端和LuaOperation中,要维护一个完整的正在等待的东西的列表,这样才可以追踪执行状态,并顺利地执行Stop行为

使用

LuaOperation


Prefab中,AddComponent添加LuaOperation这个组件即可
Class Path需要填写Lua脚本的具体路径,从LuaScripts目录开始,不需要填写LuaScripts
示例:

BehaviourManager

BehaviourManagerLua端管理LuaBehaviour的管理器,所有的LuaBehaviour都是由它创建和销毁的

1
__BehaviourManager:GetBehaviour(behaviour_go:GetInstanceID())

通过这个接口,可以获取到LuaBehaviour实例,并直接调用它的接口等
__BehaviourManager是一个全局变量
behaviour_go是一个GameObject
通过这个接口,可以查找到挂在指定的GameObject上的LuaBehaviour实例

 

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引