ToLua热更新之LuaFramework框架之Lua组件(四)

1、设计思想

在需要添加Lua组件的游戏物体上添加一个LuaComponent组件,LuaComponent引用一个lua表,这个lua表包含lua组件的各种属性以及Awake、Start等函数,由LuaComponent适时调用Lua表所包含的函数。

下面列举lua组件的文件格式,它包含一个表(如Component),这个表包含property1 、property2 等属性,包含Awake、Start等方法。表中必须包含用于派生对象的New方法,它会创建一个继承自Component的表o,供LuaComponent调用。

Component=    	--组件表
{
	property1 = 100,
	property2 = “helloWorld”
}

function Component:Awake() 
	print("TankCmp Awake name = "..self.name );
end

function Component:Start() 
	print("TankCmp Start name = "..self.name );
End

--更多方法略

function Component:New(obj) 
	local o = {} 
    setmetatable(o, self)  
    self.__index = self  
	return o
end   

2、LuaComponent组件

LuaComponent主要有Get和Add两个静态方法,其中Get相当于UnityEngine中的GetComponent方法,Add相当于AddComponent方法,只不过这里添加的是lua组件不是c#组件。每个LuaComponent拥有一个LuaTable(lua表)类型的变量table,它既引用上述的Component表。

Add方法使用AddComponent添加LuaComponent,调用参数中lua表的New方法,将其返回的表赋予table。

Get方法使用GetComponents获取游戏对象上的所有LuaComponent(一个游戏对象可能包含多个lua组件,由参数table决定需要获取哪一个),通过元表地址找到对应的LuaComponent,返回lua表。代码如下:

using UnityEngine;
using System.Collections;
using LuaInterface; 
using LuaFramework;

public class LuaComponent : MonoBehaviour 
{
	//Lua表
	public LuaTable table;

	//添加LUA组件  
	public static LuaTable Add(GameObject go, LuaTable tableClass)  
	{  
		LuaFunction fun = tableClass.GetLuaFunction("New");
		if (fun == null)
			return null;

		object[] rets = fun.Call (tableClass);
		if (rets.Length != 1)
			return null;

		LuaComponent cmp = go.AddComponent<LuaComponent>();  
		cmp.table = (LuaTable)rets[0];
		cmp.CallAwake ();
		return cmp.table;
	}  

	//获取lua组件
	public static LuaTable Get(GameObject go,LuaTable table)  
	{  
		LuaComponent[] cmps = go.GetComponents<LuaComponent>();  
		foreach (LuaComponent cmp in cmps) 
		{
			string mat1 = table.ToString();
			string mat2 = cmp.table.GetMetaTable().ToString();
			if(mat1 == mat2)
			{
				return cmp.table;
			}
		}
		return null;  
	}  
	//删除LUA组件的方法略,调用Destory()即可  

	void CallAwake () 
	{
		LuaFunction fun = table.GetLuaFunction("Awake");
		if (fun != null)
			fun.Call (table, gameObject);
	}

	void Start () 
	{
		LuaFunction fun = table.GetLuaFunction("Start");
		if (fun != null)
			fun.Call (table, gameObject);
	}

	void Update () 
	{
		//效率问题有待测试和优化
		//可在lua中调用UpdateBeat替代
		LuaFunction fun = table.GetLuaFunction("Update");
		if (fun != null)
			fun.Call (table, gameObject);
	}

	void OnCollisionEnter(Collision collisionInfo)
	{
		//略
	}

    //更多函数略
}

3、调试LuaCompomemt

现在编写名为TankCmp的lua组件,测试LuaCompomemt的功能,TankCmp会在Awake、Start和Update打印出属性name。TankCmp.lua的代码如下:

TankCmp = 
{
	--里面可以放一些属性
	Hp = 100,
	att = 50,
	name = "good tank",
}

function TankCmp:Awake()
	print("TankCmp Awake name = "..self.name );
end

function TankCmp:Start()
	print("TankCmp Start name = "..self.name );
end

function TankCmp:Update()
	print("TankCmp Update name = "..self.name );
end

--创建对象
function TankCmp:New(obj)
	local o = {} 
    setmetatable(o, self)  
    self.__index = self  
	return o
end  

编写Main.lua,给游戏对象添加lua组件。

require "TankCmp"

--主入口函数。从这里开始lua逻辑
function Main()	
    --组件1				
	local go = UnityEngine.GameObject ('go')
	local tankCmp1 = LuaComponent.Add(go,TankCmp)
	tankCmp1.name = "Tank1"
	--组件2
	local go2 = UnityEngine.GameObject ('go2')
	LuaComponent.Add(go2,TankCmp)
	local tankCmp2 = LuaComponent.Get(go2,TankCmp)
	tankCmp2.name = "Tank2"
end

运行游戏,即可看到lua组件的运行结果:

图:程序运行结果

图:程序运行结果


4、坦克组件

下面代码演示用lua组件实现“用键盘控制坦克移动”的功能,TankCmp.lua的代码如下:

TankCmp = 
{
	name = "good tank",
}

function TankCmp:Update(gameObject)
	print("TankCmp Update name = "..self.name );
	
	local Input = UnityEngine.Input;
	local horizontal = Input.GetAxis("Horizontal");
	local verticla = Input.GetAxis("Vertical");
	
	local x = gameObject.transform.position.x + horizontal
	local z = gameObject.transform.position.z + verticla
	gameObject.transform.position = Vector3.New(x,0,z)
end

--创建对象
function TankCmp:New(obj)
	local o = {} 
    setmetatable(o, self)  
    self.__index = self  
	return o
end  

Main.lua先加载坦克模型,然后给他添加lua组件,代码如下:

require "TankCmp"

--主入口函数。从这里开始lua逻辑
function Main()					
	LuaHelper = LuaFramework.LuaHelper;
	resMgr = LuaHelper.GetResManager();
	resMgr:LoadPrefab('tank', { 'TankPrefab' }, OnLoadFinish);
end

--加载完成后的回调--
function OnLoadFinish(objs)
	go = UnityEngine.GameObject.Instantiate(objs[0]);
	LuaComponent.Add(go,TankCmp)
end

运行游戏,即可用键盘的控制坦克移动。

图:坦克组件运行结果

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值