I'm trying to make my player flash when hit. I have hit detection working. He currently changes to red. I'm wondering how to make the actual flashing occur. Here's a snippet that handles being hit:
if(otherObject.CompareTag("Minion")) //hit by minion
{
if(hitFromTop(otherObject.gameObject)) //if player jumped on enemy
{
otherObject.GetComponent<Minion>().setMoving(false); //stop moving
playSound(KillEnemySound); //play killing enemy sound
jump();
Destroy(otherObject.gameObject); //kill minion
}
else //otherwise, enemy hit player
{
if(canTakeDamage)
{
changeColor(Color.red);
loseHealth(1); //lose health
canTakeDamage=false;
yield return new WaitForSeconds(1.5f); //delay taking damage repeatedly
changeColor(Color.white);
canTakeDamage=true;
}
//indicate lost health somehow
}
Currently, the changing to red is constant (not flashing) and temporary, via the yield return new WaitForSeconds(1.5f);
. I could put a couple of these calls, with colour changes in between them, but I was wondering if there was a neater way. I can't be the first one to make something flash in a game.
EDIT: I've added Heisenbug's Flash() code as follows:
IEnumerator FlashPlayer(float time, float intervalTime)
{
canTakeDamage=false;
float elapsedTime = 0f;
int index = 0;
while(elapsedTime < time )
{
Debug.Log("Elapsed time = " + elapsedTime + " < time = " + time + " deltaTime " + Time.deltaTime);
mat.color = colors[index % 2];
elapsedTime += Time.deltaTime;
index++;
yield return new WaitForSeconds(intervalTime);
}
canTakeDamage=true;
}
and it is called here:
void loseHealth(int damage)
{
//irrelevant details omitted for brevity
//the "if" checks if the player has run out of health, should not affect the else because this method is called from OnTriggerEnter...see below...
else
{
StartCoroutine(FlashPlayer (1.5f, 0.5f));
}
}
and here is where THAT is called (in OnTriggerEnter):
if(otherObject.CompareTag("Minion")) //hit by minion
{
if(hitFromTop(otherObject.gameObject)) //if player jumped on enemy
{
//irrelevant to the problem
}
else //otherwise, enemy hit player
{
if(canTakeDamage)
{
loseHealth(1);
}
//indicate lost health somehow
}
}
The problem now is that the Flash never stops. It should stop when elapsedTime reaches 1.5f, as I specified, but because it is only incrementing by small amounts (in Time.deltaTime) then it doesn't reach 1.5f for a very long time. Is there anything I've left out that should make it reach 1.5f faster, or is there another number I can pick that I can use accurately to act as a stopping point? The numbers for elapsedTime tend to be: 0, 0.02, 0.03693, 0.054132, etc. very small, so nothing I can really pick from here.
The following code may be what you are looking for. The object should flash for the total amount of time
changing its color after intervalTime
using UnityEngine;
using System.Collections;
public class FlashingObject : MonoBehaviour {
private Material mat;
private Color[] colors = {Color.yellow, Color.red};
public void Awake()
{
mat = GetComponent<MeshRenderer>().material;
}
// Use this for initialization
void Start () {
StartCoroutine(Flash(5f, 0.05f));
}
IEnumerator Flash(float time, float intervalTime)
{
float elapsedTime = 0f;
int index = 0;
while(elapsedTime < time )
{
mat.color = colors[index % 2];
elapsedTime += Time.deltaTime;
index++;
yield return new WaitForSeconds(intervalTime);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With