TextureProgressBar的progress_texture在其值改变时不会前进

问题描述 投票:0回答:1

我正在使用 Godot 4.0,并且遇到了 TextureProgressBar 的问题。为了重现此问题,请创建一个新项目,创建一个新场景作为 Node2D,并添加子 Timer 和 CanvasLayer。然后为 CanvasLayer 提供它自己的子级,即 TextureProgressBar。在Node2D中添加一个gdscript文件,并将定时器的timeout()信号连接到它(我将定时器的名称更改为StartTimer,将CanvasLayer更改为Loading Screen,将TextureProgressBar更改为Loading Bar,这就是func调用名称不同的原因在提供的代码中)。然后将脚本文件中的代码替换为:

extends Node2D

func _ready():
    get_node("Loading Screen/Loading Bar").position = Vector2(200, 360)
    get_node("Loading Screen/Loading Bar").set_value(1)

func start_world_creation():
    start_progress_bar()

func start_progress_bar():
    for x in 100:
        for y in 100:
            for time_waster in range(20000):
                time_waster += 300
        get_node("Loading Screen/Loading Bar").value += 1
        print(get_node("Loading Screen/Loading Bar").value)

func _process(delta):
    pass


func _on_start_timer_timeout():
    start_world_creation()

最后,将下面的图像分配到TextureProgressBar各自的位置: Under Texture Progress Texture Over Texture

由于某种原因,TextureProgressBar 在其值达到 100 之前不会更新。这是为什么,我该如何修复它?根据文档,它应该随着每个整数值的增加而更新,因为 TextureProgressBar 的步长值设置为 1,并且 max_value 为 100。

godot gdscript godot4
1个回答
2
投票

因此发出

Timer
的信号,并且此代码将在下一帧之前运行:

func _on_start_timer_timeout():
    start_world_creation()

正在调用此代码,该代码将在下一帧之前完成:

func start_world_creation():
    start_progress_bar()

正在调用此代码,该代码将在下一帧之前完成:

func start_progress_bar():
    for x in 100:
        for y in 100:
            for time_waster in range(20000):
                time_waster += 300
        get_node("Loading Screen/Loading Bar").value += 1
        print(get_node("Loading Screen/Loading Bar").value)

因此,当 Godot 最终到达下一帧时,

value
TextureProgressBar
位于
100.0
,这也是默认的
max_value
,所以你会看到它已满。

希望您能看到这个问题:

time_waster
等人。使线程保持忙碌,因此 Godot 无法做其他事情。 在这种情况下,使用
set_deferred
call_deferred
对您没有帮助。


更简单的解决方案是

await
一个框架:

func start_progress_bar():
    for x in 100:
        for y in 100:
            for time_waster in range(20000):
                time_waster += 300
        get_node("Loading Screen/Loading Bar").value += 1
        print(get_node("Loading Screen/Loading Bar").value)
        await get_tree().process_frame

当执行到

await
时,Godot会保存在原来的位置,并在发出指定信号(本例中为
get_tree().process_frame
)后继续。


您可以做的另一件事是在另一个

Thread
中运行代码。 在这种情况下,您可以使用
set_deferred
call_deferred
来操作 UI。


如果

time_waster
等人。代码是某些异步操作的替代,您可能还想寻找适当的信号(或创建一个信号),这样您就可以
await
直到异步操作完成。


警告:使用

await
有缺点:无法取消或断开连接。

因此:

  • 即使你知道信号永远不会发出,你也不能让戈多忘记。
  • 如果
    object
    被释放,并且发出信号,则出现运行时错误。

如果遇到这种情况,请通过将

Callable
延续(可以是匿名方法,又名“lambda”)连接到信号来重构代码...当对象被释放时,Godot 会断开它。

如果您需要检查

Node
是否即将被
queue_free
释放,您可以检查
is_queued_for_deletion
。如果您需要检查是否有对已释放的
Node
的引用,请使用
is_instance_valid
。如果您需要在释放
Object
之前执行某些操作,请让它覆盖
_notification
并对
NOTIFICATION_PREDELETE
作出反应。

© www.soinside.com 2019 - 2024. All rights reserved.