Unity项目接入xLua的一种流程

1. 导入xlua

首先导入xlua,这个不用多说
在这里插入图片描述

2. 编写C#和Lua交互脚本

基础版本,即xlua自带的版本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
using System;
using System.IO;[Serializable]
public class Injection
{public string name;public GameObject value;
}/// <summary>
/// XLua的原生版本
/// </summary>
public class LuaBehaviour : MonoBehaviour
{public TextAsset luaScript;public Injection[] injections;/// <summary>/// 虚拟机唯一/// </summary>internal static LuaEnv luaEnv = new LuaEnv();/// <summary>/// 上一次的GC时间/// </summary>internal static float lastGCTime = 0; /// <summary>/// GC间隔/// </summary>internal const float GCInterval = 1f;private Action luaStart;private Action luaUpdate;private Action luaOnDestroy;private LuaTable scriptScopeTable;private void Awake(){SetPackagePath();scriptScopeTable = luaEnv.NewTable();//给scriptScopeTable设置__index元表,使其能够访问全局using (LuaTable meta = luaEnv.NewTable()){meta.Set("__index", luaEnv.Global);scriptScopeTable.SetMetaTable(meta);}scriptScopeTable.Set("self", this);foreach (var injection in injections){scriptScopeTable.Set(injection.name, injection.value);}//执行脚本luaEnv.DoString(luaScript.text, luaScript.name, scriptScopeTable);//获得生命周期绑定,这里直接使用scriptScopeTable,代表是使用这个脚本的全局去设置的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();}}private void Start(){if (luaStart != null){luaStart();}}private void Update(){if (luaUpdate != null){luaUpdate();}if (Time.time - lastGCTime > GCInterval){luaEnv.Tick();lastGCTime = Time.time;}}private void OnDestroy(){if (luaOnDestroy != null){luaOnDestroy();}scriptScopeTable.Dispose();luaStart = null;luaUpdate = null;luaOnDestroy = null;injections = null;}/// <summary>/// 设置xlua的加载路径/// </summary>private void SetPackagePath(){//在Unity项目的“Assets”文件夹(或指定的Application.dataPath路径)及其所有子目录中,查找名为“LuaScripts”的目录,并返回一个包含这些目录路径的字符串数组foreach (string dir in Directory.GetDirectories(Application.dataPath,"LuaScripts", SearchOption.AllDirectories)){luaEnv.AddLoader(new FileLoader(dir, ".lua"));luaEnv.AddLoader(new FileLoader(dir, ".lua.txt"));}}
}

Loxodon的版本

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
using System.IO;
using Object = UnityEngine.Object;/// <summary>
/// Loxodon的版本
/// </summary>
[LuaCallCSharp]
public class LoxodonLuaBehaviour : MonoBehaviour
{public ScriptReference script;public VariableArray variables;protected LuaTable scriptEnv;protected LuaTable metatable;protected Action<MonoBehaviour> onAwake;protected Action<MonoBehaviour> onEnable;protected Action<MonoBehaviour> onDisable;protected Action<MonoBehaviour> onUpdate;protected Action<MonoBehaviour> onDestroy;protected Action<MonoBehaviour> onStart;public LuaTable GetMetatable(){return metatable;}protected virtual void Initialize(){var luaEnv = LuaEnvironment.LuaEnv;scriptEnv = luaEnv.NewTable();LuaTable meta = luaEnv.NewTable();meta.Set("__index", luaEnv.Global);scriptEnv.SetMetaTable(meta);meta.Dispose();scriptEnv.Set("target", this);SetPackagePath(luaEnv);string scriptText = (script.Type == ScriptReferenceType.TextAsset)? script.Text.text: string.Format($"require(\"System\");local cls = require(\"{script.FileName}\");return extends(target,cls);");object[] result = luaEnv.DoString(scriptText, string.Format("{0}({1})", "LuaBehaviour", this.name), scriptEnv);if (result.Length != 1 || !(result[0] is LuaTable)){throw new Exception("");}metatable = (LuaTable)result[0];  //这里使用Lua脚本的返回值去设置,即脚本的返回值去绑定生命周期if (variables != null && variables.Variables != null){foreach (var variable in variables.Variables){var name = variable.Name.Trim();if (string.IsNullOrEmpty(name)){continue;}metatable.Set(name, variable.GetValue());}}onAwake = metatable.Get<Action<MonoBehaviour>>("Awake");onEnable = metatable.Get<Action<MonoBehaviour>>("Enable");onDisable = metatable.Get<Action<MonoBehaviour>>("Disable");onStart = metatable.Get<Action<MonoBehaviour>>("Start");onUpdate = metatable.Get<Action<MonoBehaviour>>("Update");onDestroy = metatable.Get<Action<MonoBehaviour>>("Destroy");}protected virtual void Awake(){this.Initialize();if (this.onAwake != null){this.onAwake(this);}}protected virtual void OnEnable(){if (this.onEnable != null){this.onEnable(this);}}protected virtual void OnDisable(){if (this.onDisable != null){this.onDisable(this);}}protected virtual void Start(){if (onStart != null){onStart(this);}}protected virtual void Update(){if (onUpdate != null){onUpdate(this);}}protected virtual void OnDestroy(){if (this.onDestroy != null){this.onDestroy(this);}onDestroy = null;onUpdate = null;onStart = null;onEnable = null;onDisable = null;onAwake = null;if (metatable != null){metatable.Dispose();metatable = null;}if (scriptEnv != null){scriptEnv.Dispose();scriptEnv = null;}}/// <summary>/// 修改lua的loader/// </summary>/// <param name="luaEnv"></param>private void SetPackagePath(LuaEnv luaEnv){//在Unity项目的“Assets”文件夹(或指定的Application.dataPath路径)及其所有子目录中,查找名为“LuaScripts”的目录,并返回一个包含这些目录路径的字符串数组foreach (string dir in Directory.GetDirectories(Application.dataPath,"LuaScripts", SearchOption.AllDirectories)){luaEnv.AddLoader(new FileLoader(dir, ".lua"));luaEnv.AddLoader(new FileLoader(dir, ".lua.txt"));}}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;public class LuaEnvironment
{private static float interval = 2;private static WaitForSecondsRealtime wait;private static LuaEnv luaEnv;//private static IAsyncResult result;public static float Interval{get => interval;set{if (interval <= 0){return;}interval = value;wait = new WaitForSecondsRealtime(interval);}}public static LuaEnv LuaEnv{get{if (luaEnv == null){luaEnv = new LuaEnv();// if (result != null)//     result.Cancel();wait = new WaitForSecondsRealtime(interval);//result = Executors.RunOnCoroutine(DoTick());luaEnv.Tick();}return luaEnv;}}public static void Dispose(){// if (result != null)// {//     result.Cancel();//     result = null;// }if (luaEnv != null){luaEnv.Dispose();luaEnv = null;}wait = null;}private static IEnumerator DoTick(){while (true){yield return wait;try{luaEnv.Tick();}catch (Exception e){Debug.LogError(e);}}}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using Object = UnityEngine.Object;public enum ScriptReferenceType
{TextAsset,FileName
}[Serializable]
public class ScriptReference : ISerializationCallbackReceiver
{
#if UNITY_EDITOR[SerializeField]private Object cachedAsset;
#endif[SerializeField]protected TextAsset text;[SerializeField]protected string fileName;[SerializeField]protected ScriptReferenceType type = ScriptReferenceType.TextAsset;public virtual ScriptReferenceType Type => type;public virtual TextAsset Text => text;public virtual string FileName => fileName;public void OnBeforeSerialize(){Clear();}public void OnAfterDeserialize(){Clear();}protected virtual void Clear(){
#if !UNITY_EDITORswitch (type){case ScriptReferenceType.TextAsset:this.fileName = null;break;case ScriptReferenceType.FileName:this.text = null;break;}
#endif}
}

具体区别可以看两种不同的LuaBehaviour生命周期绑定

然后注意这里的lua文件读取路径设置
在这里插入图片描述
具体可以看xlua中自定义lua文件加载的一种方式
在这里插入图片描述

3.自定义属性面板

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4. Lua脚本部分

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

因为提前设置了Lua文件的读取路径,都在LuaScripts文件夹下

运行
在这里插入图片描述

在这里插入图片描述
Lua脚本执行了对应的逻辑,将text的值变为了“你好”,同时打印了协程的输出

注意使用前让xlua生成代码
在这里插入图片描述

项目链接

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/895094.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

四次挥手详解

文章目录 一、四次挥手各状态FIN_WAIT_1CLOSE_WAITFIN_WAIT_2LAST_ACKTIME_WAITCLOSE 二、双方同时调用close()&#xff0c;FIN_WAIT_1状态后进入CLOSING状态CLOSING状态 三、TIME_WAIT状态详解(1) TIME_WAIT状态下的2MSL是什么MSL &#xff08;报文最大生存时间&#xff09;为…

【嵌入式 Linux 音视频+ AI 实战项目】瑞芯微 Rockchip 系列 RK3588-基于深度学习的人脸门禁+ IPC 智能安防监控系统

前言 本文主要介绍我最近开发的一个个人实战项目&#xff0c;“基于深度学习的人脸门禁 IPC 智能安防监控系统”&#xff0c;全程满帧流畅运行。这个项目我目前全网搜了一圈&#xff0c;还没发现有相关类型的开源项目。这个项目只要稍微改进下&#xff0c;就可以变成市面上目前…

java: framework from BLL、DAL、IDAL、MODEL、Factory using oracle

oracel 21c sql: -- 创建 School 表 CREATE TABLE School (SchoolId CHAR(5) NOT NULL,SchoolName NVARCHAR2(500) NOT NULL,SchoolTelNo VARCHAR2(8) NULL,PRIMARY KEY (SchoolId) );CREATE OR REPLACE PROCEDURE addschool(p_school_id IN CHAR,p_school_name IN NVARCHAR2,p…

1.攻防世界 baby_web

题目描述这里有提示&#xff0c;初始页面 进入题目页面如下 很简洁的页面只有一行HELLO WORLD ctrlu查看了源码也没有信息 用burp suite抓包&#xff0c;并发送到重放器 根据提示&#xff08;初始页面&#xff09;修改访问index.php文件 index.php index.php 是一种常见的…

什么是三层交换技术?与二层有什么区别?

什么是三层交换技术&#xff1f;让你的网络飞起来&#xff01; 一. 什么是三层交换技术&#xff1f;二. 工作原理三. 优点四. 应用场景五. 总结 前言 点个免费的赞和关注&#xff0c;有错误的地方请指出&#xff0c;看个人主页有惊喜。 作者&#xff1a;神的孩子都在歌唱 大家好…

【机器学习】数据预处理之数据归一化

数据预处理之数据归一化 一、摘要二、数据归一化概念三、数据归一化实现方法3.1 最值归一化方法3.2 均值方差归一化方法 一、摘要 本文主要讲述了数据归一化&#xff08;Feature Scaling&#xff09;的重要性及其方法。首先通过肿瘤大小和发现时间的例子&#xff0c;说明了不同…

【AIGC】语言模型的发展历程:从统计方法到大规模预训练模型的演化

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;语言模型的发展历程&#xff1a;从统计方法到大规模预训练模型的演化1 统计语言模型&#xff08;Statistical Language Model, SLM&#xff09;&#xff1a;统…

Java面试题2025-JVM

JVM 1.为什么需要JVM&#xff0c;不要JVM可以吗&#xff1f; 1.JVM可以帮助我们屏蔽底层的操作系统 一次编译&#xff0c;到处运行 2.JVM可以运行Class文件 2.JDK&#xff0c;JRE以及JVM的关系 3.我们的编译器到底干了什么事&#xff1f; 仅仅是将我们的 .java 文件转换成了…

Deepseek的MLA技术原理介绍

DeepSeek的MLA(Multi-head Latent Attention)技术是一种创新的注意力机制,旨在优化Transformer模型的计算效率和内存使用,同时保持模型性能。以下是MLA技术的详细原理和特点: 1. 核心思想 MLA技术通过低秩联合压缩技术,将多个注意力头的键(Key)和值(Value)映射到一…

QML初识

目录 一、关于QML 二、布局定位和锚点 1.布局定位 2.锚点详解 三、数据绑定 1.基本概念 2.绑定方法 3.数据模型绑定 四、附加属性及信号 1.附加属性 2.信号 一、关于QML QML是Qt框架中的一种声明式编程语言&#xff0c;用于描述用户界面的外观和行为&#xff1b;Qu…

java项目之美妆产品进销存管理系统的设计与开发源码(ssm+mysql)

项目简介 美妆产品进销存管理系统的设计与开发实现了以下功能&#xff1a; 美妆产品进销存管理系统的设计与开发的主要使用者分为管理员登录后修改个人的密码。产品分类管理中&#xff0c;对公司内的所有产品分类进行录入&#xff0c;也可以对产品分类进行修改和删除。产品管…

Python(pymysql包)操作MySQL【增删改查】

下载pymysql&#xff1a; pip install pymysql 在MySQL中创建数据库&#xff1a;unicom create database unicom DEFAULT CHARSET utf8 COLLATE utf8_general_ci;use unicom; 在unicom中创建数据表&#xff1a;admin create table admin(id int not null primary key auto_i…

HTTP无状态的概念以及对后端服务的设计会产生的影响

HTTP无状态(Statelessness) 是指每个HTTP请求都是独立的,服务器不会记住或依赖于前一个请求的任何信息。每次请求的处理都与其他请求没有直接关系。也就是说,服务器在处理请求时,不会存储关于客户端状态的信息。 一、HTTP无状态的具体含义 ①每个请求独立:每个请求包含了…

操作系统—进程与线程

补充知识 PSW程序状态字寄存器PC程序计数器&#xff1a;存放下一条指令的地址IR指令寄存器&#xff1a;存放当前正在执行的指令通用寄存器&#xff1a;存放其他一些必要信息 进程 进程&#xff1a;进程是进程实体的运行过程&#xff0c;是系统进行资源分配和调度的一个独立单位…

【基于SprintBoot+Mybatis+Mysql】电脑商城项目之上传头像和新增收货地址

&#x1f9f8;安清h&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;【Spring篇】【计算机网络】【Mybatis篇】 &#x1f6a6;作者简介&#xff1a;一个有趣爱睡觉的intp&#xff0c;期待和更多人分享自己所学知识的真诚大学生。 目录 &#x1f680;1.上传头像 -持久…

Windows下ollama详细安装指南

文章目录 1、Windows下ollama详细安装指南1.1、ollama介绍1.2、系统要求1.3、下载安装程序1.4、安装步骤1.5、验证安装1.6、环境变量配置1.7、模型选择与安装【deepseek 示例】1.7.1、拉取并运行模型1.7.2、进阶使用技巧 1、Windows下ollama详细安装指南 1.1、ollama介绍 olla…

10vue3实战-----实现登录的基本功能

10vue3实战-----实现登录的基本功能 1.基本页面的搭建2.账号登录的验证规则配置3.点击登录按钮4.表单的校验5.账号的登录逻辑和登录状态保存6.定义IAccount对象类型 1.基本页面的搭建 大概需要搭建成这样子的页面: 具体的搭建界面就不多讲。各个项目都有自己的登录界面&#…

vue3 点击图标从相册选择二维码图片,并使用jsqr解析二维码(含crypto-js加密解密过程)

vue3 点击图标从相册选择二维码图片&#xff0c;并使用jsqr解析二维码&#xff08;含crypto-js加密解密过程&#xff09; 1.安装 jsqr 和 crypto-js npm install -d jsqr npm install crypto-js2.在util目录下新建encryptionHelper.js文件&#xff0c;写加密解密方法。 // e…

支持多种网络数据库格式的自动化转换工具——VisualXML

一、VisualXML软件介绍 对于DBC、ARXML……文件的编辑、修改等繁琐操作&#xff0c;WINDHILL风丘科技开发的总线设计工具——VisualXML&#xff0c;可轻松解决这一问题&#xff0c;提升工作效率。 VisualXML是一个强大且基于Excel表格生成多种网络数据库文件的转换工具&#…

【JVM详解四】执行引擎

一、概述 Java程序运行时&#xff0c;JVM会加载.class字节码文件&#xff0c;但是字节码并不能直接运行在操作系统之上&#xff0c;而JVM中的执行引擎就是负责将字节码转化为对应平台的机器码让CPU运行的组件。 执行引擎是JVM核心的组成部分之一。可以把JVM架构分成三部分&am…