【Unity/XLua】xlua自带教程示例分析(二)—— 使用C#控制Lua生命周期函数并为其注入Unity物体依赖

news/2024/10/22 16:49:59/

文章目录

    • 第一步 创建C#类LuaBehaviour,负责控制Lua的生命周期函数,创建Lua文件,内部提供所需生命周期函数和局部变量
    • 第二步 准备C#变量
    • 第三步 Awake函数初始化

第一步 创建C#类LuaBehaviour,负责控制Lua的生命周期函数,创建Lua文件,内部提供所需生命周期函数和局部变量

lua">local speed = 10
local lightCpnt = nilfunction start()print("lua start...")print("injected object", lightObject)lightCpnt = lightObject:GetComponent(typeof(CS.UnityEngine.Light))
endfunction update()local r = CS.UnityEngine.Vector3.up * CS.UnityEngine.Time.deltaTime * speedself.transform:Rotate(r)lightCpnt.color = CS.UnityEngine.Color(CS.UnityEngine.Mathf.Sin(CS.UnityEngine.Time.time) / 2 + 0.5, 0, 0, 1)
endfunction ondestroy()print("lua destroy")
end

lua脚本中,访问了注入的lightObject,并由其成员函数获得该GameObject上的灯光组件

使用CS.UnityEngine访问Unity的变量和函数,设置自身(self在后续C#中被设为了this)的旋转,以及灯光组件的颜色

第二步 准备C#变量

[System.Serializable]
public class Injection
{public string name;public GameObject value;
}
public TextAsset luaScript;
public Injection[] injections;

声明一个TextAsset接收一个需要运行的lua的文本文件,声明一个injections数组用于为lua表注入全局依赖

internal static LuaEnv luaEnv = new LuaEnv(); //all lua behaviour shared one luaenv only!
internal static float lastGCTime = 0;
internal const float GCInterval = 1;//1 second 

声明一个LuaEnv用于运行Lua环境,lastGCTime和GCInterval负责定时进行手动GC操作

private Action luaStart;
private Action luaUpdate;
private Action luaOnDestroy;private LuaTable scriptScopeTable;

三个委托负责用于接收Lua表的对应生命周期函数,LuaTable则代表着一个独立的脚本域,可有效防止脚本间的全局变量,函数的名称冲突


第三步 Awake函数初始化

// 为每个脚本设置一个独立的脚本域,可一定程度上防止脚本间全局变量、函数冲突
scriptScopeTable = luaEnv.NewTable();// 设置其元表的 __index, 使其能够访问全局变量
using (LuaTable meta = luaEnv.NewTable())
{meta.Set("__index", luaEnv.Global);scriptScopeTable.SetMetaTable(meta);
}

使用luaEnv的NewTable函数创建一个新的LuaTable提供给局部脚本域scriptScopeTable

之后创建一个临时的NewTable,将其__index指向lua的全局G表,然后设置为scriptScopeTable的元表,保证了scriptScopeTable可以访问全局变量


// 将所需值注入到 Lua 脚本域中
scriptScopeTable.Set("self", this);
foreach (var injection in injections)
{scriptScopeTable.Set(injection.name, injection.value);
}

将该表的self设置为本C#类,并向其中增加依赖的名称与值


// 如果你希望在脚本内能够设置全局变量, 也可以直接将全局脚本域注入到当前脚本的脚本域中
// 这样, 你就可以在 Lua 脚本中通过 Global.XXX 来访问全局变量
// scriptScopeTable.Set("Global", luaEnv.Global);
// 执行脚本
luaEnv.DoString(luaScript.text, luaScript.name, scriptScopeTable);// 从 Lua 脚本域中获取定义的函数
Action luaAwake = scriptScopeTable.Get<Action>("awake");
scriptScopeTable.Get("start", out luaStart);
scriptScopeTable.Get("update", out luaUpdate);
scriptScopeTable.Get("ondestroy", out luaOnDestroy);if (luaAwake != null)
{luaAwake();
}

使用luaEnv的DoString进行脚本执行,参数分别是脚本内容,脚本名称,需要存储到的LuaTable

之后从该脚本中拿出声明周期函数,并绑定到对应的C#委托中,并进行调用


// Use this for initialization
void Start()
{if (luaStart != null){luaStart();}
}// Update is called once per frame
void Update()
{if (luaUpdate != null){luaUpdate();}if (Time.time - LuaBehaviour.lastGCTime > GCInterval){luaEnv.Tick();LuaBehaviour.lastGCTime = Time.time;}
}void OnDestroy()
{if (luaOnDestroy != null){luaOnDestroy();}scriptScopeTable.Dispose();luaOnDestroy = null;luaUpdate = null;luaStart = null;injections = null;
}

http://www.ppmy.cn/news/1505337.html

相关文章

二分查找法

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…

STM32常见的下载方式有三种

经过对比&#xff0c;推荐使用 SWD下载&#xff0c;只需要一个仿真器&#xff08;如jLINK、ST LINK、 CMSIS DAP 等&#xff09;&#xff0c;比较方便。 不推荐使用串口下载&#xff08;速度慢、无法仿真和调试&#xff09;和 JTAG 下载&#xff08;占用 IO 多&#xff09;。

贪心算法part03

134 加油站 在一条环路上有 N 个加油站&#xff0c;其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车&#xff0c;从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发&#xff0c;开始时油箱为空。 如果你可以绕环路行…

SocketIO推送连接后,收不到服务端推送数据问题分析

重点需要注意前端和后端的SocketIO的版本&#xff0c;socketio在2.0.x才开始支持4.0协议。 可以看https://mvnrepository.com/artifact/com.corundumstudio.socketio/netty-socketio&#xff0c;引用最新版本。 <dependency><groupId>com.corundumstudio.socketi…

【HarmonyOS NEXT星河版开发学习】小型测试案例04-个人中心顶部导航

个人主页→VON 收录专栏→鸿蒙开发小型案例总结​​​​​ 基础语法部分会发布于github 和 gitee上面&#xff08;暂未发布&#xff09; 前言 主轴对齐方式在鸿蒙开发中非常重要&#xff0c;通过合理选择 justifyContent 和 alignItems 属性&#xff0c;开发者可以精确控制 Fle…

最新CSS3纵向菜单的实现

纵向菜单 通过下面例子&#xff0c;你会知道把列表转换成菜单的关键技术 a中的#是URL的占位符可以点击&#xff0c;真正用途中写实际URL <nav class"list1"><ul><li><a href"#">Alternative</a></li><li><…

练习实践-基础设施:搭建时钟同步服务器-基于chrony软件在centos7系统上的实现

参考来源&#xff1a;B站视频&#xff1a;up主&#xff1a;林哥讲运维 【一分钟学会&#xff1a;使用 chrony 部署企业 NTP 时间服务器】 https://chrony-project.org/comparison.html --chrony组织的比较 https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/…

SQL注入实例(sqli-labs/less-11)

0、初始页面 1、确定闭合字符 2、确定列数 3、确定回显位置 4、爆库名 a union select user(),database() # 5、爆表名 a union select 1,group_concat(table_name) from information_schema.tables where table_schemasecurity# 6、爆列名 a union select 1,group_concat(c…