+2 votes

I want to implement a blinking damage effect in Godot 3.0 where every few milliseconds my Player sprite alternates between his normal image and a somewhat transparent version of that image. I want this blinking to happen 3 or 4 times.

I already have a damage flag which lasts for however long I want, I just need to figure out how to code the blinking. This blinking should occur even if my sprite changes his animation.

I feel like the easiest way would be to change the sprite's modulate, for example, lowing the alpha, then setting it back to 1. But what's an elegant way to go about this so that it happens 3 or 4 times?

in Engine by (1,577 points)
retagged by

1 Answer

+3 votes
Best answer

Two variants of the same solution:

If you have a flag which is true while you should be flickering, you can do this:

func _process(delta):
    if is_damage_state:
        # Halve opacity every uneven frame counts
        self.modulate.a = 0.5 if Engine.get_frames_drawn() % 2 == 0 else 1.0
    else:
        # But beware... if the last damage frame is not even,
        # you risk to leave your character half transparent!
        # Preferably do this when you set your flag back to false
        self.modulate.a = 1.0

If you have a signal emitted only once you take damage:

func on_take_damage():
    # Flicker 4 times
    for i in 4:
        self_modulate.a = 0.5
        yield(get_tree(), "idle_frame")
        self_modulate.a = 1.0
        yield(get_tree(), "idle_frame")

You can also do this without code, by adding another AnimationPlayer which can run independently from your main animations.

by (28,835 points)
selected by

I ended up going with another AnimationPlayer which I named "EffectsPlayer". I can also use it for other effects on my player. I didn't like your first suggestion since the damage blinking might span two different animation states of my player and the states' frames might not have equal spacing, resulting in unequal blinking. I didn't try your second suggestion.

They were code suggestions, I just wanted to show different variants. I think the `AnimationPlayerv solution is better overall :)

I appreciate the multiple suggestions, just wanted to point out one flaw with the approach. I wish more people gave detailed answers like this on the site!

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.