I'm using Lua in a game engine that I'm working on. I'd like to give Lua a way to get and set the position of the entity that the script is sitting on. The script is a component that contains a pointer to the entity that contains it. From Lua, I'd like to be able to type:
print(transform.position.x)
transform.position.x = 10
I've written a getter and setter for position, by I'd like them to be contained under transform.position
, and preferably not be getter and setters at all but rather behave more like public members. My current getter and setter looks like this:
int getXPosition(lua_State* L) {
lua_pushnumber(L, Script::currentEntity->get<Transform>().position.x);
return 1;
}
So, how would this be done, if possible at all?
Short answer: it may be done with userdata and metatables.
More details:
Register metatable that will be a "class" for the position
object and register "__index"
and "__newindex"
metamethods for it:
luaL_newmetatable(L, "position_metatable");
lua_pushcfunction(L, &position__index);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, &position__newindex);
lua_setfield(L, -2, "__newindex");
lua_pop(L, 1);
Write function position__index
(it is getter). This is regular C Api function, it takes 2 arguments: the position
userdata and a field name. If the field name is "x"
, the function should return the value of the x
field.
Write function position__newindex
(it is setter). This is regular C Api function, it takes 3 arguments: the position
userdata, field name and a value to write. If the field is "x"
, teh function should write the value to the x
field.
To pass the position
object from native code to script, create userdata and set the "position_metatable"
as a metatable for the userdata, see 28.2 – Metatables for example.
Access to the field as transform.position.x
.