【UE Lua】 快速入门(基础语法、与UE引擎的交互)

news2024/11/14 19:25:03

目录

  • 0 引言
  • 1 基础语法
    • 1.1 变量和数据类型
    • 1.2 注释
    • 1.3 控制结构
    • 1.4 函数
    • 1.5 表(Table)
    • 1.6 元表(Metatable)
    • 1.7 字符串操作
    • 1.8 模块和包
    • 1.9 错误处理
  • 2 数据结构 - 表
    • 2.1 表(Table)
    • 2.2 元表(Metatable)
    • 2.3 `__index` 元方法
      • 2.3.1 `__index` 作为表
      • 2.3.2 `__index` 作为函数
    • 2.4 表和元表的区别
  • 3 面向对象范式
  • 4 Lua与UE引擎的交互
    • 4.1 使用第三方插件 UnLua
    • 4.2 使用 LuaBridge
    • 4.3 使用 Unreal Engine Lua Plugin
    • 4.4 底层实现原理
      • 4.4.1 嵌入 Lua 解释器
      • 4.4.2 绑定 C++ 和 Lua
      • 4.4.3 脚本加载和执行
      • 4.4.4 事件和回调机制
      • 4.4.5 总结

请添加图片描述

  • 🙋‍♂️ 作者:海码007
  • 📜 专栏:UE虚幻引擎专栏
  • 💥 标题:【UE Lua】 快速入门
  • ❣️ 寄语:书到用时方恨少,事非经过不知难!
  • 🎈 最后:文章作者技术和水平有限,如果文中出现错误,希望大家能指正,同时有问题的话,欢迎大家留言讨论。

0 引言

1 基础语法

Lua 是一种轻量级的脚本语言,语法简洁且易于学习。以下是 Lua 脚本的基础语法,包括变量、数据类型、控制结构、函数、表、元表等。

1.1 变量和数据类型

Lua 是动态类型语言,变量不需要声明类型。

-- 变量
local a = 10        -- 整数
local b = 3.14      -- 浮点数
local c = "Hello"   -- 字符串
local d = true      -- 布尔值
local e = nil       -- 空值

1.2 注释

Lua 支持单行注释和多行注释。

-- 单行注释

--[[
多行注释
可以跨越多行
]]

1.3 控制结构

条件语句

local x = 10

if x > 0 then
    print("x is positive")
elseif x < 0 then
    print("x is negative")
else
    print("x is zero")
end

循环语句

-- while 循环
local i = 1
while i <= 5 do
    print(i)
    i = i + 1
end

-- for 循环
for i = 1, 5 do
    print(i)
end

-- 泛型 for 循环
local t = {10, 20, 30}
for index, value in ipairs(t) do
    print(index, value)
end

1.4 函数

-- 定义函数
function add(a, b)
    return a + b
end

-- 调用函数
local result = add(3, 4)
print(result)  -- 输出 7

-- 匿名函数
local multiply = function(a, b)
    return a * b
end

print(multiply(3, 4))  -- 输出 12

1.5 表(Table)

表是 Lua 中唯一的数据结构,可以用来表示数组、字典、集合、对象等。

-- 创建一个空表
local t = {}

-- 数组
local array = {1, 2, 3, 4, 5}
print(array[1])  -- 输出 1

-- 字典
local dict = {name = "Alice", age = 30}
print(dict["name"])  -- 输出 "Alice"
print(dict.age)      -- 输出 30

-- 嵌套表
local nested = {a = {b = {c = 10}}}
print(nested.a.b.c)  -- 输出 10

1.6 元表(Metatable)

元表用于改变表的行为,可以定义一些特殊的操作,如算术运算、比较运算、表访问等。

-- 创建一个表
local myTable = {name = "Alice"}

-- 创建一个元表
local myMetatable = {
    __index = {age = 30}
}

-- 设置元表
setmetatable(myTable, myMetatable)

-- 访问表中的值
print(myTable.name)  -- 输出 "Alice"
print(myTable.age)   -- 输出 30  (从元表中获取)

1.7 字符串操作

Lua 提供了一些常用的字符串操作函数。

local str = "Hello, World!"

-- 获取字符串长度
print(#str)  -- 输出 13

-- 字符串连接
local str2 = str .. " Lua"
print(str2)  -- 输出 "Hello, World! Lua"

-- 字符串查找
local start, finish = string.find(str, "World")
print(start, finish)  -- 输出 8 12

-- 字符串替换
local newStr = string.gsub(str, "World", "Lua")
print(newStr)  -- 输出 "Hello, Lua!"

1.8 模块和包

Lua 支持模块和包,可以通过 require 函数加载模块。

-- mymodule.lua
local mymodule = {}

function mymodule.greet(name)
    print("Hello, " .. name)
end

return mymodule

-- main.lua
local mymodule = require("mymodule")
mymodule.greet("World")  -- 输出 "Hello, World"

1.9 错误处理

Lua 提供了 pcallxpcall 函数用于错误处理。

-- 使用 pcall 进行错误处理
local status, err = pcall(function()
    error("An error occurred")
end)

if not status then
    print("Error: " .. err)
end

2 数据结构 - 表

在 Lua 中,表(table)是最重要的数据结构,而元表(metatable)则是用于改变表行为的机制。以下是对表和元表的详细解释,以及 __index 元方法的作用。

2.1 表(Table)

表是 Lua 中唯一的数据结构,可以用来表示数组、字典、集合、对象等。表是动态的,可以根据需要添加或删除键值对。

-- 创建一个空表
local myTable = {}

-- 添加键值对
myTable["name"] = "Alice"
myTable["age"] = 30

-- 访问表中的值
print(myTable["name"])  -- 输出 "Alice"
print(myTable["age"])   -- 输出 30

2.2 元表(Metatable)

元表是一个特殊的表,可以用来改变另一个表的行为。通过设置元表,可以定义一些特殊的操作,如算术运算、比较运算、表访问等。

-- 创建一个表
local myTable = {}

-- 创建一个元表
local myMetatable = {}

-- 设置元表
setmetatable(myTable, myMetatable)

2.3 __index 元方法

__index 是元表中的一个特殊字段,用于处理对表中不存在的键的访问。当访问一个表中不存在的键时,Lua 会查找该表的元表中的 __index 元方法。如果 __index 是一个表,Lua 会在这个表中查找键;如果 __index 是一个函数,Lua 会调用这个函数。

2.3.1 __index 作为表

-- 创建一个表
local myTable = {name = "Alice"}

-- 创建一个元表
local myMetatable = {
    __index = {age = 30}
}

-- 设置元表
setmetatable(myTable, myMetatable)

-- 访问表中的值
print(myTable.name)  -- 输出 "Alice"
print(myTable.age)   -- 输出 30  (从元表中获取)

2.3.2 __index 作为函数

-- 创建一个表
local myTable = {name = "Alice"}

-- 创建一个元表
local myMetatable = {
    __index = function(table, key)
        if key == "age" then
            return 30
        else
            return nil
        end
    end
}

-- 设置元表
setmetatable(myTable, myMetatable)

-- 访问表中的值
print(myTable.name)  -- 输出 "Alice"
print(myTable.age)   -- 输出 30  (通过函数获取)

2.4 表和元表的区别

  1. 表(Table)

    • 表是 Lua 中的基本数据结构,用于存储键值对。
    • 表可以用来表示数组、字典、集合、对象等。
    • 表是动态的,可以根据需要添加或删除键值对。
  2. 元表(Metatable)

    • 元表是一个特殊的表,用于改变另一个表的行为。
    • 元表可以包含一些特殊的字段(如 __index__newindex__add 等),用于定义表的特殊操作。
    • 元表通过 setmetatable 函数设置,getmetatable 函数获取。
  • 表(Table) 是 Lua 中的基本数据结构,用于存储键值对。
  • 元表(Metatable) 是一个特殊的表,用于改变另一个表的行为。
  • __index 元方法用于处理对表中不存在的键的访问,可以是一个表或一个函数。

通过使用元表和 __index 元方法,可以实现更灵活和强大的表操作,满足各种编程需求。

3 面向对象范式

虽然 Lua 本身没有内置的面向对象编程支持,但可以通过元表(metatables)和表(tables)来实现面向对象编程。

-- 定义一个类
Person = {}
Person.__index = Person

-- 构造函数
function Person:new(name, age)
    local self = setmetatable({}, Person)
    self.name = name
    self.age = age
    return self
end

-- 方法
function Person:greet()
    print("Hello, my name is " .. self.name .. " and I am " .. self.age .. " years old.")
end

-- 创建对象
local person = Person:new("Alice", 30)
person:greet()

4 Lua与UE引擎的交互

Lua 与 Unreal Engine(UE)交互通常通过第三方插件或绑定库来实现。这些插件和库提供了在 UE 中嵌入 Lua 脚本的能力,使得开发者可以使用 Lua 编写游戏逻辑、控制游戏对象等。以下是一些常见的方法和工具:

4.1 使用第三方插件 UnLua

UnLua 是一个专门为 Unreal Engine 设计的 Lua 插件,提供了深度集成和高性能。以下是使用 UnLua 的基本步骤:

  1. 安装 UnLua

    • 下载并安装 UnLua 插件。
    • 将插件添加到你的 UE 项目中。
  2. 配置 UnLua

    • 在项目设置中启用 UnLua 插件。
    • 配置 Lua 脚本路径等参数。
  3. 编写 Lua 脚本

    • 创建 Lua 脚本文件,例如 MyScript.lua

    • 编写游戏逻辑,例如:

      print("Hello from UnLua!")
      
      function OnBeginPlay()
          print("Game started")
      end
      
  4. 在 UE 中调用 Lua 脚本

    • 在 UE 蓝图或 C++ 代码中加载并执行 Lua 脚本。

      // 在 C++ 代码中加载 Lua 脚本
      UUnLuaManager* UnLuaManager = UUnLuaManager::Get();
      UnLuaManager->RunFile("MyScript.lua");
      
      // 调用 Lua 函数
      UnLuaManager->CallFunction("OnBeginPlay");
      

4.2 使用 LuaBridge

LuaBridge 是一个轻量级的 C++ 库,用于将 Lua 嵌入到 C++ 应用程序中。以下是使用 LuaBridge 与 UE 交互的基本步骤:

  1. 安装 LuaBridge

    • 下载并集成 LuaBridge 到你的 UE 项目中。
  2. 编写 C++ 代码

    • 在 UE 项目中编写 C++ 代码,加载并执行 Lua 脚本。

      #include "LuaBridge/LuaBridge.h"
      #include "lua.hpp"
      
      void RunLuaScript()
      {
          lua_State* L = luaL_newstate();
          luaL_openlibs(L);
      
          // 加载并执行 Lua 脚本
          if (luaL_dofile(L, "MyScript.lua") != LUA_OK)
          {
              const char* error = lua_tostring(L, -1);
              UE_LOG(LogTemp, Error, TEXT("Error: %s"), UTF8_TO_TCHAR(error));
          }
      
          // 调用 Lua 函数
          lua_getglobal(L, "OnBeginPlay");
          if (lua_pcall(L, 0, 0, 0) != LUA_OK)
          {
              const char* error = lua_tostring(L, -1);
              UE_LOG(LogTemp, Error, TEXT("Error: %s"), UTF8_TO_TCHAR(error));
          }
      
          lua_close(L);
      }
      

4.3 使用 Unreal Engine Lua Plugin

Unreal Engine Lua Plugin 是一个流行的插件,允许在 UE 中嵌入 Lua 脚本。以下是使用该插件的一些基本步骤:

  1. 安装插件

    • 下载并安装 Unreal Engine Lua Plugin。
    • 将插件添加到你的 UE 项目中。
  2. 配置插件

    • 在项目设置中启用 Lua 插件。
    • 配置 Lua 脚本路径等参数。
  3. 编写 Lua 脚本

    • 创建 Lua 脚本文件,例如 MyScript.lua

    • 编写游戏逻辑,例如:

      print("Hello from Lua!")
      
      function OnBeginPlay()
          print("Game started")
      end
      
  4. 在 UE 中调用 Lua 脚本

    • 在 UE 蓝图或 C++ 代码中加载并执行 Lua 脚本。

      // 在 C++ 代码中加载 Lua 脚本
      ULuaState* LuaState = NewObject<ULuaState>();
      LuaState->DoFile("MyScript.lua");
      
      // 调用 Lua 函数
      LuaState->GetFunction("OnBeginPlay");
      LuaState->Call(0, 0);
      

4.4 底层实现原理

Lua 与 Unreal Engine(UE)交互的底层实现原理主要涉及以下几个方面:

  1. 嵌入 Lua 解释器

    • 在 UE 中嵌入 Lua 解释器,使得 Lua 脚本可以在 UE 的运行时环境中执行。
    • 这通常通过在 C++ 代码中包含 Lua 解释器库(如 lua.hpp)并初始化 Lua 解释器来实现。
  2. 绑定 C++ 和 Lua

    • 通过绑定机制,将 UE 的 C++ 类和函数暴露给 Lua,使得 Lua 脚本可以调用这些 C++ 函数。
    • 绑定机制可以手动实现,也可以使用自动化工具或库(如 LuaBridge、Sol2、UnLua 等)来简化绑定过程。
  3. 脚本加载和执行

    • 提供加载和执行 Lua 脚本的功能,使得 Lua 脚本可以在特定的事件或条件下执行。
    • 这通常通过在 C++ 代码中调用 Lua 解释器的 API 来实现,例如 luaL_dofile 用于加载和执行 Lua 脚本。
  4. 事件和回调机制

    • 实现事件和回调机制,使得 Lua 脚本可以响应 UE 中的事件(如游戏开始、对象碰撞等)。
    • 这通常通过在 C++ 代码中注册 Lua 函数作为回调函数,并在特定事件发生时调用这些回调函数来实现。

以下是一些具体的实现细节,展示了如何在 C++ 代码中嵌入 Lua 解释器并实现与 Lua 的交互。


4.4.1 嵌入 Lua 解释器

首先,需要在 C++ 代码中包含 Lua 解释器库并初始化 Lua 解释器:

#include "lua.hpp"

lua_State* L = luaL_newstate();  // 创建一个新的 Lua 状态
luaL_openlibs(L);  // 打开 Lua 标准库

4.4.2 绑定 C++ 和 Lua

可以使用 LuaBridge 或其他绑定库来简化绑定过程。以下是使用 LuaBridge 的示例:

#include "LuaBridge/LuaBridge.h"

void HelloWorld()
{
    UE_LOG(LogTemp, Log, TEXT("Hello from C++"));
}

void BindFunctions(lua_State* L)
{
    luabridge::getGlobalNamespace(L)
        .addFunction("HelloWorld", HelloWorld);
}

在 Lua 脚本中,可以调用绑定的 C++ 函数:

HelloWorld()  -- 调用 C++ 函数

4.4.3 脚本加载和执行

可以在 C++ 代码中加载和执行 Lua 脚本:

if (luaL_dofile(L, "MyScript.lua") != LUA_OK)
{
    const char* error = lua_tostring(L, -1);
    UE_LOG(LogTemp, Error, TEXT("Error: %s"), UTF8_TO_TCHAR(error));
}

4.4.4 事件和回调机制

可以在 C++ 代码中注册 Lua 函数作为回调函数,并在特定事件发生时调用这些回调函数:

// 注册 Lua 回调函数
lua_getglobal(L, "OnBeginPlay");
if (lua_isfunction(L, -1))
{
    lua_pcall(L, 0, 0, 0);
}

在 Lua 脚本中定义回调函数:

function OnBeginPlay()
    print("Game started")
end

4.4.5 总结

Lua 与 Unreal Engine 交互的底层实现原理主要涉及嵌入 Lua 解释器、绑定 C++ 和 Lua、加载和执行 Lua 脚本以及实现事件和回调机制。通过这些机制,可以在 UE 中嵌入 Lua 脚本,实现灵活的游戏逻辑编写和控制。使用第三方插件和库(如 UnLua、LuaBridge 等)可以简化这些过程,使得开发者更容易实现 Lua 与 UE 的交互。

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

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

相关文章

ElasticSearch学习篇14_《检索技术核心20讲》进阶篇之大倒排索引

背景 学习极客实践课程《检索技术核心20讲》https://time.geekbang.org/column/article/215243&#xff0c;文档形式记录笔记。 内容 主要是海量数据的大倒排索引的一些原理设计思想&#xff0c;ES底层就是基于这些设计思想以及原理&#xff0c;主要涉及读写分离、索引分层等…

【DFS(深度优先搜索)详解】看这一篇就够啦

【DFS详解】看这一篇就够啦 &#x1f343;1. 算法思想&#x1f343;2. 三种枚举方式&#x1f343;2.1 指数型枚举&#x1f343;2.2 排列型枚举&#x1f343;2.3 组合型枚举 &#x1f343;3. 剪枝优化&#x1f343;4. 图的搜索&#x1f343;5. 来几道题试试手&#x1f343;5.1 选…

淘宝扭蛋机小程序搭建全攻略

一、引言 在数字化时代&#xff0c;线上娱乐方式层出不穷&#xff0c;其中扭蛋机小程序以其独特的互动性和趣味性&#xff0c;受到了广大用户的喜爱。淘宝扭蛋机小程序作为其中的佼佼者&#xff0c;不仅为用户提供了丰富的奖品选择&#xff0c;还通过创新的玩法和营销策略&…

【计算机毕业设计】018基于weixin小程序实习记录

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

Scrapy crawl spider 停止工作

Scrapy是一个用于爬取网站数据的流行框架&#xff0c;有时爬虫可能会停止工作&#xff0c;这通常是由多种原因引起的。以下是一些常见问题及其解决方法&#xff1a; 1、问题背景 用户在使用 Scrapy 0.16.2 版本进行网络爬取时遇到问题&#xff0c;具体表现为爬虫在运行一段时间…

OV SSL证书—防止钓鱼攻击的最佳证书

据Menlo Security日前发布的《2023年浏览器安全状况报告》&#xff0c;针对浏览器的高度规避自适应威胁&#xff08;HEAT&#xff09;呈现激增的发展趋势。 钓鱼攻击概率激增&#xff1a; 安全研究人员发现&#xff0c;与上半年相比&#xff0c;2023年下半年基于浏览器的网络…

大野耐一是如何为丰田铸就精益生产的?

在制造业的漫长历史中&#xff0c;无数的革新者和企业家为追求更高效、更精益的生产方式而不懈努力。其中&#xff0c;大野耐一的名字无疑是这段历史中最为耀眼的星辰之一。他&#xff0c;以其卓越的才智和坚韧的毅力&#xff0c;为丰田汽车公司铸就了一套享誉全球的精益生产体…

windows上部署python3.11

hello&#xff0c;大家好&#xff0c;我是一名测试开发工程师&#xff0c;至今已在自动化测试领域深耕9个年头&#xff0c;现已将本人实战多年的多终端自动化测试框架【wyTest】开源啦&#xff0c;在接下来的一个月里&#xff0c;我将免费指导大家使用wyTest&#xff0c;请大家…

软件安全性测试的工具有哪些?

软件安全性测试是确保软件系统在设计和实施过程中能够保护系统的机密性、完整性和可用性。为了进行软件安全性测试&#xff0c;有许多工具可供选择&#xff0c;这些工具可以帮助测试人员发现潜在的安全漏洞和弱点&#xff0c;从而提高软件系统的安全性。 以下是一些常用的软件安…

游戏提示找不到steam_api64.dll无法继续执行代码的处理方法

相信很多人在玩游戏时候打开游戏时候&#xff0c;经常会遇到各式各样的小问题&#xff0c;比如steam_api64.dll丢失或许找不到steam_api64.dll无法打开游戏就是其中常见问题之一&#xff0c;那么遇到steam_api64.dll丢失问题要如何解决呢&#xff1f;今天我就给大家详细分析一下…

无人直播怎么玩,一文带你了解AI小姐姐自动换装玩法

最近经常有小伙伴问我 就是像这种&#xff0c;一刷礼物&#xff0c;小姐姐就换装的视频到底该怎么做 今天就来教大家 如何来制作这种直播视频 第一步&#xff1a;搭建OBS 1、设置屏幕分辨率&#xff1a; 背景&#xff1a;因为一般初始状态&#xff0c;屏幕是横屏的&#xf…

【Linux】进程补充知识

文章目录 前言磁盘与物理内存 数据交互局部性原理页表 前言 磁盘是计算机唯一的一个机械设备&#xff0c;在磁盘文件系统中&#xff0c;我们了解到&#xff0c;磁盘的数据读取写入相比物理内存&#xff0c;CPU等效率低了很多。但是其作为数据的载体&#xff0c;物理内存与其交…

阿里达摩院——寻光:用AI,实现视频创作一条龙!

7 月 6 日&#xff0c;在2024 世界人工智能大会&#xff08;WAIC 2024&#xff09;上&#xff0c;阿里达摩院推出了一站式 AI 视频创作平台 —— 寻光&#xff0c;今天带大家提前来了解一下这款工具&#xff5e; 1、关于“寻光” 寻光是一个拥有辅助用户创作剧本、分镜图等&am…

NAT:地址转换技术

为什么会引入NAT&#xff1f; NAT&#xff08;网络地址转换&#xff09;的引入主要是为了解决两个问题 IPv4地址短缺&#xff1a;互联网快速发展&#xff0c;可用的公网IP地址越来越少。网络安全&#xff1a;需要一种方法来保护内部网络不被直接暴露在互联网上。 IPv4 &…

网络服务器配置与管理

网络服务器配置与管理是一个涉及多个方面的领域&#xff0c;它涵盖了从物理硬件的设置到操作系统、网络服务和应用的配置&#xff0c;再到日常维护和安全策略的实施。以下是网络服务器配置与管理的一些核心概念和步骤&#xff1a; 硬件配置&#xff1a; 选择合适的服务器硬件&a…

git简介以及git操作软件下载以及安装教程,git基础指令介绍,持续更新中~

什么是Git&#xff1f; 最近在学一些git的基础指令&#xff0c;仔细地了解了一下git&#xff0c;发现了他的强大功能&#xff0c;分享一下&#xff1a; Git是一个强大的工具&#xff0c;它在软件开发中扮演着至关重要的角色。 Git是一个开源的分布式版本控制系统&#xff0c;…

GET与POST请求的区别【随记】

区别 1. 请求参数的传递方式 2. 安全性 3. 数据量 4. 幂等性 5. 用途 在Java中&#xff0c;GET和POST请求是通过HTTP协议与服务器进行通信的两种常用方法&#xff0c;它们之间有一些关键的区别&#xff1a; 1. 请求参数的传递方式 GET请求&#xff1a;将参数直接附加在U…

书生·浦语2.5开源,推理能力再创新标杆

导读 2024 年 7 月 3 日&#xff0c;上海人工智能实验室与商汤科技联合香港中文大学和复旦大学正式发布新一代大语言模型书⽣浦语2.5&#xff08;InternLM2.5&#xff09;。相比上一代模型&#xff0c;InternLM2.5 有三项突出亮点&#xff1a; 推理能力大幅提升&#xff0c;在…

四、嵌入式技术(考点篇)

1 第二版教材2.4嵌入式内容补充 嵌入式系统是以应用为中心、以计算机技术为基础&#xff0c;并将可配置与可裁减的软、硬件集成于一体的专用计算机系统&#xff0c;需要满足应用对功能、可靠性、成本、体积和功耗等方面的严格要求。 一般嵌入式系统由嵌入式处理器、相关支撑硬…

View->不同刻度大小的刻度尺View

XML文件 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:o…