ulua(一)上手

在项目中引入脚本系统有两个好处:

1.灵活快速地调试测试各种数值、设定,省却重编译的时间

2.热更新,游戏内容修改后用户不需要重新下载安装


要在Unity中使用Lua脚本,各种解决方案很多,我选择较为热门的ulua来试试。


关于ulua的前世今生、各种奇奇怪怪的项目名字、分别包含哪些东西、可以用来做什么,我想首先是要搞清楚的。这些问题的答案在www.ulua.org这个网站都可以找到,作为一个入门者,一开始感觉一头雾水很正常,网站的文档资料也不算太友好,但耐心反复多看几遍,渐渐自然就明白了。


给自己设定的练习目标

能够用lua脚本对一个已有的UI界面进行修改。

当然完全从零开始创建一套UI我想也是完全行得通的,但这里尽量将问题简化。


为此首先搭建一个测试环境,先做好一个UI prefab,包括顶部一条文字,左下角一张图,和右下角的一个按钮。

场景运行后,程序会载入此prefab,然后运行UIAdjust.lua脚本来进行修改。

代码如下:

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using LuaInterface;

public class Main : MonoBehaviour {

    LuaScriptMgr lua;
    //RectTransform btnTrans;

    void Start () 
    {
        lua = new LuaScriptMgr();
        lua.Start(); 
        InitUI();
    }

    void InitUI()
    {
        GameObject fightUIRes = Resources.Load("UIPrefabs/FightUI") as GameObject;
        GameObject fightUI = Instantiate(fightUIRes);
        fightUI.transform.SetParent(GameObject.Find("Canvas").transform, false);

        AdjustUIwithLua(fightUI);
    }

    void AdjustUIwithLua(GameObject ui)
    {
        LuaState l = lua.lua;
        l["ui"] = ui;
        lua.DoFile("Test/AdjustUI");

        //ui.transform.FindChild("Text").GetComponent().text = "hello";
        //ui.transform.FindChild("Image").GetComponent().color = Color.blue;
        //btnTrans = ui.transform.FindChild("Button").GetComponent();
        //btnTrans.pivot = new Vector2(0, 1);
        //btnTrans.anchorMin = new Vector2(0, 1);
        //btnTrans.anchorMax = new Vector2(0, 1);
        //btnTrans.anchoredPosition = new Vector2(0, 0);
    } 
}


这里头已经包含了如何启动一个Lua虚拟机,如何运行一段脚本,已经如何向脚本传递变量。

后面注释掉的,是用C#代码实现的修改操作,具体就是改变文本内容、图片颜色、及按钮的位置。


然后接下来就是如何编写lua脚本了,代码如下:

--更改Text内容
ui.transform:FindChild("Text"):GetComponent('Text').text = "668"

--更改Image颜色
ui.transform:FindChild("Image"):GetComponent('Image').color = Color.blue

--更改Button位置
btnTrans = ui.transform:FindChild("Button"):GetComponent('RectTransform')
btnTrans.pivot = Vector2.New(0,1)
btnTrans.anchorMin = Vector2.New(0,1)
btnTrans.anchorMax = Vector2.New(0,1)
btnTrans.anchoredPosition = Vector2.New(0, 0)



假如什么也不做,就这么一运行,会发现文本和图片的属性都正常修改了,但按钮的位置死活不对,具体好像是Vector2永远无法正常赋值给btnTrans。

先说下我用的是ulua v1.25的插件unitypackage包。

想要让这段代码顺利得到正确的结果,有几个坑要踩:

1.找到WrapFile.cs,在里头一堆_GT(typeof(xxx))后面,添加上脚本里用到的几个ugui的类,具体是这样:

        //ugui
        _GT(typeof(UIBehaviour)),  
        _GT(typeof(Graphic)), 
        _GT(typeof(MaskableGraphic)), 
        _GT(typeof(Text)), 
        _GT(typeof(Image)),  
        _GT(typeof(RectTransform)),   


2.注意有些类的成员是继承自其父类的,所以父类也要一并Wrap,否则提示无法访问成员变量

可以参考这篇文章:http://bbs.ulua.org/article/faq/guanyuuluaduiuguizhichideyixieyongfa.html


3. Clear Wrap Files、 重新Gen Wrap Files

然后会遇到第三个坑,在自动生成的GraphicWrap文件中,死活找不到UIBehaviour,因为UIBehaviour在UnityEngine.EventSystems命名空间下,而自动生成Wrap文件时,貌似没注意到这点。所以我们在GraphicWrap.cs中手动添加using UnityEngine.EventSystems;


然后就都搞定了,效果如预期,也无警告报错。

这样就算是上手了吧。


整个过程其实很懵逼,仅仅是按着文档说明及各种示例代码一通瞎搞终于得到了结果。假如想更明白些,以下问题恐怕是必须深入研究的:

1.Lua脚本如何被虚拟机执行

2.Lua脚本调用C#函数的反射、Wrap两种机制的原理

另外Lua的语法本身也要弄得更熟些。


这些都需要时间,我不急,后面有机会自然慢慢都能熟练。

下一步打算实践下热更新,具体是把AdjustUI.lua脚本放在真实的另一台服务器上,运行游戏后要能得到同样的效果。

你可能感兴趣的:(ulua)