Lua调用c#

news2024/9/22 9:33:52

1. 类

在这里插入图片描述

--lua中使用C#的类非常简单
--固定套路
--CS.命名空间.类名
--Unity的类 比如 GameObject Transform等等 —— CS.UnityEngine.类名
--CS.UnityEngine.GameObject

--通过C#中的类 实例化一个对象 lua中没有new 所以我们直接 类名括号就是实例化对象
--默认调用的 相当于就是无参构造
local obj1 = CS.UnityEngine.GameObject()
local obj2 = CS.UnityEngine.GameObject("ABC")

--为了方便使用 并且节约性能 定义全局变量存储 C#中的类
--相当于取了一个别名
GameObject = CS.UnityEngine.GameObject
local obj3 = GameObject("ABC好爱同学们")

--类中的静态对象 可以直接使用.来调用
local obj4 = GameObject.Find("ABC")

--得到对象中的成员变量  直接对象 . 即可
print(obj4.transform.position)
Debug = CS.UnityEngine.Debug
Debug.Log(obj4.transform.position)

Vector3 = CS.UnityEngine.Vector3
--如果使用对象中的 成员方法!!!!一定要加:
obj4.transform:Translate(Vector3.right)
Debug.Log(obj4.transform.position)

--自定义类 使用方法 相同  只是命名空间不同而已
local t = CS.Test()
t:Speak("test说话")

local t2 = CS.MrTang.Test2()
t2:Speak("test2说话")

--继承了Mono的类
--继承了Mono的类 是不能直接new 
local obj5 = GameObject("加脚本测试")
--通过GameObject的 AddComponent添加脚本
--xlua提供了一个重要方法 typeof 可以得到类的Type
--xlua中不支持 无参泛型函数  所以 我们要使用另一个重载
obj5:AddComponent(typeof(CS.LuaCallCSharp))

在这里插入图片描述

--枚举调用 
--调用Unity当中的枚举
--枚举的调用规则 和 类的调用规则是一样的
--CS.命名空间.枚举名.枚举成员
--也支持取别名 
--同样 如果报错 需要在CustomSetting中去加上
PrimitiveType = CS.UnityEngine.PrimitiveType
GameObject = CS.UnityEngine.GameObject

local obj = GameObject.CreatePrimitive(PrimitiveType.Cube)

--自定义枚举 使用方法一样 只是注意命名空间即可
E_MyEnum =  CS.E_MyEnum

local c = E_MyEnum.Idle
print(c)
--枚举转换相关
--数值转枚举
local a = E_MyEnum.__CastFrom(1)
print(a)
--字符串转枚举
local b = E_MyEnum.__CastFrom("Atk")
print(b)

在这里插入图片描述

local obj = CS.Lesson3()

--Lua使用C#数组相关知识
--长度 userdata
--C#怎么用 lua就怎么用 不能使用#去获取长度
print(obj.array.Length)

--访问元素
print(obj.array[0])

--遍历要注意 虽然lua中索引从1开始
--但是数组是C#那边的规则 所以 还是得按C#的来
--注意最大值 一定要减1
for i=0,obj.array.Length-1 do
	print(obj.array[i])
end

--Lua中创建一个C#的数组 Lua中表示数组和List可以用表 
--但是我要使用C#中???
--创建C#中的数组 使用 Array类中的静态方法即可
local array2 = CS.System.Array.CreateInstance(typeof(CS.System.Int32), 10)
print(array2.Length)
print(array2[0])
print(array2[1])
print(array2)

print("*********Lua调用C# list相关知识点***********")
--调用成员方法 用冒号!!!!!!
obj.list:Add(1)
obj.list:Add(2)
obj.list:Add(3)
--长度
print(obj.list.Count)
--遍历
for i=0,obj.list.Count - 1 do
	print(obj.list[i])
end
print(obj.list)

--在Lua中创建一个List对象
--老版本
local list2 = CS.System.Collections.Generic["List`1[System.String]"]()
print(list2)
list2:Add("123")
print(list2[0])

--新版本 >v2.1.12
--相当于得到了一个 List<string> 的一个类别名 需要再实例化
local List_String = CS.System.Collections.Generic.List(CS.System.String)
local list3 = List_String()
list3:Add("5555555")
print(list3[0])

print("*********Lua调用C# dictionary相关知识点***********")
--使用和C#一致
obj.dic:Add(1, "123")
print(obj.dic[1])

--遍历
for k,v in pairs(obj.dic) do
	print(k,v)
end

--在Lua中创建一个字典对象
--相当于得到了一个 Dictionary<string, Vector3> 的一个类别名 需要再实例化
local Dic_String_Vector3 = CS.System.Collections.Generic.Dictionary(CS.System.String, CS.UnityEngine.Vector3)
local dic2 = Dic_String_Vector3()
dic2:Add("123", CS.UnityEngine.Vector3.right)
for i,v in pairs(dic2) do
	print(i,v)
end
--在Lua中创建的字典 直接通过键中括号得 得不到 是nil
print(dic2["123"])
print(dic2:TryGetValue("123"))
--如果要通过键获取值 要通过这个固定方法
print(dic2:get_Item("123"))
dic2:set_Item("123", nil)
print(dic2:get_Item("123"))

local Dic_String_String = CS.System.Collections.Generic.Dictionary(CS.System.String, CS.System.String)
local dic2 = Dic_String_String()
dic2:Add("id_1", "hello")
print(dic2:get_Item("id_1"))


for key, value in pairs(dic2) do
    print(key, value)
end

在这里插入图片描述

//想要在Lua中使用拓展方法 一定要在工具类前面加上特定
//建议 Lua中要使用的类 都加上该特性 可以提升性能
//如果不加该特性 除了拓展方法对应的类 其它类的使用 都不会报错
//但是lua是通过反射的机制去调用的C#类  效率较低
[LuaCallCSharp]
public static class Tools
{
    //Lesson4的拓展方法
    public static void Move(this Lesson4 obj)
    {
        Debug.Log(obj.name + "移动");
    }
}

public class Lesson4
{
    public string name = "EFT";

    public void Speak(string str)
    {
        Debug.Log(str);
    }

    public static void Eat()
    {
        Debug.Log("吃东西");
    }
}
Lesson4 = CS.Lesson4
--使用静态方法
--CS.命名空间.类名.静态方法名()
Lesson4.Eat()

--成员方法 实例化出来用
local obj = Lesson4()
--成员方法 一定用冒号
obj:Speak("CCC哈哈哈哈哈")

--使用拓展方法 和使用成员方法 一致
--要调用 C#中某个类的拓展方法 那一定要在拓展方法的静态类前面加上LuaCallCSharp特性
obj:Move()

在这里插入图片描述

Lesson5 = CS.Lesson5

local obj = Lesson5()

--ref参数 会以多返回值的形式返回给lua
--如果函数存在返回值 那么第一个值 就是该返回值
--之后的返回值 就是ref的结果 从左到右一一对应
--ref参数 需要传入一个默认值 占位置
--a 相当于 函数返回值
--b 第一个ref
--c 第二个ref
local a,b,c = obj:RefFun(1, 0, 0, 1)
print(a)
print(b)
print(c)
print("*********Lua调用C# out方法相关知识点***********")
--out参数 会以多返回值的形式返回给lua
--如果函数存在返回值 那么第一个值 就是该返回值
--之后的返回值 就是out的结果 从左到右一一对应
--out参数 不需要传占位置的值
local a,b,c = obj:OutFun(20,30)
print(a)
print(b)
print(c)


--混合使用时  综合上面的规则
--ref需占位 out不用传
--第一个是函数的返回值  之后 从左到右依次对应ref或者out
local a,b,c = obj:RefOutFun(20,1)
print(a)--300
print(b)--200
print(c)--400

在这里插入图片描述

local obj = CS.Lesson6()

--虽然Lua自己不支持写重载函数
--但是Lua支持调用C#中的重载函数  
print(obj:Calc())
print(obj:Calc(15, 1))

--Lua虽然支持调用C#重载函数
--但是因为Lua中的数值类型 只有Number
--对C#中多精度的重载函数支持不好 傻傻分不清
--在使用时 可能出现意想不到的问题
print(obj:Calc(10))
print(obj:Calc(10.2))


--解决重载函数含糊的问题
--xlua提供了解决方案 反射机制 
--这种方法只做了解 尽量别用
--Type是反射的关键类
--得到指定函数的相关信息
local m1 = typeof(CS.Lesson6):GetMethod("Calc", {typeof(CS.System.Int32)})
local m2 = typeof(CS.Lesson6):GetMethod("Calc", {typeof(CS.System.Single)})

--通过xlua提供的一个方法 把它转成lua函数来使用
--一般我们转一次 然后重复使用
local f1 = xlua.tofunction(m1)
local f2 = xlua.tofunction(m2)
--成员方法 第一个参数传对象
--静态方法 不用传对象
print(f1(obj, 10))
print(f2(obj, 10.2))

在这里插入图片描述

local obj = CS.Lesson7()

--委托是用来装函数的
--使用C#中的委托 就是用来装lua函数的
local fun = function( )
	print("Lua函数Fun")
end

--Lua中没有复合运算符 不能+=
--如果第一次往委托中加函数 因为是nil 不能直接+
--所以第一次 要先等=
print("*********开始加函数***********")
obj.del = fun
--obj.del = obj.del + fun
obj.del = obj.del + fun
--不建议这样写 最好最好还是 先声明函数再加
obj.del = obj.del + function( )
	print("临时申明的函数")
end
--委托执行
obj.del()
print("*********开始减函数***********")
obj.del = obj.del - fun
obj.del = obj.del - fun
--委托执行
obj.del()
print("*********清空***********")
--清空所有存储的函数
obj.del = nil
--清空过后得先等
obj.del = fun
--调用
obj.del()

print("*********Lua调用C# 事件相关知识点***********")
local fun2 = function()
	print("事件加的函数")
end
print("*********事件加函数***********")
--事件加减函数  和 委托非常不一样
--lua中使用C#事件 加函数 
--有点类似使用成员方 冒号事件名("+", 函数变量)
obj:eventAction("+", fun2)
--最好最好不要这样写
obj:eventAction("+", function()
	print("事件加的匿名函数")
end)

obj:DoEvent()
print("*********事件减函数***********")
obj:eventAction("-", fun2)
obj:DoEvent()

print("*********事件清楚***********")
--清事件 不能直接设空
obj:ClaerEvent()
obj:DoEvent()
#region 委托和事件

public class Lesson7
{
    //申明委托和事件 
    public UnityAction del;

    public event UnityAction eventAction;

    public void DoEvent()
    {
        if (eventAction != null)
            eventAction();
    }

    public void ClaerEvent()
    {
        eventAction = null;
    }
}

#endregion

在这里插入图片描述

local obj = CS.Lesson8()

--获取长度
print("行:" .. obj.array:GetLength(0))
print("列:" .. obj.array:GetLength(1))

--获取元素
--不能通过[0,0]或者[0][0]访问元素 会报错
print(obj.array:GetValue(0,0))
print(obj.array:GetValue(1,0))
print("********************")
for i=0,obj.array:GetLength(0)-1 do
	for j=0,obj.array:GetLength(1)-1 do
		print(obj.array:GetValue(i,j))
	end
end

obj:SetValue(obj.array, 99, 0, 0)
print(obj.array:GetValue(0,0))


local m = typeof(CS.System.Array):GetMethod("SetValue", {typeof(CS.System.Int32), typeof(CS.System.Int32), typeof(CS.System.Int32)})
print(m);
local ff = xlua.tofunction(m)
print(ff);
ff(obj.array, 1,0,0)
--print(obj.array:GetValue(0,0))

在这里插入图片描述

--往场景对象上添加一个脚本 如果存在就不加 如果不存在再加
GameObject = CS.UnityEngine.GameObject
Debug = CS.UnityEngine.Debug
Rigidbody = CS.UnityEngine.Rigidbody
Image = CS.UnityEngine.UI.Image

local obj = GameObject("测试加脚本")
--得到身上的刚体组件  如果没有 就加 有就不管
local rig = obj:GetComponent(typeof(Rigidbody))
print(rig)
Debug.Log(rig)
if rig == nil then
	print(true)
end

local img = obj:GetComponent(typeof(Image))
print(img)
Debug.Log(img)
--判断空
--nil和null 没法进行==比较
--第一种方法
--if rig:Equals(nil) then
--if IsNull(rig) then
if rig:IsNull() then
	print("123")
	rig = obj:AddComponent(typeof(Rigidbody))
end
print(rig)

在这里插入图片描述

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

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

print("*********Lua调用C# 协程相关知识点***********")
--xlua提供的一个工具表
--一定是要通过require调用之后 才能用
util = require("xlua.util")
--C#中协程启动都是通过继承了Mono的类 通过里面的启动函数StartCoroutine

GameObject = CS.UnityEngine.GameObject
WaitForSeconds = CS.UnityEngine.WaitForSeconds
--在场景中新建一个空物体  然后挂一个脚本上去 脚本继承mono使用它来开启协程
local obj = GameObject("Coroutine")
local mono = obj:AddComponent(typeof(CS.LuaCallCSharp))

--希望用来被开启的协程函数 
fun = function()
	local a = 1
	while true do
		--lua中 不能直接使用 C#中的 yield return 
		--就使用lua中的协程返回
		coroutine.yield(WaitForSeconds(1))
		print(a)
		a = a + 1
		if a > 10 then
			--停止协程和C#当中一样
			mono:StopCoroutine(b)
		end
	end
end
--我们不能直接将 lua函数传入到开启协程中!!!!!
--如果要把lua函数当做协程函数传入
--必须 先调用 xlua.util中的cs_generator(lua函数)
b = mono:StartCoroutine(util.cs_generator(fun))

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

local obj = CS.Lesson12()

local child = CS.Lesson12.TestChild()
local father = CS.Lesson12.TestFather()

--支持有约束有参数的泛型函数
obj:TestFun1(child, father)
obj:TestFun1(father, child)

--lua中不支持 没有约束的泛型函数
--obj:TestFun2(child)

--lua中不支持 有约束 但是没有参数的泛型函数
--obj:TestFun3()

--lua中不支持 非class的约束
--obj:TestFun4(child)


--有一定的使用限制
--Mono打包 这种方式支持使用
--il2cpp打包  如果泛型参数是引用类型才可以使用
--il2cpp打包  如果泛型参数是值类型,除非C#那边已经调用过了 同类型的泛型参数 lua中才能够被使用

--补充知识 让上面 不支持使用的泛型函数 变得能用
--得到通用函数  
--设置泛型类型再使用
--xlua.get_generic_method(类, "函数名")
local testFun2 = xlua.get_generic_method(CS.Lesson12, "TestFun2")
local testFun2_R = testFun2(CS.System.Int32)
--调用
--成员方法  第一个参数 传调用函数的对象
--静态方法 不用传
testFun2_R(obj, 1)

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

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

相关文章

【MySQL进阶】事务、存储引擎、索引、锁

一、事务 1.概念 事务是一组操作的集合&#xff0c;它是一个不可分割的工作单位&#xff0c;事务会把所有的操作作为一个整体一起向 系统提交或撤销操作请求&#xff0c;即这些操作要么同时成功&#xff0c;要么同时失败。 例子&#xff1a;转账&#xff0c;要求扣钱和进账…

从0开始搭建vue + flask 旅游景点数据分析系统(九):旅游景点管理之增删改查

这一期来做旅游景点数据的增删改查 先看下我们做好的效果是这样的&#xff1a; ## 1 后台接口 这里的接口已经考虑到了分页的情况&#xff0c;因为前端的表格是带有分页的&#xff0c;接受的前端传过来的get参数为 title 、page、 limit &#xff0c;titie是查询的关键词&…

C#学习笔记15:上位机助手_usercontrol窗体内嵌的应用

今日完善一下之前的上位机助手&#xff0c;做一个组合窗体内嵌的多功能助手软件应用, 与之前的上位机软件相比: 更注重控件能够随着窗体缩放而缩放变换&#xff0c;串口助手部分能自动后台检测串口设备&#xff0c;解决市面上大部分串口助手的打开初始化会卡顿的问题 ( 多线程后…

Android全面解析之context机制(三): 从源码角度分析context创建流程(下)

前言 前面已经讲了什么是context以及从源码角度分析context创建流程&#xff08;上&#xff09;。限于篇幅把四大组件中的广播和内容提供器的context获取流程放在了这篇文章。广播和内容提供器并不是context家族里的一员&#xff0c;所以他们本身并不是context&#xff0c;因而…

Spring日志

1.日志的作用 定位和发现问题(主要)系统监控数据采集日志审计...... 2.日志的使用 2.1 ⽇志格式的说明 2.2 打印日志 Spring集成了日志框架,直接使用即可 步骤: 1.定义日志对象 2.使⽤⽇志对象打印⽇志 RestController public class LoggerController {private static Logger…

Ecovadis认证评估什么 Ecovadis认证有哪些注意事

Ecovadis认证是一个全球性的企业可持续性评估平台&#xff0c;它通过评估企业在环境、劳工与人权、公平商业实践、可持续采购等四个领域的表现&#xff0c;帮助企业识别潜在风险&#xff0c;提升ESG(环境、社会和公司治理)绩效&#xff0c;实现可持续发展 Ecovadis认证注意事项…

Linux-文件系统与日志分析

系列文章目录 提示&#xff1a;仅用于个人学习&#xff0c;进行查漏补缺使用。 1.Linux介绍、目录结构、文件基本属性、Shell 2.Linux常用命令 3.Linux文件管理 4.Linux 命令安装(rpm、install) 5.Linux账号管理 6.Linux文件/目录权限管理 7.Linux磁盘管理/文件系统 8.Linu…

MapReduce 简单介绍

MapReduce 一、MapReduce概述二、MapReduce 基本设计思想分而治之2.2 抽象成模型2.3 上升到框架 三、MapReduce 优缺点3.1 MapReduce 的优点3.1 MapReduce 的缺点 四、MapReduce 编程模型4.1 MapReduce 分布式计算原理4.2 MapReduce 编程模型4.3 剖析 MapReduce 编程模型4.3.1 …

好书推荐!《Building LLM Apps》构建大语言模型LLM应用!一次性讲清楚!

《Building LLM Apps》这本书是一份全面而实用的指南&#xff0c;它不仅介绍了大型语言模型&#xff08;LLM&#xff09;的基础知识和前沿技术&#xff0c;还深入探讨了如何将这些模型应用到实际的AI应用中。 书中从对LLM的深入介绍入手&#xff0c;接着探讨了包括GPT 3.5、GP…

RxJava在Android中的应用

RxJava是一个基于事件流、异步和响应式编程的库&#xff0c;它在Android开发中广泛用于简化异步操作和事件处理。通过RxJava&#xff0c;我们可以以声明式方式管理异步任务&#xff0c;并有效整合多个数据源。 1. RxJava核心组件介绍 1.1 Observable与Observer Observable&a…

大模型面试系列-大模型算法工程师的面试题目与解答技巧详细说明

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下大模型面试系列-大模型算法工程师的面试题目与解答技巧详细说明。 文章目录 大模型算法工程师面试题1. Llama 2 中使用的注意力机制是什么&#xff1f;描述一下查询分组注意力。2. LangChain 的结构详细描述一下。…

2024年8月15日嵌入式学习

今日主要学习线程和线程的互斥锁 pthread_cancel函数 它用于取消一个线程&#xff0c;当一个线程收到取消的申请时&#xff0c;他不会立即停止&#xff0c;而是在下一个取消点处结束运行&#xff0c;取消点是程序中一个特定的位置。如果线程在执行一个不可中断的系统调用&…

网络安全风险扫描原理及工具使用

课程目标 1.熟悉常见网络安全风险扫描工具 2.了解网络安全风险扫描原理 3.掌握扫描工具使用方法 为什么要做网络安全风险扫描&#xff1f; 什么是网络安全风险扫描&#xff1f; 通过一定的技术手段发现系统和软件存在的安全漏洞、弱口令 网络安全风险扫描的目的&#xff1…

【AI 绘画】web_ui 搭建(基于gradio)

AI 绘画- web_ui 搭建(基于gradio) 1. 内容介绍 Gradio的优势在于易用性,代码结构相比Streamlit简单,只需简单定义输入和输出接口即可快速构建简单的交互页面,更轻松部署模型。适合场景相对简单,想要快速部署应用的开发者。便于分享:gradio可以在启动应用时设置share=…

QT文件操作实战

QT文件操作实战 页面布局如下 读取文件:文件→界面文本框 采用“浏览”按钮的槽函数,编写的代码如下 void Widget::on_pushButton_clicked() {//读取txt文件,获取要打开的文件名,并将文件名(包含)填入lineEdit中// QString fileName = QFileDialog::getOpenFileName(th…

云HIS平台源码,云医院管理信息系统源码,云HIS医疗卫生管理系统源码

云医院管理信息系统源码&#xff0c;云HIS医疗卫生管理系统源码&#xff0c;医疗云HIS系统源码&#xff0c;自主版权二级医院应用案例 云HIS平台采用SaaS服务模式&#xff0c;软件使用者无需购置额外硬件设备、软件许可证及安装和维护软件系统&#xff0c;通过互联网浏览器在任…

YS9082HP量产工具,支持N38B开卡(ID:89D3AC32C204),解决YS9082HP N38B开卡到87%报错,状态8817,Fail:写表失败

收的固态硬盘&#xff0c;主控是YS9082HP&#xff0c;颗粒是Intel的N38B&#xff1a; 从网上找了个YS9082HP_MPToolV8.00.00.01.025_HPS2704M_release_N38B版本试试&#xff0c;倒是能识别颗粒&#xff0c;到87%就报错&#xff0c;Fail:写表失败&#xff0c;错误状态是8817&…

山东易注册网络科技有限公司:合伙人模式的机遇与创新

在互联网高速发展的今天&#xff0c;合伙人模式成为网络运营的新趋势。山东易注册网络科技有限公司以其创新的合伙人模式&#xff0c;为用户带来了前所未有的机遇。 加入山东易注册的合伙人&#xff0c;可以享受到独立搭建系统和独立服务器的权益。用户可以打造自己的独立域名和…

怎样用python函数画图像

打开Python的shell界面&#xff0c;如图所示。&#xff08;注意我们需要已经安装了matplotlib库包&#xff09;。 输入以下代码&#xff0c;导入我们用到的函数库。 >>> import numpy as np >>> import matplotlib.pyplot as plt 产生我们要画的的函数的数据…

数据集的简单制作和使用

数据集的简单制作和使用 参考资料&#xff1a;Labelme分割标注软件使用 使用labelme软件对数据集进行分割 每张图片获得一个json文件 我们看看其中一个文件&#xff0c;内容包含每个点在图片中的位置 我们可以自己写一个脚本&#xff08;或使用别人的&#xff09;将上述json…