如何将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
相关产品推荐
相关产品推荐

