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.pswp.cn/news/895094.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/895094.shtml
英文地址,請注明出處:http://en.pswp.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…

解決錯誤:CondaHTTPError: HTTP 000 CONNECTION FAILED for url

解決錯誤&#xff1a;CondaHTTPError: HTTP 000 CONNECTION FAILED for url 查看channels:vim ~/.condarcshow_channel_urls: true channels:- http://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/- http://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/msys2/…

Apache APISIX 快速入門

文章目錄 apisix 快速入門什么是apisix有了 NGINX 和 Kong&#xff0c;為什么還需要 Apache APISIX&#xff1f;軟件架構基于 Nginx 開源版本&#xff0c;而 Nginx 并不支持動態配置&#xff0c;為什么 Apache APISIX 聲稱自己可以實現動態配置&#xff1f; 安裝配置 APISIX配置…

2025嵌入式高頻面試題解析

一、概述 到了年初&#xff0c;是求職者最活躍的時間。本文梳理了嵌入式高頻面試題&#xff0c;幫助求職者更好地準備面試&#xff0c;同時也為技術愛好者提供深入學習嵌入式知識的參考。 二、C 語言基礎 2.1 指針與數組 問題 1&#xff1a;指針和數組的區別是什么&#xf…

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;統…

高效知識管理與分類優化指南:從目錄設計到實踐應用

摘要 本文旨在幫助讀者在信息爆炸時代構建高效的知識管理體系&#xff0c;提供了知識收藏目錄、瀏覽器書簽和電腦文件夾的優化分類方案。知識收藏目錄方案包括工作與項目、記錄與日常、知識管理等八大類&#xff0c;具有邊界清晰、擴展靈活、貼合實際場景等優勢。瀏覽器書簽分類…

OpenAI 實戰進階教程 - 第十二節 : 多模態任務開發(文本、圖像、音頻)

適用讀者與目標 適用讀者&#xff1a;已經熟悉基礎的 OpenAI API 調用方式&#xff0c;對文本生成或數據處理有一定經驗的計算機從業人員。目標&#xff1a;在本節中&#xff0c;你將學會如何使用 OpenAI 提供的多模態接口&#xff08;圖像生成、語音轉錄等&#xff09;開發更…

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…

日志2025.2.9

日志2025.2.9 1.增加了敵人揮砍類型 2.增加了敵人的死亡狀態 在敵人身上添加Ragdoll&#xff0c;死后激活布偶模式 public class EnemyRagdoll : MonoBehaviour { private Rigidbody[] rigidbodies; private Collider[] colliders; private void Awake() { rigidbodi…

HTTP無狀態的概念以及對后端服務的設計會產生的影響

HTTP無狀態(Statelessness) 是指每個HTTP請求都是獨立的,服務器不會記住或依賴于前一個請求的任何信息。每次請求的處理都與其他請求沒有直接關系。也就是說,服務器在處理請求時,不會存儲關于客戶端狀態的信息。 一、HTTP無狀態的具體含義 ①每個請求獨立:每個請求包含了…

操作系統—進程與線程

補充知識 PSW程序狀態字寄存器PC程序計數器&#xff1a;存放下一條指令的地址IR指令寄存器&#xff1a;存放當前正在執行的指令通用寄存器&#xff1a;存放其他一些必要信息 進程 進程&#xff1a;進程是進程實體的運行過程&#xff0c;是系統進行資源分配和調度的一個獨立單位…