- Home /
How to Make a Character Flicker?
Hey Guys! I've made my character a bit transparent (alpha = 0.3f) and red on collision, and it comes back to normal after one second. Before coming back to normal alpha, I want it to flicker between alpha value of 0.3f and 1.0f. You might have seen this effect on many games when the character gets hit by something.
Can someone help me with this? Please Help, ThankYou.
Answer by ninjapretzel · May 12, 2014 at 01:31 AM
There would be multiple steps involved. My solution would be to create a new behaviour to handle the flickering. It would track flicker 'ticks' and update the color that is on the material on the same object. Assuming you are using the default Transparent/Diffuse shader, and C#...
Using a timer pattern is pretty easy, though not the most 'effecient'. It's really not to big of a deal for most games.
Pastebin for easier copy: http://pastebin.com/uB3NGfks
Edit: with the way this is designed, you will just need to set the animating property when you want to start/stop the effect.
If you're using the same timer pattern (it would be good practice to use it a bunch, since it's a pretty common pattern, and pretty useful)
//When taking damage, wherever that is
flickerTimeout = 3; //flicker for 3 seconds when hit
//In Update() somewhere
flickerTimeout -= Time.deltaTime
GetComponent<Flicker>().animate = flickerTimeout > 0;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Flicker : MonoBehaviour {
public bool animate = true;
public float tickTime = .1f; //Time in seconds per 'tick' (.1 = .1sec full alpha, .1sec reduced alpha, .1sec full, etc)
public float alphaScale = .3f; //How transparent are the 'faded' ticks?
float timeout = 0; //timer to keep track of current time this tick.
float fullAlpha = 1; //Keep track of full alpha. We will grab this info from the material on start.
bool full = true; //Flag to keep track of if we should use the full or reduced alpha
void Start() {
fullAlpha = renderer.material.color.a;
timeout = 0;
full = true;
}
void Update() {
Color c = renderer.material.color;
c.a = fullAlpha;
//Is the effect animating?
if (animate) {
//Accumulate time into the timer
timeout += Time.deltaTime;
//Process all ticks that would have happened over the deltaTime
//(incase of a delay, we don't want it to instantly flip for a few frames)
while (timeout > tickTime) {
timeout -= tickTime;
full = !full;
//Subtract the time for that tick, and flip the fade flag.
}
//If we are not full this frame, set the reduced alpha value.
if (!full) {
c.a *= alphaScale;
}
}
//This will apply the full alpha if we are not animating,
//And then partial alpha half the time if we are.
renderer.material.color = c;
}
}
@ninjapretzel its not flickering. ins$$anonymous$$d it is staying at full alpha.
did you attach the script to the object that also has the mesh renderer attached to it?
Also, are you using a transparent shader? (not a cutout, Transparent/Diffuse or some other)
ping pong could work, but you would also get a smooth transition from high to low, ins$$anonymous$$d of instant. It would create a different effect.
Color c = renderer.material.color;
c.a = .3f + $$anonymous$$athf.PingPong(Time.time * 7f, .7f);
renderer.material.color = c;
@ninjapretzel yes! I've attached the script to the object having mesh renderer. But I'm using this shader.