假设我有一个对象,并且在字符串中给定了一个类名,
如何检查该对象是否属于该类?
extends Node2D
func _ready():
var given_class_name="KinematicBody2D"
if($Obj is given_class_name):
...
Run Code Online (Sandbox Code Playgroud)
您可以使用get_class()来查找 an 的类Object,忽略Scripts。在这种情况下应该足够了:
var given_class_name="KinematicBody2D"
prints($Obj.get_class() == given_class_name)
Run Code Online (Sandbox Code Playgroud)
但并非所有情况都是如此,不是吗?也许您想检查基类,那么这不起作用:
var given_class_name="PhysicsBody2D"
prints($Obj.get_class() == given_class_name)
Run Code Online (Sandbox Code Playgroud)
相反,我们可以使用is_class:
var given_class_name="PhysicsBody2D"
prints($Obj.is_class(given_class_name))
Run Code Online (Sandbox Code Playgroud)
或者我们可以问ClassDB:
var given_class_name="PhysicsBody2D"
var obj_class := $Obj.get_class()
prints(
obj_class == given_class_name
or ClassDB.is_parent_class(given_class_name, obj_class)
)
Run Code Online (Sandbox Code Playgroud)
但是课程呢Script?
也许您还记得我们可以通过查看来找到脚本的类名_global_script_classes,如下所示:
var obj_class_name := $Obj.get_class()
var script:Script = $Obj.get_script()
if script != null:
obj_class_name = script.resource_path
for x in ProjectSettings.get_setting("_global_script_classes"):
if str(x["path"]) == script.resource_path:
script_class_name = str(x["class"])
Run Code Online (Sandbox Code Playgroud)
上面的代码将设置obj_class_name为:
$Obj(如果有)。$Obj(如果有)。$Obj。然而,由于我们想要检查它是否属于给定类型,所以这是不够的。因为我们还需要检查Script继承。事实证明,弄清楚我们给出的名称是什么类型的类并从那里开始工作会更方便:
func is_instance_of(obj:Object, given_class_name:String) -> bool:
if ClassDB.class_exists(given_class_name):
# We have a build in class
return obj.is_class(given_class_name)
else:
# We don't have a build in class
# It must be a Script class
# Try to find the Script
var class_script:Script
for x in ProjectSettings.get_setting("_global_script_classes"):
if str(x["class"]) == obj_class_name:
class_script = load(str(x["path"]))
break
if class_script == null:
# Unknown class
return false
# Get the script of the object and try to match it
var check_script := obj.get_script()
while check_script != null:
if check_script == class_script:
return true
check_script = check_script.get_base_script()
# Match not found
return false
Run Code Online (Sandbox Code Playgroud)
我们就快到了。如您所知,在 GDScript 中,您可以使用脚本路径进行扩展(请参阅类)。因此,我们可能会考虑脚本有效类名的资源路径...我们也可以支持:
func is_instance_of(obj:Object, given_class_name:String) -> bool:
if ClassDB.class_exists(given_class_name):
# We have a build in class
return obj.is_class(given_class_name)
else:
# We don't have a build in class
# It must be a script class
var class_script:Script
# Assume it is a script path and try to load it
if ResourceLoader.exists(given_class_name):
class_script = load(given_class_name) as Script
if class_script == null:
# Assume it is a class name and try to find it
for x in ProjectSettings.get_setting("_global_script_classes"):
if str(x["class"]) == obj_class_name:
class_script = load(str(x["path"]))
break
if class_script == null:
# Unknown class
return false
# Get the script of the object and try to match it
var check_script := obj.get_script()
while check_script != null:
if check_script == class_script:
return true
check_script = check_script.get_base_script()
# Match not found
return false
Run Code Online (Sandbox Code Playgroud)
您可以加倍努力并支持 Variant 而不是Object. 然后你可以用typeof...检查它的类型。如果是,TYPE_OBJECT那么你继续检查一个类。如果不是,您将需要一个巨大的开关来检查构建类型的名称(与此处的类似,但带有类型名称)。
对于任何试图在《GODOT 4》中这样做的人:ProjectSettings.get_setting("_global_script_classes")不再有效。而是使用ProjectSettings.get_global_class_list().
| 归档时间: |
|
| 查看次数: |
4066 次 |
| 最近记录: |