- Home /
how to make a character flash red when damaged
ok you see i created this coroutine to loop from red to defualt colors for a period of time when the player is hit the problem enter code here
is that i set the coroutine to wait 0.3 seconds then go to the next color then wait 0.3 seconds but the corotouine only follows this once when it is red then the colors start flashing randomly as if it was going with the frame rate( im not sure) but everything else works fine but i want the flashing to look smooth and consistent thank you.
if (damagebreak) {
damagebreaktimer -= 1 * Time.deltaTime;
colorchange = true;
}
if (colorchange && damagebreak) {
StartCoroutine ("color");
} else {
GetComponent<SpriteRenderer> ().color = white;
}
}
IEnumerator color(){
while(colorchange && damagebreak) {
GetComponent<SpriteRenderer> ().color = red;
yield return new WaitForSeconds(0.3f);
GetComponent<SpriteRenderer> ().color = white;
yield return new WaitForSeconds(0.3f);
}
}
Answer by dorpeleg · May 25, 2015 at 03:02 PM
You are probably calling StartCoroutine ("color"); more then once, so you have multiple coroutines running.
Do something like:
bool coroutineCalled = false;
if (damagebreak) {
damagebreaktimer -= 1 * Time.deltaTime;
colorchange = true;
}
if (colorchange && damagebreak)
{
if(!coroutineCalled)
{
StartCoroutine ("color");
}
}
else
{
GetComponent<SpriteRenderer> ().color = white;
}
}
IEnumerator color()
{
while(colorchange && damagebreak)
{
coroutineCalled = true;
GetComponent<SpriteRenderer> ().color = red;
yield return new WaitForSeconds(0.3f);
GetComponent<SpriteRenderer> ().color = white;
yield return new WaitForSeconds(0.3f);
}
coroutineCalled = false;
}
alright using UnityEngine; using System.Collections;
public class playerhealth : $$anonymous$$onoBehaviour {
public bool lvlthreehearts;
public float threehearts = 15;
public float health;
public bool heart3ishalf = false;
public bool heart3isempty = false;
public bool heart2ishalf = false;
public bool heart2isempty = false;
public bool heart1ishalf = false;
public bool heart1isempty = false;
public bool damagebreak = false;
public float damagebreaktimer = 5f;
public float damagebreaktimertotal = 5f;
public bool colorchange = false;
public float colorchangetimer = 1f;
public Color red;
public Color white;
// Use this for initialization
void Start () {
lvlthreehearts = true;
damagebreaktimer = damagebreaktimertotal;
}
// Update is called once per frame
void Update () {
if (lvlthreehearts) {
health = threehearts;
lvlthreehearts = false;
}
if (health == 12.5) {
heart3ishalf = true;
}
if (health == 10) {
heart3isempty = true;
}
if (health == 7.5) {
heart2ishalf = true;
}
if (health == 5) {
heart2isempty = true;
}
if (health == 2.5) {
heart1ishalf = true;
}
if (health == 0) {
heart1isempty = true;
}
if (damagebreaktimer <= 0) {
damagebreak = false;
colorchange = false;
damagebreaktimer = damagebreaktimertotal;
}
if (damagebreak) {
damagebreaktimer -= 1 * Time.deltaTime;
colorchange = true;
}
if (colorchange) {
StartCoroutine ("color");
} else {
GetComponent<SpriteRenderer> ().color = white;
}
}
IEnumerator color(){
{
GetComponent<SpriteRenderer> ().color = red;
yield return new WaitForSeconds(0.3f);
GetComponent<SpriteRenderer> ().color = white;
yield return new WaitForSeconds(0.3f);
}
}
void OnCollisionEnter2D (Collision2D coll) {
if(coll.gameObject.tag == "charger" && damagebreak == false){
damagebreak = true;
health -= 2.5f;
}
}
}
This is still not good.
You are calling the coroutine if 'colorchange' is true.
You are setting 'colorchange' to true once you collide with "charger" (collide > damagebreak = true > colorchange = true > coroutine called)
Then you are waiting for some time before turning 'colorchange' off.
During that time, the coroutine is called multiple times.
Also, your code is written without proper na$$anonymous$$g for the fields, it makes it very hard to read.
$$anonymous$$y next comment will contain the solution.
Seems correct, not sure why it's not working (did not try this myself).
Can you explain a bit more about how you want things to work?
I don't understand why you need it in update anyway...
You can just call the coroutine in the OnCollision....