在项目中引入脚本系统有两个好处:
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);
}
}
后面注释掉的,是用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)),
可以参考这篇文章: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脚本放在真实的另一台服务器上,运行游戏后要能得到同样的效果。