unity lua开发体系搭建

在前面的文章里面我们已经介绍了怎么样在unity里面配置lua的开发环境,我们可以通过C#代码装载lua的脚本并执行相应的处理,这次我们一步步搭建下lua的开发体系。

1.基于c#体系所有的类都继承MonoBehaviour在这里lua环境下我们也需要创建一个类似于这个类的东西,我们叫这个类LuaBehaviour在这个类里面我们提供了transform及object的实例

lua 复制代码
local LuaBehaviour = {}
function LuaBehaviour:new(instant) 
	if not instant then 
		instant = {} --类的实例
	end
	setmetatable(instant, {__index = self}) 
	return instant
end

-- 返回一个基类为base的类;
function LuaExtend(base) 
	return base:new()
end

function LuaBehaviour:init(obj)
	self.transform = obj.transform
	self.gameObject = obj
end

return LuaBehaviour

这里面提供三个方法 new方法创建实例对象,init创建实例化对象后初始化游戏要用到,最后一个方法可以理解为继承后面我们会介绍到。

2.上面的init方法我们可以看到有两个对象transform以及gameobject这两个对象是怎么来的可以看到transform是gameobject点出来的,那我们是不是需要一个gameobject的基类我们叫做LuaGameObject

类代码如下

lua 复制代码
LuaGameObject = {}

local GameObject = CS.UnityEngine.GameObject
local GameObjectMap = {}
-- key ObjectID:  {lua组件实例1, Lua组件实例2, ...};

local function Instantiate(prefab)
	GameObject.Instantiate(prefab)
end

local function Destroy(obj)
	local obj_id = obj:GetInstanceID()
	if (GameObjectMap[obj_id]) then -- 删除掉所有的组件实例
		table.remove(GameObjectMap, obj_id)
	end

	GameObject.Destroy(obj)
end

local function Find(name)
	return GameObject.Find(name)
end

local function AddLuaComponent(obj, lua_class)
	local componet = lua_class:new()
	componet:init(obj) 

	local obj_id = obj:GetInstanceID()

	if (GameObjectMap[obj_id]) then
		table.insert(GameObjectMap[obj_id], componet)
	else
		GameObjectMap[obj_id] = {}
		table.insert(GameObjectMap[obj_id], componet)
	end

	if componet.Awake ~= nil then 
		componet:Awake()
	end
	
	return componet
end

local function trigger_update(components_array)
	local key, value
	for key, value in pairs(components_array) do
		if value.Update ~= nil then
			value:Update()
		end
	end
end

local function trigger_fixupdate(components_array)
	local key, value
	for key, value in pairs(components_array) do
		if value.FixedUpdate ~= nil then
			value:FixedUpdate()
		end
	end
end

local function trigger_lateupdate(components_array)
	local key, value
	for key, value in pairs(components_array) do
		if value.LateUpdate ~= nil then
			value:LateUpdate()
		end
	end
end

local function Update()
	local key, value
	for key, value in pairs(GameObjectMap) do
		trigger_update(value)
	end
end

local function FixedUpdate()
	local key, value
	for key, value in pairs(GameObjectMap) do
		trigger_fixupdate(value)
	end
end

local function LateUpdate()
	local key, value
	for key, value in pairs(GameObjectMap) do
		trigger_lateupdate(value)
	end
end

LuaGameObject.Update = Update
LuaGameObject.LateUpdate = LateUpdate
LuaGameObject.FixedUpdate = FixedUpdate

LuaGameObject.Find = Find
LuaGameObject.Instantiate = Instantiate
LuaGameObject.Destroy = Destroy
LuaGameObject.AddLuaComponent = AddLuaComponent

return LuaGameObject 

上面我们提供了几个方法有需要的话可以继续添加方法以满足开发的需要。 Find函数负责找到我们需要的GameObject,Instantiate用过预制体的伙伴都熟悉这个函数负责实例化对象用的,Destroy不用说销毁对象用的这里需要注意的是我们表里面跟这个对象挂钩的数据也要一并清理掉。AddLuaComponent这块是重点我们处理逻辑是将脚本实例化,并调用init方法初始化object以及transform跟上面的LuaBehaviour脚本对应上了,将脚本存放到表中去,这样做的目的主要是在update里面调用脚本上面的update函数等等。

3.假如我们需要通过lua控制一个物体不断移动我们试着建立一个脚本叫做cube_ctrl继承LuaBehaviour

lua 复制代码
local LuaBehaviour = require("Component.LuaBehaviour")
local cube_ctrl = LuaExtend(LuaBehaviour)

function cube_ctrl:Awake()
	print("========Awake=========")
end 

function cube_ctrl:Update()
	self.transform:Translate(0, 0, 5 * CS.UnityEngine.Time.deltaTime)
end

return cube_ctrl

4.我们添加一个场景游戏启动类

lua 复制代码
local start = {}
local cube_ctrl = require("game.cube_ctrl")

local function enter_login_scene()
	print("enter_login_scene")
	local obj = LuaGameObject.Find("Cube")
	LuaGameObject.AddLuaComponent(obj, cube_ctrl)
end

local function enter_game_scene()
end

local function init()
	enter_login_scene()
end
start.init = init
return start;

这个类的处理也是很简单定义了一个初始化方法初始化的时候调用enter_login_scene方法这里面找到了场景中物体Cube然后给这个物体添加脚本,这样update处理就能处理到这些脚本的update方法

5.最后的处理将我们这些造好的轮子驱动起来,如何驱动这些脚本回到我们的main方法中去

lua 复制代码
require("managers.LuaGameObject")
local game = require("game.start")

main = {} -- main是一个全局模块;

local function start()
	game.init();
end

local function Update()
	LuaGameObject.Update()
end

local function FixedUpdate()
	LuaGameObject.FixedUpdate()
end


local function LateUpdate()
	LuaGameObject.LateUpdate()
end

main.Update = Update
main.FixedUpdate = FixedUpdate
main.LateUpdate = LateUpdate
main.start = start

return main

最后是C#调用代码代码如下

csharp 复制代码
 using UnityEngine;
using XLua;

public class LuaLoader : MonoBehaviour
{
    private LuaEnv luaEnv = null;
    void Start()
    {
        luaEnv = new LuaEnv();
        luaEnv.AddLoader(MyLuaLoader);
        LoadScript("main");
        SafeDoString("main.start()");//执行脚本
    }

    void Update()
    {
        SafeDoString("main.Update()");
    }

    void FixedUpdate()
    {
        SafeDoString("main.FixedUpdate()");
    }

    void LateUpdate()
    {
        SafeDoString("main.LateUpdate()");
    }

    public static byte[] MyLuaLoader(ref string filePath)
    {
        string scriptPath = string.Empty;
        filePath = filePath.Replace(".", "/") + ".lua";
        scriptPath += Application.dataPath + "/LuaScripts/" + filePath;
        return GameUtility.SafeReadAllBytes(scriptPath);//通过文件IO读取lua内容
    }

    public void LoadScript(string scriptName)
    {
        SafeDoString(string.Format("require('{0}')", scriptName));
    }

    public void SafeDoString(string scriptContent)
    { // 执行脚本, scriptContent脚本代码的文本内容;
        if (this.luaEnv != null)
        {
            try
            {
                luaEnv.DoString(scriptContent); // 执行我们的脚本代码;
            }
            catch (System.Exception ex)
            {
                string msg = string.Format("xLua exception : {0}\n {1}", ex.Message, ex.StackTrace);
                Debug.LogError(msg, null);
            }
        }
    }
}

场景也是极其简单在场景放一个cube即可

相关推荐
在路上看风景16 小时前
15. 纹理尺寸是4的倍数
unity
IMPYLH17 小时前
Lua 的 IO (输入/输出)模块
开发语言·笔记·后端·lua
AT~19 小时前
unity 使用Socket和protobuf实现网络连接
unity·游戏引擎
菠萝地亚狂想曲1 天前
使用C语言操作LUA栈
c语言·junit·lua
怣疯knight1 天前
Cocos creator判断节点是否能用的方法
unity·cocos2d
tealcwu1 天前
Google Play的Keystore不可用时的解决方法
unity
呼呼突突1 天前
Unity使用TouchSocket的RPC
unity·rpc·游戏引擎
qq 180809512 天前
从零构建一个多目标多传感器融合跟踪器
unity
平行云2 天前
实时云渲染支持在网页上运行UE5开发的3A大作Lyra项目
unity·云原生·ue5·webgl·虚拟现实·实时云渲染·像素流送