【Unity游戏开发】基于xLua构建一个简单的3D游戏框架
一、xLua简介
xLua是基于Lua语言的开源插件,能够支持在Unity中嵌入Lua脚本(Lua脚本支持热更,适用于游戏的业务逻辑开发和维护)
xLua源码地址
二、构建方法
- 新建一个Unity项目(模板选择Universal 3D(URP))
- 下载xLua源码,将Assets目录及其子目录下的全部文件拷贝到Unity项目的Assets目录下
- 如出现编译错误“error CS0246: The type or namespace name 'MemberInfo' could not be found (are you missing a using directive or an assembly reference?)”,则打开报错的ExampleGenConfig.cs文件,把“using System.Reflection;”的注释去掉
- 创建Lua脚本:在Assets/Resource/Lua目录下(没有则自行创建),创建PlayerController.lua
local PlayerController =
{
speed = 2
}
function PlayerController:Update()
self.direction = CS.UnityEngine.Vector3(0, 0, 0)
if CS.UnityEngine.Input.GetKey(CS.UnityEngine.KeyCode.W) then
self.direction = self.direction + CS.UnityEngine.Vector3(0, 0, 1)
end
if CS.UnityEngine.Input.GetKey(CS.UnityEngine.KeyCode.S) then
self.direction = self.direction + CS.UnityEngine.Vector3(0, 0, -1)
end
if CS.UnityEngine.Input.GetKey(CS.UnityEngine.KeyCode.A) then
self.direction = self.direction + CS.UnityEngine.Vector3(-1, 0, 0)
end
if CS.UnityEngine.Input.GetKey(CS.UnityEngine.KeyCode.D) then
self.direction = self.direction + CS.UnityEngine.Vector3(1, 0, 0)
end
self.gameObject.transform.position = self.gameObject.transform.position + self.direction * self.speed * CS.UnityEngine.Time.deltaTime
end
_G.PlayerController = PlayerController
- 创建LuaImporter:在Assets/Scripts/Editor目录下,创建LuaImporter.cs,使得Unity能够将.lua后缀的文件识别为文本文件
using System.IO;
using UnityEditor;
using UnityEditor.AssetImporters;
using UnityEngine;
using XLuaTest;
[ScriptedImporter(1, ".lua")]
public class LuaImporter : ScriptedImporter
{
public override void OnImportAsset(AssetImportContext ctx)
{
var luaTxt = File.ReadAllText(ctx.assetPath);
var assetsText = new TextAsset(luaTxt);
ctx.AddObjectToAsset("main obj", assetsText);
ctx.SetMainObject(assetsText);
}
}
- 创建并使用Lua虚拟机:在Assets/Scripts目录下,创建LuaManager.cs脚本,作为lua脚本执行的入口
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
public class LuaManager : MonoBehaviour
{
LuaEnv luaEnv;
LuaTable luaTable;
LuaFunction luaFunction;
void Start()
{
// 创建Lua虚拟机
luaEnv = new LuaEnv();
// 指定Lua文件的加载方式
luaEnv.AddLoader(LoadLuaFile);
// 将C#对象存入Lua表中
GameObject player = GameObject.Find("Player");
luaEnv.DoString("require('Lua.PlayerController')");
// 设置PlayerController的gameObject属性,并获取Update函数
luaTable = luaEnv.Global.Get<LuaTable>("PlayerController");
luaTable.Set("gameObject", player);
luaFunction = luaTable.Get<LuaFunction>("Update");
}
void Update()
{
// 执行PlayerController:Update()函数
luaFunction.Call(luaTable);
}
public static byte[] LoadLuaFile(ref string filepath)
{
filepath = $"{filepath.Replace(".", "/")}";
TextAsset file = Resources.Load(filepath) as TextAsset;
return file.bytes;
}
}
- 创建对象,挂载脚本:
打开SampleScene场景,创建三个对象:一个空对象,一个Capsule(将名称修改为Player),一个Plane,在空对象上挂载LuaManager脚本
- 测试:
启动游戏,可通过键盘WASD控制Player移动
三、打包
- 菜单栏选择XLua > Generate Code
- 菜单栏选择File > Build Settings,打开Build Settings面板,上方选择要打包的场景,左侧Platform栏选择目标平台(以Android为例),然后右下角选择Build,选择打包路径,等待打包完成即可
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!