📜  GDscript中的工具模式

📅  最后修改于: 2021-01-02 10:10:05             🧑  作者: Mango

GDscript中的工具模式

脚本不在编辑器中运行,只能更改导出的属性。在某些情况下,希望它们确实在编辑器中运行(只要它们不执行游戏代码或手动避免这样做)。为此,存在tool关键字,并且必须将其放置在文件的顶部:

tool
extends Button

func _ready():
    print("Hello")

内存管理

如果一个类从Reference继承,则实例将在不再使用时释放。不存在垃圾收集器,引用计数。默认情况下,所有未定义继承的类都将扩展Reference。如果不希望这样做,则类必须手动继承Object,并且必须调用instance.free()。为了避免无法释放的引用循环,提供了weakref函数来创建弱引用。

讯号

通常希望发送一个通知,说明实例中发生了某些事情。 GDScript支持创建内置的Godot信号。使用signal关键字在GDScript中声明信号很容易。

# No arguments.
signal your_signal_name
# With arguments.
signal your_signal_name_with_args(a, b)

这些信号可以在编辑器中连接,也可以像常规信号一样从代码中连接。以声明信号的类的实例为例,并将其连接到另一个实例的方法:

func _callback_no_args():
    print("Got callback!")

func _callback_args(a,b):
    print("Got callback with args! a: ", a, " and b: ", b)

func _at_some_func():
    instance.connect("your_signal_name", self, "_callback_no_args")
    instance.connect("your_signal_name_with_args", self, "_callback_args")

也可以使用自定义值将参数绑定到缺少参数的信号:

func _at_some_func():
    instance.connect("your_signal_name", self, "_callback_args", [22, "hello"])

当来自多个对象的信号连接到单个回调并且必须标识发送者时,这很有用:

func _button_pressed(which):
    print("Button was pressed: ", which.get_name())

func _ready():
    for b in get_node("buttons").get_children():
        b.connect("pressed", self, "_button_pressed",[b])

最后,通过使用Object.emit_signal方法来发出自定义信号:

func _at_some_func():
    emit_signal("your_signal_name")
    emit_signal("your_signal_name_with_args", 55, 128)
    some_instance.emit_signal("some_signal")

协程产量

GDScript通过yield内置函数为协程提供支持。调用产量将立即从当前的函数返回,具有相同函数作为返回值的电流冻结状态。在该结果对象上调用resume将继续执行并返回函数返回的任何内容。恢复后,状态对象将无效。这是一个例子:

func my_func():
   print("Hello")
   yield()
   print("world")

func _ready():
    var y = my_func()
    # Function state saved in 'y'.
    print("my dear")
    y.resume()
    # 'y' resumed and is now an invalid state.

将print:

Hello
my dear
world

也可以在yield()和resume()之间传递值,例如:

func my_func():
   print("Hello")
   print(yield())
   return "cheers!"

func _ready():
    var y = my_func()
    # Function state saved in 'y'.
    print(y.resume("world"))
    # 'y' resumed and is now an invalid state.

将print:

Hello
world
cheers!

协程和信号

使用Yield的真正优势在于与信号结合使用。良率可以接受两个参数,一个对象和一个信号。收到信号后,将重新开始执行。这里有些例子:

# Resume execution the next frame.
yield(get_tree(), "idle_frame")

# Resume execution when animation is done playing.
yield(get_node("AnimationPlayer"), "finished")

# Wait 5 seconds, then resume execution.
yield(get_tree().create_timer(5.0), "timeout")

协程自身转换为无效状态时会使用完成的信号,

例如:

func my_func():
        yield(button_func(), "completed")
        print("All buttons were pressed, hurray!")

func button_func():
    yield($Button0, "pressed")
        yield($Button1, "pressed")

只有同时按下两个按钮,my_func才会继续执行。

就绪关键字

使用节点时,通常希望将对场景部分的引用保留在变量中。由于仅在进入活动场景树时才保证对视图进行配置,因此只有在调用Node._ready()时才能获取子节点。

var my_label

func _ready():
    my_label = get_node("MyLabel")

这可能会有些麻烦,尤其是当节点和外部引用堆积时。为此,GDScript具有onready关键字,该关键字将成员变量的初始化推迟到调用_ready为止。它可以用一行替换上面的代码:

onready var my_label = get_node("MyLabel")

断言关键字

assert关键字可用于检查调试版本中的条件。在非调试版本中,这些断言将被忽略。

# Check that 'i' is 0.
assert(i == 0)