I'm trying to define a new function for my Player class which was defined in C#. The purpose of Lua in my project (a game engine) is to define custom behavior for entities such as players.
However, when I do DoFile(fileName) on the Lua file, it crashes with this exception:
"field or property 'Idle' does not exist"
It specifically points to the first line in this chunk of code:
function Player:Idle()
self:Turn()
self.StateType = StateType.Stand
self.MoveType = MoveType.Idle
self.Vel = Vector2.Zero
if self.Anim.Number ~= 0 and (self.Anim.Number ~= 5 or self:GetAnimTime() == 0) then
self:ChangeAnim(0)
end
end
It seems to have a problem with writing Player:Idle. However, I also tried writing it as Player.Idle and I get the same issue. Here's how I handle loading the scripts for the player in C#:
state["Player"] = this;
// Load the states
for (int j = 0; j < stateFiles.Length; j++)
{
string fp = filePath + @"\" + stateFiles[j];
// If it's common, then if it doesn't exist, use the default.
if (stateFiles[j] == "common.lua" && !File.Exists(fp))
fp = Path.Combine("Content", "common.lua");
// Now load it
var f = state.DoFile(fp);
}
I'm setting the Player global to this because this is the player class, so any new functions need to be declared in the context of Player. What am I doing wrong?
Edit
I've solved the error from earlier, but I'm still not getting the results I want. It seems it's not possible to directly do this; however I've read up and it seems in Lua 5.2, there's a way to do something like this by associating a table with the userdata object through debug.setuservalue. However, when I tried using it, the table was still empty (even though the userdata was not).
This is what I tried (C#):
state.NewTable("Player");
state["tmp"] = this;
state.DoString("a = debug.setuservalue(tmp, Player)");
var t = state["Player"]; // Shows that Player is an empty table
var a = state["a"]; // Shows that a was indeed set.
In other words, I want to be able to use self in the script to be able to refer to the userdata, as well as custom functions, such as Idle() and Turn().
How can I achieve the behavior I desire?
From the Lua reference manual: https://www.lua.org/manual/5.3/manual.html#2.1
So you cannot add functions to userdata but you write your own, extended interface by wrapping the userdata in your own Lua table.
Simple example, assuming you can create a Player userdata value by calling Player().
Then you can simply call
WrappedPlayer:Idle()Of course you can further improve this and after overwriting the Player table with your own and adding some metatable magic you could simply create your very own Player object:
Just read some Lua OOP tutorials to find out how.
Not to forget a very simple solution: