How to make enemy 'flash' when hit?

I was wondering how I can make an enemy flash a grey or white colour when a bullet hits them? I have a health script called ‘EnemyHealth’ and a bullet script which interact with one another.

Here is my bullet script:

public class PlayerShooting : MonoBehaviour

{

 //Weapon Collider Script
  void OnTriggerEnter(Collider hit)
{
  if (hit.gameObject.tag == "Enemy")
  {
  hit.GetComponent<EnemyHealth>().TakeDamage (10);
  Destroy(gameObject);
  return;
  }
}

To start with, is this in 2d or 3d?

Its a side scrolling game but im making it in 3D.

Cool!

There’s a few ways you could go about this, but the easiest would be to go through your characters shader. If you were to add a property that changes the diffuse color, or maybe emission, then you could ‘animate’ that value from code when you take damage and make your character flash

Yeah a few people around the web have suggested this method to other people, but I couldn’t get any of them to work for me. I’ve only been using Unity for just over a week so I’m not very familiar with many of the commands and how they work.

1 Like

For a newbie I’ll admit that shader work can feel way advanced. Are you using unity’s standard shader?

Yes im just using the standard shader. Some of my enemies have multiple parts to their bodies, each with their own shader. Is this going to complicate things?

Nope, you can do it pretty easily :slight_smile: For the enemies with multiple materials, you’ll just have to iterate through them.

You can animate the colour variable in the Emission slot of the material to get the effect you want

Play around with it in the inspector to see what it does to your model. Once you have a colour that you would like for your flash effect, you can start coding it.

Here’s a pretty good place to start with the code

Post back here if you have any other questions :slight_smile:

OK thanks for that, I’ll take a look at that link and have a play with it. I assume the code I use needs to go in the same script that’s attached to the bullet?

Depends on how you want to do it really. I would add it to your character and enemy classes myself (bonus points if they both inherit from the same base class that manages health)

That way you can destroy your bullets the second they impact and still run your code that makes the characters flash

OK I added the code to the health script, but in the console it says error 'There is no ‘Renderer’ attached to the “UFO” game object, but a script is trying to access it.

The renderer is not part of the main body, the renderer is attach to a part of the enemy, as you can see here:

1 Like

UPDATE:

I changed GetComponent to GetComponentInChildren and with one of my enemies this now changes the renderer to a solid colour, but it stays that colour, it doesnt change back to normal between shots. Here is the exact script I now have:

public void TakeDamage(int amount)
  {
  // If the enemy is dead...
  if (isDead)
 
  return;
  
  // Reduce the current health by the amount of damage sustained.
  currentHealth -= amount;
  
  if (currentHealth > 0)

  {
  Renderer renderer = GetComponentInChildren<Renderer>();
  Material mat = renderer.material;

  float emission = Mathf.PingPong(Time.time, 1.0f);
  Color baseColor = Color.yellow; //Replace this with whatever you want for your base color at emission level '1'

  Color finalColor = baseColor * Mathf.LinearToGammaSpace(emission);

  mat.SetColor("_EmissionColor", finalColor);
  }
  
  // If the current health is less than or equal to zero...
  if (currentHealth <= 0)
  {
  // ... the enemy is dead.
  Death();
  }
  }

This code still wont work for my ‘UFO’ enemy though.

I’m guessing that this TakeDamage() function is only called the frame that the enemy actually gets hit, right?

You need something that will keep getting called every frame, until the end of the flash effect.

Checkout Coroutines :wink:

Seems like you have a lot to learn, but you’ll be happy you learned it all. Coroutines are especially useful to get a handle on

The problem is I can’t use Coroutines or invokes or anything like that because of the way my script is set up. This is the section that links to the bullet script:

public void TakeDamage(int amount)
  {
  // If the enemy is dead...
  if (isDead)
  // ... no need to take damage so exit the function.

  return;
   
  // Reduce the current health by the amount of damage sustained.
  currentHealth -= amount;
   
  if (currentHealth > 0)

  {

  //code needs to go here
   
  }
  
  // If the current health is less than or equal to zero...
  if (currentHealth <= 0)
  {
  // ... the enemy is dead.
  Death();
  }
  }

So the code needs to go here part of the script tells the game if the enemy takes damaged and if(currentHealth > 0) then do something. All I have had success with so far is using Instantiate to create a small particle effect to signify the enemy is being hit.

This actually works OK for regular enemies, but if I have a larger boss enemy its not so convincing, plus when he is finally destroyed he will need to flash numerous times before disappearing in a fireball.

I don’t see why you can’t use coroutines with the above code. Just define a coroutine function somewhere in the class like this:

IEnumerator FlashCoroutine()
{
    float duration = 1f;
    while(duration > 0)
    {
        duration -= Time.deltaTime;

        // flashing code goes here

        return null;
    }
}

Then after the return statement in the TakeDamage function, add:

StopCoroutine("FlashCoroutine");
StartCoroutine("FlashCoroutine");
2 Likes