Godot/Gdscript:为什么 str2var 无法使用 _init 方法处理 类?
Godot/Gdscript: Why is str2var not working on classes with _init method?
让我们定义 2 类
A.gd
class_name A
var v = null
func _init(v_):
v = v_
B.gd
class_name B
var v = null
现在,当我尝试使用 str2var/var2str 时,这就是我得到的
var a = A.new("aaa")
var b = B.new()
b.v = "bbb"
printt("var2str(a):", var2str(a))
printt("var2str(b):", var2str(b))
printt ("var2str(str2var(var2str(a))):", var2str(str2var(var2str(a))))
printt ("var2str(str2var(var2str(b))):", var2str(str2var(var2str(b))))
输出:
var2str(a): Object(Reference,"script":Resource( "res://Scripts/AI/A.gd"),"v":"aaa")
var2str(b): Object(Reference,"script":Resource( "res://Scripts/AI/B.gd"),"v":"bbb")
var2str(str2var(var2str(a))): Object(Reference,"script":null)
var2str(str2var(var2str(b))): Object(Reference,"script":Resource( "res://Scripts/AI/B.gd"),"v":"bbb")
为什么 str2var(a) 不起作用?
我该如何解决?
解决方案
通过将参数设为可选来修复它,例如:
class_name A
var v = null
func _init(v_ = null):
v = v_
这样就没有错误了。我得到这个输出:
var2str(a): Object(Reference,"script":Resource( "res://A.gd"),"v":"aaa")
var2str(b): Object(Reference,"script":Resource( "res://B.gd"),"v":"bbb")
var2str(str2var(var2str(a))): Object(Reference,"script":Resource( "res://A.gd"),"v":"aaa")
var2str(str2var(var2str(b))): Object(Reference,"script":Resource( "res://B.gd"),"v":"bbb")
问题
对于摘要,str2var
不会将任何参数传递给 _init
。 反正传什么也不知道
答案的其余部分是确认 str2var
将导致不带参数调用 _init
的过程。
当我尝试使用您的代码时出现此错误:
E 0:00:00.630 _create_instance: Condition "r_error.error != Variant::CallError::CALL_OK" is true. Returned: __null
<C++ Source> modules/gdscript/gdscript.cpp:121 @ _create_instance()
<Stack Trace> main.gd:12 @ _ready()
我们可以通过查看 source.
找到在 _create_instance
中抛出错误的行
遗憾的是,这并没有给我太多信息。所以,我决定搜索 str2var
是如何实现的。
我们在 GDScriptFunctions::call
, here. Which calls VariantParser::parse
, which calls VariantParser::parse_value
. We are interested in the case of an "Object"
(here) 中找到它。这会导致调用 ClassDB::instance(type)
。类型将是 "Reference"
,然后它会继续设置所有属性。作为第一个 "script":Resource("res://A.gd")
.
当我们设置脚本时(here), it will result in a call to GDScript::instance_create
. Which calls GDScript::_create_instance
(here):
return _create_instance(NULL, 0, p_this, Object::cast_to<Reference>(p_this) != NULL, unchecked_error)
_init
没有参数(NULL
是参数数组,0
是参数个数)。这是 GDScript::_create_instance
:
的签名
GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Variant::CallError &r_error)
当然,initializer->call(instance, p_args, p_argcount, r_error);
失败了,因为 _init
需要一个参数。我们找到了进一步向下抛出错误的行。 注意:initializer
是在解析脚本时创建的。
让我们定义 2 类
A.gd
class_name A
var v = null
func _init(v_):
v = v_
B.gd
class_name B
var v = null
现在,当我尝试使用 str2var/var2str 时,这就是我得到的
var a = A.new("aaa")
var b = B.new()
b.v = "bbb"
printt("var2str(a):", var2str(a))
printt("var2str(b):", var2str(b))
printt ("var2str(str2var(var2str(a))):", var2str(str2var(var2str(a))))
printt ("var2str(str2var(var2str(b))):", var2str(str2var(var2str(b))))
输出:
var2str(a): Object(Reference,"script":Resource( "res://Scripts/AI/A.gd"),"v":"aaa")
var2str(b): Object(Reference,"script":Resource( "res://Scripts/AI/B.gd"),"v":"bbb")
var2str(str2var(var2str(a))): Object(Reference,"script":null)
var2str(str2var(var2str(b))): Object(Reference,"script":Resource( "res://Scripts/AI/B.gd"),"v":"bbb")
为什么 str2var(a) 不起作用?
我该如何解决?
解决方案
通过将参数设为可选来修复它,例如:
class_name A
var v = null
func _init(v_ = null):
v = v_
这样就没有错误了。我得到这个输出:
var2str(a): Object(Reference,"script":Resource( "res://A.gd"),"v":"aaa")
var2str(b): Object(Reference,"script":Resource( "res://B.gd"),"v":"bbb")
var2str(str2var(var2str(a))): Object(Reference,"script":Resource( "res://A.gd"),"v":"aaa")
var2str(str2var(var2str(b))): Object(Reference,"script":Resource( "res://B.gd"),"v":"bbb")
问题
对于摘要,str2var
不会将任何参数传递给 _init
。 反正传什么也不知道
答案的其余部分是确认 str2var
将导致不带参数调用 _init
的过程。
当我尝试使用您的代码时出现此错误:
E 0:00:00.630 _create_instance: Condition "r_error.error != Variant::CallError::CALL_OK" is true. Returned: __null
<C++ Source> modules/gdscript/gdscript.cpp:121 @ _create_instance()
<Stack Trace> main.gd:12 @ _ready()
我们可以通过查看 source.
找到在_create_instance
中抛出错误的行
遗憾的是,这并没有给我太多信息。所以,我决定搜索 str2var
是如何实现的。
我们在 GDScriptFunctions::call
, here. Which calls VariantParser::parse
, which calls VariantParser::parse_value
. We are interested in the case of an "Object"
(here) 中找到它。这会导致调用 ClassDB::instance(type)
。类型将是 "Reference"
,然后它会继续设置所有属性。作为第一个 "script":Resource("res://A.gd")
.
当我们设置脚本时(here), it will result in a call to GDScript::instance_create
. Which calls GDScript::_create_instance
(here):
return _create_instance(NULL, 0, p_this, Object::cast_to<Reference>(p_this) != NULL, unchecked_error)
_init
没有参数(NULL
是参数数组,0
是参数个数)。这是 GDScript::_create_instance
:
GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Variant::CallError &r_error)
当然,initializer->call(instance, p_args, p_argcount, r_error);
失败了,因为 _init
需要一个参数。我们找到了进一步向下抛出错误的行。 注意:initializer
是在解析脚本时创建的。