C#调用Lua方法1+C#调用Lua方法2,3

news2025/4/19 14:13:04

xLua中Lua调用C#代码

        原因:C#实现的系统,因为Lua可以调用,所以完全可以换成Lua实现,因为Lua可以即时更改,即时运行,所以游戏的代码逻辑就可以随时更改。

        实现和C#相同效果的系统,如何实现?

                Lua调用Unity的各种API,从而实现C#开发系统同样的效果

xLua中C#调用Lua代码

        原因:Unity是基于C#语言开发的,所有生命周期函数都是基于C#实现,xLua本身是不存在Unity的相关生命周期函数的。如果希望xLua能够拥有生命周期函数,那么我们可以实现C#作为Unity原始调用,再使用C#调用Lua对应的方法。

具体代码示例:

在前几节提到的使用单例模式的xLuaEnv代码中添加如下代码:

 //返回Lua环境的全局变量
    public LuaTable Global
    {
        get
        {
            return _Env.Global;
        }
    }

添加CSharpCallVariable脚本代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;

public class CSharpCallVariable : MonoBehaviour
{
    void Start()
    {
        xLuaEnv.Instance.DoString("return require('L2C/CSharpCallVariable')");
        //Debug.Log(data[0]);
        //LuaEnv提供了一个成员变量Global,它可以用于C#获取Lua的全局变量
        //Global的数据类型是C#实现的LuaTable,LuaTable是xLua实现的C#和Lua中表对应的数据结构
        //xLua会将Lua中的全局变量以Table的方式全部存储在Global中

        //通过运行环境,导出全局变量,类型是LuaTable
        //LuaTable是C#的数据对象,用于和Lua中的全局变量存储的table对应
        LuaTable g = xLuaEnv.Instance.Global;

        //从Lua中,将全局变量提取出来
        //参数:Lua中全局变量的名称
        //类型:Lua中全局变量的名称所对应的类型
        //返回值:变量的值
        int num = g.Get<int>("num");
        float rate = g.Get<float>("rate");
        bool isWoman = g.Get<bool>("isWoman");
        string name=g.Get<string>("name");

        Debug.Log("数字:" + num);
        Debug.Log("浮点数:" + rate);
        Debug.Log("布尔:" + isWoman);
        Debug.Log("字符串:" + name);
    }

    // Update is called once per frame
    void OnDestroy()
    {
        xLuaEnv.Instance.Free();
    }
}

Lua相关代码如下:

--隐性做了{num=100,rate=99.99,isWoman=false,name="admin"}
num=100
rate=99.99
isWoman=false
name="admin"

 运行测试结果如下:

使用C#代码调用Lua代码的函数

相关详细代码如下所示:

//C#相关代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;

public delegate void Func1();
public delegate void Func2(string name);
public delegate string Func3();
//映射产生时,xLua提示添加的

[CSharpCallLua]
public delegate void Func4(out string name, out int id);
public class CSharpCallFunction : MonoBehaviour
{
    void Start()
    {
        xLuaEnv.Instance.DoString("return require('L2C/CSharpCallFunction')");
        LuaTable g = xLuaEnv.Instance.Global;
        //Lua的函数,会导出为C#的委托类型
        Func1 func1=g.Get<Func1>("func1");
        func1();

        //向Lua函数传递数据
        Func2 func2 = g.Get<Func2>("func2");
        func2("admin");
        
        //接收Lua函数的返回值
        Func3 func3=g.Get<Func3>("func3");
        Debug.Log(func3()+",被C#打印");

        //Lua多返回值
        Func4 func4 = g.Get<Func4>("func4");
        string name;
        int id;
        func4(out name,out id);
        Debug.Log(name + "," + id);

    }
    // Update is called once per frame
    void OnDestroy()
    {
        xLuaEnv.Instance.Free();
    }
}
--Lua相关代码
func1=function()
	print("这是Lua中的func1")
end
func2=function(name)
	print("这是Lua中的func2,参数是:"..name)
end
--Lua的函数会导出为C#的委托
func3=function()
	return "这是Lua中的func3"
end
func4=function()
	return "这是Lua中的func4",100
end

运行效果如图所示:

使用C#代码调用Lua代码的结构体

详细代码如下所示:

//C#代码如下所示
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;

public delegate void OneStringParams(string name);
public delegate void TransSelf(LuaTable table);

//针对结构体调用后添加
public delegate string OneStringReturn();
[CSharpCallLua]
public delegate void TransMy(LuaCore table);

//Lua映射table过来,需要有个结构体进行对应
//Lua的table导出到C#的结构体,可以实现C#运行时无GC
[GCOptimize]
public struct LuaCore
{
    public int ID;
    public string Name;
    public bool IsWoman;

    public OneStringParams Func1;
    public OneStringReturn Func2;
    public TransMy Func3;
    public TransMy Func4;
}
public class CSharpCallTable : MonoBehaviour
{
    void Start()
    {
        xLuaEnv.Instance.DoString("require('L2C/CSharpCallTable')");
        //UseLuaTable();
        UseStruct();
    }
    public void UseLuaTable()
    {
        LuaTable g = xLuaEnv.Instance.Global;

        //获取的是全局变量Core,因为它在Lua中是表,所以取出的是LuaTable
        LuaTable core = g.Get<LuaTable>("Core");
        //获取Name
        //参数:table中索引名
        //类型:索引对应值的类型
        Debug.Log(core.Get<string>("Name"));

        core.Set<string, string>("Name", "admin");
        OneStringParams osp = core.Get<OneStringParams>("Func1");
        osp("admin");

        //相当于":"调用
        TransSelf ts = core.Get<TransSelf>("Func4");
        ts(core);
    }

    public void UseStruct()
    {
        LuaTable g = xLuaEnv.Instance.Global;

        //将Lua的table导出为core
        LuaCore core=g.Get<LuaCore>("Core");
        Debug.Log(core.Name);
        core.Func4(core);
    }

    // Update is called once per frame
    void OnDestroy()
    {
        xLuaEnv.Instance.Free();
    }
}
--Lua代码如下所示
Core={}

Core.ID=100
Core.Name="root"
Core.IsWoman=false

Core.Func1=function(name)
	print("这是Core表的Func1函数,接收到C#数据"..name)
end

Core.Func2=function()
	return "这是Core表的Func2函数"
end
Core.Func3=function(self)
	print("这是Core表的Func3函数,Core表的成员变量Name是"..self.Name)
end

function Core:Func4()
	print("这是Core表的Func4函数,Core表的成员变量Name是"..self.Name)
end

当出现以下问题提示添加[CSharpCallLua]解决问题,在代码中添加后却依然报错,可尝试以下方式解决问题:

按下上图按键后重新运行游戏,报错即可消失

更多有关于Lua与CS之间相互调用的相关知识:

https://shenjun-coder.github.io/LuaBook

该系列专栏为网课课程笔记,仅用于学习参考。

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

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

相关文章

NO.77十六届蓝桥杯备战|数据结构-单调队列|质量检测(C++)

什么是单调队列&#xff1f; 单调队列&#xff0c;顾名思义&#xff0c;就是存储的元素要么单调递增要么单调递减的队列。注意&#xff0c;这⾥的队列和普通的队列不⼀样&#xff0c;是⼀个双端队列。单调队列解决的问题 ⼀般⽤于解决滑动窗⼝内最⼤值最⼩值问题&#xff0c;以…

通过发票四要素信息核验增值税发票真伪-iOS发票查验接口

发票是企业经济间往来的重要凭证&#xff0c;现如今&#xff0c;随着经济环境的日益复杂&#xff0c;发票造假现象屡禁不止&#xff0c;这使得增值税发票查验成为企业必须高度重视的工作。人工智能时代&#xff0c;发票查验接口犹如一道坚固的防线&#xff0c;助力企业财务守护…

【JAVA】十、基础知识“类和对象”干货分享~(三)

目录 1. 封装 1.1 封装的概念 1.2 访问限定符 public&#xff08;公开访问&#xff09; private&#xff08;私有访问&#xff09; 1.3 包 1.3.1 包的概念 1.3.2 导入包中的类 1.3.3 自定义包 2. static成员 2.1 static变量&#xff08;类变量&#xff09; 2.1.1 sta…

DeepSeek+SpringAI家庭AI医生

文章目录 项目架构项目开发内容项目用户用例图项目地址开发环境大模型使用本地&#xff1a;Ollama部署DeepSeek离线与在线api大模型客户端使用 数据库脚本代码deepseek创建定制医生模型 内网互通原则云服务器类型 项目架构 项目开发内容 项目用户用例图 项目地址 FamilyAIDoct…

PyTorch:解锁AI新时代的钥匙

&#xff08;前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff09;。 揭开PyTorch面纱 对于许多刚开始接触人工智能领域的朋友来说&#xff0c;PyTorch这个名字或许既熟悉又陌生。…

C++第14届蓝桥杯b组学习笔记

1. 日期统计 小蓝现在有一个长度为 100100 的数组&#xff0c;数组中的每个元素的值都在 00 到 99 的范围之内。数组中的元素从左至右如下所示&#xff1a; 5 6 8 6 9 1 6 1 2 4 9 1 9 8 2 3 6 4 7 7 5 9 5 0 3 8 7 5 8 1 5 8 6 1 8 3 0 3 7 9 2 7 0 5 8 8 5 7 0 9 9 1 9 4 4…

解锁工业通信:Profibus DP到ModbusTCP网关指南!

解锁工业通信&#xff1a;Profibus DP到ModbusTCP网关指南&#xff01; 在工业自动化领域&#xff0c;随着技术的不断进步和应用场景的日益复杂&#xff0c;不同设备和系统之间的通讯协议兼容性问题成为了工程师们面临的一大挑战。尤其是在Profibus DP和Modbus/TCP这两种广泛应…

每日一题(小白)字符串娱乐篇16

分析题意可以了解到本题要求在一串字符串中找到所有组合起来排序递增的字符串。我们可以默认所有字符在字符串中的上升序列是1&#xff0c;从第一个字符开始找&#xff0c;如果后面的字符大于前面的字符就说明这是一个上序列那么后面字符所在的数组加一&#xff0c;如果连接不上…

如何深刻理解Reactor和Proactor

前言&#xff1a; 网络框架的设计离不开 I/O 线程模型&#xff0c;线程模型的优劣直接决定了系统的吞吐量、可扩展性、安全性等。目前主流的网络框架&#xff0c;在网络 IO 处理层面几乎都采用了I/O 多路复用方案(又以epoll为主)&#xff0c;这是服务端应对高并发的性能利器。 …

java基础 数组Array的介绍

Array 数组定义一维数组多维数组动态数组常见方法Arrays排序1.sort() 排序 2.parallelSort() 排序 查找&#xff1a;binarySearch()填充&#xff1a;fill()比较&#xff1a;equals() 和 deepEquals()复制&#xff1a;copyOf() 和 copyOfRange()转换为列表&#xff1a;asList()转…

我的NISP二级之路-02

目录 一.数据库 二.TCP/IP协议 分层结构 三.STRIDE模型 四.检查评估与自评估 检查评估 自评估 五.信息安全应急响应过程 六.系统工程 七.SSE-CMM 八.CC标准 九.九项重点工作 记背: 一.数据库 关于数据库恢复技术&#xff0c;下列说法不正确的是&#xff1a…

常见的微信个人号二次开发功能

一、常见开发功能 1. 好友管理 好友列表维护 添加/删除好友 修改好友信息&#xff08;备注、标签等&#xff09; 分组管理 创建/编辑/删除标签 好友分类与筛选 2. 消息管理 信息发送 支持多类型内容&#xff1a;文本、图片、视频、文件、小程序、名片、URL链接等 附加功…

unity的dots中instantiate克隆对象后,对象会在原位置闪现的原因和解决

原因 在Entity中有两个位置信息&#xff0c;一个是local transform。一个是local to world 其中local transform负责具体位置&#xff0c;local to world 负责渲染位置&#xff0c;即图像的渲染的位置是根据local to world的。 local to world 的更新是引擎自己控制的&#x…

R语言——绘制生命曲线图(细胞因子IL5)

绘制生命曲线图&#xff08;根据细胞因子&#xff09; 说明流程代码加载包读取Excel文件清理数据重命名列名处理IL-5中的"<"符号 - 替换为检测下限的一半首先找出所有包含"<"的值检查缺失移除缺失值根据IL-5中位数将患者分为高低两组 创建生存对象拟…

神马系统8.5搭建过程,附源码数据库

项目介绍 神马系统是多年来流行的一款电视端应用&#xff0c;历经多年的发展&#xff0c;在稳定性和易用性方面都比较友好。 十多年前当家里的第一台智能电视买回家&#xff0c;就泡在某论坛&#xff0c;找了很多APP安装在电视上&#xff0c;其中这个神马系统就是用得很久的一…

大模型论文:Improving Language Understanding by Generative Pre-Training

大模型论文&#xff1a;Improving Language Understanding by Generative Pre-Training OpenAI2018 文章地址&#xff1a;https://www.mikecaptain.com/resources/pdf/GPT-1.pdf 摘要 自然语言理解包括各种各样的任务&#xff0c;如文本蕴涵、问题回答、语义相似性评估和文…

[ctfshow web入门] web18

前置知识 js(javascript)语言用于前台控制&#xff0c;不需要知道他的语法是什么&#xff0c;以高级语言的阅读方式也能看懂个大概。 在JavaScript中&#xff0c;confirm()是一个用于显示确认对话框的内置函数&#xff0c;不用知道怎么使用。 信息收集 提示&#xff1a;不要…

`uia.WindowControl` 是什么:获取窗口文字是基于系统的 UI 自动化接口,而非 OCR 方式

uia.WindowControl 是什么:获取窗口文字是基于系统的 UI 自动化接口,而非 OCR 方式 uia.WindowControl 通常是基于 Windows 系统的 UI 自动化框架(如 pywinauto 中的 uia 模块)里用于表示窗口控件的类。在 Windows 操作系统中,每个应用程序的窗口都可以看作是一个控件,ui…

vue3 处理文字 根据文字单独添加class

下面写的是根据后端返回的html 提取我需要的标签和字 将他们单独添加样式 后端返回的数据 大概类似于<h1>2024年“双11”购物节网络零售监测报告</h1><p>表1 “双11” 期间网络零售热销品类TOP10</p> function checkfun(newList){if (newList) {let …

Jupyter Notebook不能自动打开默认浏览器怎么办?

在安装anaconda的过程中,部分用户可能会遇到,打开Jupyter Notebook的时候,不会弹出默认浏览器。本章教程给出解决办法。 一、生成一个jupyter默认配置文件 打开cmd,运行以下命令,会生成一个jupyter_notebook配置文件。 jupyter notebook --generate-config二、编辑jupyter_…