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

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代码中添加如下代码:

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

添加CSharpCallVariable脚本代码:

cs 复制代码
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相关代码如下:

Lua 复制代码
--隐性做了{num=100,rate=99.99,isWoman=false,name="admin"}
num=100
rate=99.99
isWoman=false
name="admin"

运行测试结果如下:

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

相关详细代码如下所示:

cs 复制代码
//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 复制代码
--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代码的结构体

详细代码如下所示:

cs 复制代码
//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 复制代码
--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

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

相关推荐
Humbunklung2 分钟前
Rust枚举:让数据类型告别单调乏味
开发语言·后端·rust
Y1nhl5 分钟前
力扣_链表_python版本
开发语言·python·算法·leetcode·链表·职场和发展
OEC小胖胖18 分钟前
深入理解 Vue.js 响应式原理及其在 Web 前端开发中的应用
开发语言·前端·javascript·vue.js·web
qq_4017004121 分钟前
C语言中位运算以及获取低8位和高8位、高低位合并
c语言·开发语言·算法
小码编匠21 分钟前
WPF 自定义分页控件,可通过样式模板修改外观
后端·c#·.net
yanjiaweiya25 分钟前
云原生-集群管理
java·开发语言·云原生
qianbo_insist1 小时前
c++ python 共享内存
开发语言·c++·python
今天背单词了吗9801 小时前
算法学习笔记:8.Bellman-Ford 算法——从原理到实战,涵盖 LeetCode 与考研 408 例题
java·开发语言·后端·算法·最短路径问题
CoderPractice1 小时前
C#控制台小项目-飞行棋
开发语言·c#·小游戏·飞行棋