Unity学习笔记-XLua在Unity中的简单实现(1)

前言

虽然现在华佗已经横空出世,但是毕竟现在还问世不久。现在市面上的热更新主流方案依旧是Lua,而且也不清楚华佗未来是否真正能成为真正的主流方案,所以即使lua用起来在恶心还是依旧得去用。

Lua方案常见的为XLua和ToLua,这里选用XLua进行测试,简单实现下面几个部分:

1.采用代理模式实现Lua脚本在物体上的热加载

2.实现lua中的面对对象,也就是封装继承多态

3.AB包加载使用

4.完成一个lua小项目

Lua脚本挂载实现

显而易见,我们不能直接将lua脚本像在C#中一样,C#可以继承Mono,Lua应该还做不到,那我们该如何处理这个问题

采用代理模式可以很好的解决这一点,通过中间脚本LuaComponent来实现,如果你不了解代理模式的话可以详细了解一下代理模式,只要你了解了代理模式就可以轻松的理解如何做到这一点。

我们将LuaComponent继承Mono,在lua中调用该脚本,将LuaComponent挂载到物体上,其次通过LuaComponent在start,update等函数间接调用我们想实现的Lua函数就可以。

具体实现代码直接复制的别人的,(毕竟我总感觉Lua在未来可能会被取代,不想深究了,大致了解原理就好了)简单理解就是lua挂载脚本后,传入一个LuaTable,在通过LuaTable找到对应的同名函数间接调用

复制粘贴到你的项目中

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
using System.IO;
using System;
/// <summary>
/// lua挂载脚本
/// 代理模式
/// </summary>
[LuaCallCSharp]
public class LuaComponent : MonoBehaviour
{

	public LuaTable luaTable;
	LuaFunction luaStart;
	LuaFunction luaUpdate;
	LuaFunction luaOnDestroy;
	LuaFunction luaAwake;
	LuaFunction luaOnEnable;
	LuaFunction luaFixedUpdate;
	LuaFunction luaOnDisable;
	LuaFunction luaLateUpdate;


	/// <summary>
	/// 添加lua组件
	/// </summary>
	/// <param name="go"></param>
	/// <param name="tableClass"></param>
	/// <returns></returns>
	public static LuaTable Add(GameObject go, LuaTable tableClass)
	{
		LuaFunction luaCtor = tableClass.Get<LuaFunction>("ctor");
		if (null != luaCtor)
		{
			object[] rets = luaCtor.Call(tableClass);
			if (1 != rets.Length)
			{
				return null;
			}
			LuaComponent cmp = go.AddComponent<LuaComponent>();
			cmp.luaTable = (LuaTable)rets[0];
			cmp.initLuaFunction();
			cmp.CallAwake();
			return cmp.luaTable;
		}
		else
		{
			throw new Exception("Lua function .ctor not found");
		}


	}

	/// <summary>
	/// 获取lua组件
	/// </summary>
	/// <param name="go"></param>
	/// <param name="table"></param>
	/// <returns></returns>
	public static LuaTable Get(GameObject go, LuaTable table)
	{
		LuaComponent[] cmps = go.GetComponents<LuaComponent>();
		string tableStr = table.ToString();
		for (int i = 0; i < cmps.Length; i++)
		{
			string temp = cmps[i].luaTable.ToString();
			if (string.Equals(tableStr, cmps[i].luaTable.ToString()))
			{
				return cmps[i].luaTable;
			}
		}
		return null;

	}

	/// <summary>
	/// 设置组件父节点
	/// </summary>
	/// <param name="go"></param>
	/// <param name="parent"></param>
	public static void SetParent(GameObject go, Transform parent)
	{
		go.transform.SetParent(parent);
	}

	/// <summary>
	/// 初始化Lua脚本中的方法
	/// </summary>
	void initLuaFunction()
	{
		luaOnDestroy = luaTable.Get<LuaFunction>("OnDestroy");
		luaAwake = luaTable.Get<LuaFunction>("Awake");
		luaStart = luaTable.Get<LuaFunction>("Start");
		luaUpdate = luaTable.Get<LuaFunction>("Update");
		luaOnEnable = luaTable.Get<LuaFunction>("OnEnable");
		luaFixedUpdate = luaTable.Get<LuaFunction>("FixedUpdate");
		luaOnDisable = luaTable.Get<LuaFunction>("OnDisable");
		luaLateUpdate = luaTable.Get<LuaFunction>("LateUpdate");
	}

	/// <summary>
	/// 调用lua脚本中定义的Awake方法
	/// </summary>
	void CallAwake()
	{
		if (null != luaAwake)
		{
			luaAwake.Call(luaTable, gameObject);
		}
	}

	/// <summary>
	/// 调用lua脚本中定义的Start方法
	/// </summary>
	private void Start()
	{

		if (null != luaStart)
		{
			luaStart.Call(luaTable, gameObject);
		}
	}

	/// <summary>
	/// 调用lua脚本中定义的Update方法
	/// </summary>
	private void Update()
	{
		if (null != luaUpdate)
		{
			luaUpdate.Call();
		}
	}

	/// <summary>
	/// 调用lua脚本中定义的FixedUpdate方法
	/// </summary>
	private void FixedUpdate()
	{
		if (null != luaFixedUpdate)
		{
			luaFixedUpdate.Call();
		}
	}

	/// <summary>
	/// 调用lua脚本中定义的OnDestroy方法
	/// </summary>
	private void OnDestroy()
	{
		if (null != luaOnDestroy)
		{
			luaOnDestroy.Call();
		}
	}

	/// <summary>
	/// 调用lua脚本中定义的 OnEnable
	/// </summary>
	private void OnEnable()
	{
		if (null != luaOnEnable)
		{
			luaOnEnable.Call();
		}
	}

	/// <summary>
	/// 调用lua脚本中定义的 OnDisable
	/// </summary>
	private void OnDisable()
	{
		if (null != luaOnDisable)
		{
			luaOnDisable.Call();
		}
	}

	/// <summary>
	/// 调用lua脚本中定义的 LateUpdate
	/// </summary>
	private void LateUpdate()
	{
		if (null != luaLateUpdate)
		{
			luaLateUpdate.Call();
		}
	}
}


在lua中该如何使用:

print("lua脚本执行开始")
--要做的几件件事情
--1:代理模式
--2:实现面对对象的模式
--3:加载Unity内部的一些API
UnityEngine = CS.UnityEngine
GameObject = CS.UnityEngine.GameObject
UI = CS.UnityEngine.UI
Vector3 = UnityEngine.Vector3
Vector2 = UnityEngine.Vector2
LuaComponent = CS.LuaComponent
--Test
Monster = {}
function Monster:Start()
	print("StartLua")
end

function Monster:ctor()
	local obj = {}
	self.__index = self
	setmetatable(obj, self)
	return obj
end

local go = GameObject("LuaComponent")
LuaComponent.Add(go, Monster)

猜你喜欢

转载自blog.csdn.net/qq_55042292/article/details/125446920