协程(Coroutine) 是一种打破函数传统工作流程的机制。之前在使用Unity的时候,初次接触到协程,当时查了一下并非所有语言都支持协程,而且我也只用它来实现一些类似计时或延时以及加载等待的功能,因此可能尚未领悟其精髓,下面是个人的心得,如有错误希望大家指正。
协程- 其本质,就是能让一个函数在执行过程中暂停(挂起),然后在接收到恢复指令以后继续执行的机制。
- 协程是单线程的,因此它线程安全,但是有些时候可以起到伪多线程的效果。
- 常用于函数间的对话,你可以把它想象成一把可以将函数切成片段的小刀。
在GDScript中使用协程,必须要使用yield
方法
方法原型
GDScriptFunctionState yield( Object object=null, String signal="" )
GDScriptFunctionState 是记录一个协程状态的对象,实际上它就代表(引用)着该协程。
官方在《GDScript协程范例》中给出了3种使用场景
-
yield()
和resmue()
组合
用yield()
来挂起,用resmue()
来恢复
注意: yield()
前面不需要return
使用范例
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.
- 用
yield(节点对象N,信号S)
的形式
这样相当于把函数挂起的同时,把这个协程(即 GDScriptFunctionState
)注册为 节点N
上信号S
的接收者,当 节点N
发出信号S
以后,函数会恢复执行。这种形式在处理两个独立动画之间相互交互的时候会比较有用。
使用范例
# Resume execution the next frame.
yield(get_tree(), "idle_frame")
# Resume execution when animation is done playing.
yield(get_node("AnimationPlayer"), "animation_finished")
# Wait 5 seconds, then resume execution.
yield(get_tree().create_timer(5.0), "timeout")
- 用
yield(协程对象C,"completed")
的形式
协程失效(即GDScriptFunctionState
的is_valid
为false
)以后,它会释放一个"completed"
信号,用这个信号恢复上一层协程。
使用范例
func my_func():
yield(button_func(), "completed")
print("All buttons were pressed, hurray!")
func button_func():
yield($Button0, "pressed")
yield($Button1, "pressed")