Godot 在黑色和白色之间淡入淡出使用 Tween 延迟不起作用

Godot Fade In Between Black and White Using Tween Delay Doesn't Work

我正在尝试根据玩家是否移动在 2 tween.interpolate_properties() 之间切换。但是,延迟功能不起作用。在第 11 行没有延迟,它立即工作(应该如此)。但是,当我添加 2 秒的延迟时,看起来两秒后它会短暂地闪烁黑色(但不是一直闪烁)然后恢复透明。附上代码,求助!

extends Sprite
onready var TweenNode = get_node("../Tween")
onready var velocity

func _ready():
    modulate.a = 0

func _process(delta):
    velocity = get_node("../../").velocity
    if velocity == Vector2.ZERO:
        TweenNode.interpolate_property(self, "modulate", modulate, Color(0, 0, 0, 1), 5, Tween.TRANS_EXPO, Tween.EASE_OUT_IN, 2)
    else:
        TweenNode.interpolate_property(self, "modulate", modulate, Color(0, 0, 0, 0), .1, Tween.TRANS_EXPO, Tween.EASE_OUT_IN)
    TweenNode.start()

这是“计算机正在按照您的指示执行”的情况。

这一行:

TweenNode.interpolate_property(self, "modulate", modulate, Color(0, 0, 0, 1), 5, Tween.TRANS_EXPO, Tween.EASE_OUT_IN, 2)

它说,2 秒后将 modulate 设置为 modulate 现在的值。 然后在 5 秒内将它的值更改为 Color(0, 0, 0, 1),如此这般缓和。

而且你每一帧都在这样做。因此,两秒后,每一帧,它都会将 modulate 设置为两秒前的值。 插值将尝试更改 modulate,只是为了在下一帧重置值。

因此:

it looks like after two seconds it briefly flashes black (but not all the way) and then goes back to transparent

如果你离开它 运行,你会发现在另外两秒后它不会变回透明。相反,它会回到两秒钟后你看到的那种微黑。因为四秒后,就是两秒前调制的结果。

并且,如您所想,这意味着天会开始变得更暗。几分钟后,它几乎变黑了。


当然,我们可以跟踪我们所做的 interpolate_property 调用。为此,我们将添加一个新的 属性 来跟踪我们告诉 Tween 插值到的值...


好吧,我要边走边解释一下follow_property

使用 follow_property 你可以告诉 Tween 将一个 属性 插入另一个 属性.

的值

因此,我们添加新的 属性,例如:

var _modulate_target:Color

我们需要初始化一下,顺便说一句:

func _ready():
    modulate.a = 0
    _modulate_target = modulate

然后我们可以告诉 Tween 让一个 属性 跟随另一个 属性:

_modulate_target = Color(0, 0, 0, 1)
TweenNode.follow_property(
    self,
    "modulate",
    modulate,
    self,
    "_modulate_target",
    5,
    Tween.TRANS_EXPO,
    Tween.EASE_OUT_IN,
    2
)
TweenNode.start()

并且为了避免重置行为,我们检查新 属性 的值,如果它已经是我们想要的值,我们什么也不做:

if _modulate_target != Color(0, 0, 0, 1):
    _modulate_target = Color(0, 0, 0, 1)
    TweenNode.remove(self, "modulate")
    TweenNode.follow_property(
        self,
        "modulate",
        modulate,
        self,
        "_modulate_target",
        5,
        Tween.TRANS_EXPO,
        Tween.EASE_OUT_IN,
        2
    )
    TweenNode.start()

我还删除了 modulate 上的所有现有动画:

TweenNode.remove(self, "modulate")

而且每次更改时您都会遵循该模式。我会主张使用 setget,但考虑到您想要不同的 durationdelay,这是行不通的。相反,我们可以简单地将其包装到另一个 func:

func _tween_modulate(target:Color, duration:float, delay:float) -> void:
    if _modulate_target == target:
        return

    _modulate_target = target
    TweenNode.remove(self, "modulate")
    TweenNode.follow_property(
        self,
        "modulate",
        modulate,
        self,
        "_modulate_target",
        duration,
        Tween.TRANS_EXPO,
        Tween.EASE_OUT_IN,
        delay
    )
    TweenNode.start()

然后你这样使用它:

    if velocity == Vector2.ZERO:
        _tween_modulate(Color(0, 0, 0, 1), 5, 2)
    else:
        _tween_modulate(Color(0, 0, 0, 0), .1, 0)

请注意,您仍然需要 _modulate_target 来检查它是否与 target 不同。但是,是的,您可以使用 interpolate_property:

func _tween_modulate(target:Color, duration:float, delay:float) -> void:
    if _modulate_target == target:
        return

    _modulate_target = target
    TweenNode.remove(self, "modulate")
    TweenNode.interpolate_property(
        self,
        "modulate",
        modulate,
        target,
        duration,
        Tween.TRANS_EXPO,
        Tween.EASE_OUT_IN,
        delay
    )
    TweenNode.start()

使用 follow_property 只是让这个重构更容易解释。