[英]NLua - How to add new functions to a userdata through Lua?
I'm trying to define a new function for my Player
class which was defined in C#. 我正在尝试为在C#中定义的
Player
类定义一个新函数。 The purpose of Lua in my project (a game engine) is to define custom behavior for entities such as players. Lua在我的项目(游戏引擎)中的目的是为玩家等实体定义自定义行为。
However, when I do DoFile(fileName)
on the Lua file, it crashes with this exception: 但是,当我在Lua文件上执行
DoFile(fileName)
时,它因以下异常而崩溃:
"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
. 编写
Player:Idle
似乎有问题。 However, I also tried writing it as Player.Idle
and I get the same issue. 但是,我也尝试将其编写为
Player.Idle
并遇到相同的问题。 Here's how I handle loading the scripts for the player in C#: 这是我在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
. 我将Player全局设置
this
因为这是Player类,因此任何新函数都需要在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
. 但是我已经阅读了,在Lua 5.2中,似乎有一种方法可以通过
debug.setuservalue
将表与userdata对象相关联。 However, when I tried using it, the table was still empty (even though the userdata was not). 但是,当我尝试使用它时,表仍然是空的(即使userdata不是)。
This is what I tried (C#): 这是我尝试过的(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()
. 换句话说,我希望能够在脚本中使用
self
来引用用户数据以及自定义函数,例如Idle()
和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 从Lua参考手册中: https : //www.lua.org/manual/5.3/manual.html#2.1
Userdata values cannot be created or modified in Lua, only through the C API.
只能通过C API无法在Lua中创建或修改Userdata值。 This guarantees the integrity of data owned by the host program.
这保证了主机程序拥有的数据的完整性。
So you cannot add functions to userdata but you write your own, extended interface by wrapping the userdata in your own Lua table. 因此,您无法向用户数据添加功能,而是通过将用户数据包装在自己的Lua表中来编写自己的扩展接口。
Simple example, assuming you can create a Player userdata value by calling Player(). 一个简单的示例,假设您可以通过调用Player()创建Player用户数据值。
WrappedPlayer = {}
WrappedPlayer.usrdata = Player()
function WrappedPlayer:Idle()
self.usrdata:Turn()
self.usrdata.MoveType = MoveType.Idle
end
Then you can simply call WrappedPlayer:Idle()
然后,您可以简单地调用
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: 当然,您可以进一步改善这一点,并用自己的Player表覆盖并添加一些可继承的魔术之后,您可以简单地创建自己的Player对象:
local myPlayer = Player()
myPlayer:Idle()
Just read some Lua OOP tutorials to find out how. 只需阅读一些Lua OOP教程以了解操作方法。
Not to forget a very simple solution: 不要忘记一个非常简单的解决方案:
function SetPlayerIdle(player)
player:Turn()
-- and so forth
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.