You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将C++已创建的游戏对象推送到Lua并支持直接访问属性

C++ 已创建游戏对象推送Lua环境实现方案

核心逻辑

类绑定时不注册构造函数即可禁止Lua侧新建实例,绑定成员变量即可支持直接.属性访问,再调用对应接口将已创建的C++实例指针推送到Lua环境即可。

方案1:使用Sol2实现

第一步:绑定Player类(不暴露构造函数)

#include <sol/sol.hpp>

sol::state lua;
// 仅绑定成员变量,不注册构造函数,Lua侧无法新建Player实例
lua.new_usertype<Player>("Player",
    "name", &Player::name,
    "objectId", &Player::objectId
);

第二步:推送已创建的实例到Lua

// C++侧创建的实例
Player* player1 = new Player("Player1", 1);
Player* player2 = new Player("Player2", 2);

// 推送为Lua全局变量,使用std::ref表示Lua不持有对象所有权,不会GC释放C++侧对象
lua["player1"] = std::ref(*player1);
lua["player2"] = std::ref(*player2);

Lua侧访问示例

直接通过属性名访问即可:

print(player1.name) -- 输出Player1
print(player2.objectId) -- 输出2

方案2:使用LuaBridge实现

第一步:绑定Player类(不暴露构造函数)

#include <LuaBridge/LuaBridge.h>

lua_State* L = luaL_newstate();
luaL_openlibs(L);

// 仅绑定属性,不注册构造函数,Lua侧无法新建Player实例
luabridge::getGlobalNamespace(L)
    .beginClass<Player>("Player")
    .addProperty("name", &Player::name)
    .addProperty("objectId", &Player::objectId)
    .endClass();

第二步:推送已创建的实例到Lua

Player* player1 = new Player("Player1", 1);
Player* player2 = new Player("Player2", 2);

// 推送实例到Lua栈,再设为全局变量
luabridge::push(L, player1);
lua_setglobal(L, "player1");

luabridge::push(L, player2);
lua_setglobal(L, "player2");

Lua侧访问方式和Sol2方案完全一致。

注意事项

  • 所有对象生命周期由C侧管理时,不要让Lua持有对象所有权,避免GC触发时误删C侧还在使用的对象
  • 若成员变量后续需要加访问控制,可将addProperty的参数替换为对应的get/set函数,Lua侧访问语法保持不变,无需修改脚本代码

内容的提问来源于stack exchange,提问作者Cheeky Bastard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 06:54:04