uLua拆分MonoBehavior逻辑

  最近项目准备用uLua实现部分代码热更新。于是去了解了一下uLua的使用方法。既然是项目后期想用uLua,自然有不少代码需要改造,我看了一下最简单的就是先从MonoBehavior开始改造。项目中有不少直接挂在GameObject上的,其中的逻辑相对比较独立,就先从这个开始试一下。

  实验用的脚本长这样:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class MonoBeh : MonoBehaviour {

    // Use this for initialization
    public List gameObjects;
    public float rotateSpeed = 90.0f;
    void Start () {

    }

    // Update is called once per frame
    void Update () {
        for (int idx = 0; idx < gameObjects.Count; ++idx)
        {
            gameObjects[idx].Rotate(0, Time.deltaTime * rotateSpeed, 0);
        }
    }
}

  代码很简单,就是让列表里面的物体一直转转转~

  要使用uLua,首先要从uLua官网下载uLua的Unity插件,目前的版本是1.2.1,需要注意的是uLua在旧版本的Unity运行会有问题,会把Unity直接整崩掉,所以最好升级到4.6.2以上的Unity再用。

  使用uLua的目的是把容易变动的逻辑部分作为Lua脚本嵌入项目,以后这些脚本就可以像普通资源一样通过AssetBundle实现热更新了。要使用Lua脚本,需要用LuaScriptMgr对象,调用DoString方法就可以执行Lua脚本了。下面是改造后的MonoBehavior代码:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using LuaInterface;

public class MonoBeh2 : MonoBehaviour {
    public TextAsset luaScript;
    public List gameObjects;
    public float rotateSpeed = 90.0f;
    private LuaScriptMgr mgr;
    private LuaFunction funUpdate;
    private LuaFunction funSetGameObjects;
    private LuaFunction funSetSpeed;
    // Use this for initialization
    void Start () {
        mgr = new LuaScriptMgr();
        mgr.Start();
        if (luaScript != null)
        {
            mgr.DoString(luaScript.text);
            funUpdate = mgr.GetLuaFunction("logic.Update");
            funSetGameObjects = mgr.GetLuaFunction("logic.SetGameObjects");
            funSetSpeed = mgr.GetLuaFunction("logic.SetRotateSpeed");

            if (funSetGameObjects != null)
            {
                funSetGameObjects.Call((object)gameObjects.ToArray());
            }
            if (funSetSpeed != null)
            {
                funSetSpeed.Call((double)rotateSpeed);
            }
        }
    }

    // Update is called once per frame
    void Update () {
        if (funUpdate != null)
        {
            //fun.Call(这里参数不会写)
            funUpdate.Call((double)Time.deltaTime);
        }
    }

    void OnDestroy()
    {
        if (funUpdate != null)
        {
            funUpdate.Release();
        }
        if (funSetGameObjects != null)
        {
            funSetGameObjects.Release();
        }
        if (funSetSpeed != null)
        {
            funSetSpeed.Release();
        }
    }
}

  这样我们就把Update中做核心工作的代码拿了出去,放到了luaScript中。Lua中的脚本是这样的:

logic = logic or {}
logic.gameObjects = gameObjects or {}
logic.rotateSpeed = 0


function logic.SetGameObjects(objects)
    for i = 0, objects.Length - 1, 1 do
        if logic.gameObjects[i] == nil then
            logic.gameObjects[i] = objects[i]
        end
    end
    print "Call Fun:SetGameObjects"
end

function logic.SetRotateSpeed(speed)
    logic.rotateSpeed = speed
    print "Call Fun:SetRotateSpeed "
end

function logic.Update(deltaTime)
    for i, v in next, logic.gameObjects do
        v:Rotate(0, logic.rotateSpeed * deltaTime, 0)
    end
end

  Unity中的类已经通过uLua生成的xxxWrap.cs的代码引入到Lua中了,所以我们可以直接用,但是我们自己的数据是需要自己传给Lua的,这里我用了两个Set方法。另外需要说的一点是Lua中不能直接用Time.deltaTime,这个值始终是0,所以我在Update里面手动传入了这个值,也可能是我用的方式不对吧,如果有知道怎么用的欢迎交流。总之,作为一次实验性的探索,代码还是写的比较丑的,毕竟只是想先学会用。

你可能感兴趣的:(Unity)