• unity lua开发体系搭建


    在前面的文章里面我们已经介绍了怎么样在unity里面配置lua的开发环境,我们可以通过C#代码装载lua的脚本并执行相应的处理,这次我们一步步搭建下lua的开发体系。
    1.基于c#体系所有的类都继承MonoBehaviour在这里lua环境下我们也需要创建一个类似于这个类的东西,我们叫这个类LuaBehaviour在这个类里面我们提供了transform及object的实例

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

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

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

    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 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101

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

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

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

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

    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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    这个类的处理也是很简单定义了一个初始化方法初始化的时候调用enter_login_scene方法这里面找到了场景中物体Cube然后给这个物体添加脚本,这样update处理就能处理到这些脚本的update方法
    5.最后的处理将我们这些造好的轮子驱动起来,如何驱动这些脚本回到我们的main方法中去

    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
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

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

     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);
                }
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

    场景也是极其简单在场景放一个cube即可
    在这里插入图片描述

  • 相关阅读:
    Spring Boot 3.x快速入门
    关于windows下的System32与SysWOW64两个文件夹
    在win7中安装node14.0以上版本
    Java中的读写锁ReentrantReadWriteLock详解,存在一个小缺陷
    L. Lemper Cooking Competition(前缀和/逆序对/树状数组/归并排序)
    【Kubernetes】浅聊Kubernetes中的容器和镜像
    利用Python批量替换文档中特定参数的数值
    智能合约语言对比:Solidity | Vyper | Move | Rust
    数据分析思维分析方法和业务知识——业务指标
    降本增效利器?Share Creators智能数字资产管理系统真香!
  • 原文地址:https://blog.csdn.net/u011048906/article/details/133325057