Particle effects skipping health left

so heres a doozy.

I implemented the particle system and decided to try and use two different effects, one for when the enemy is hit and it still has health, and one for when it is hit and has no health. To do this I used a boolean which I then set in the explosioneffects script.

however it seems that ive missed something, as when the hit take method plays, it automatically destroys the object even if the object’s health is set to more than 1. I’ve included my scripts below. Is anyone able to double check for me please? I’m sure i’ve done it right, but if ive missed something id like to know!

Explode Effects Script

{
    [SerializeField] ParticleSystem ShieldedHit;
    [SerializeField] ParticleSystem DeathHit;


    public void PlayHitEffect(bool killer)
    {
        if (!killer)
        {
            ParticleSystem instance = Instantiate(ShieldedHit, transform.position, Quaternion.identity);
            Destroy(instance.gameObject, instance.main.duration+instance.main.startLifetime.constantMax);
        }
        else
        {
            ParticleSystem instance = Instantiate(DeathHit, transform.position, Quaternion.identity);
            Destroy(instance.gameObject, instance.main.duration+instance.main.startLifetime.constantMax);
        }
    }
    

} 

Health script

{
    [SerializeField] int health = 2;
    [SerializeField] ExplodeEffects effects;

    private void Start()
    {
        effects = GetComponent<ExplodeEffects>();
        
    }

    public void HurtUnit(int damageTaken)
    {
        if (!IsDead())
        {
            effects.PlayHitEffect(false);
            health -= damageTaken;
            Debug.Log($"Oww {gameObject.name} took {damageTaken} damage!");
            
            if (IsDead())
            {
                health = 0;
                effects.PlayHitEffect(true);
                KillUnit();
            }
            else
            {

            }
        }
        else
            effects.PlayHitEffect(false);
            KillUnit();
        
    }

    public bool IsDead()
    {
        return health <= 0;
    }

    public void KillUnit()
    {
        GameObject.Destroy(gameObject);
        Debug.Log("Oww I Am DEAD!");
    }

}

Anyone have any ideas? Much appreciated!

Hi,

It’s great to see that you are challenging yourself. :slight_smile:

however it seems that ive missed something, as when the hit take method plays, it automatically destroys the object even if the object’s health is set to more than 1.

What do the Debug.Log messages reveal what’s going on at runtime?

Also, depending on where you put the particle systems, it might be that they get destroyed along with the enemy. Destroyed particle systems cannot emit any particles. Obviously. That’s something you could check.

1 Like

The problem is here. You are missing curly braces so KillUnit() will always execute when HurtUnit() is called. Only effects.PlayHitEffect(false) is part of the else here. This is what your code actually looks like

public void HurtUnit(int damageTaken)
{
    if (!IsDead())
    {
        effects.PlayHitEffect(false);
        health -= damageTaken;
        Debug.Log($"Oww {gameObject.name} took {damageTaken} damage!");
        
        if (IsDead())
        {
            health = 0;
            effects.PlayHitEffect(true);
            KillUnit();
        }
        else
        {

        }
    }
    else
    {
        effects.PlayHitEffect(false);
    }
    KillUnit();
}

Edit
Here’s a note. Take it. Leave it. It doesn’t matter. It’s just something for future you;

  1. Always try to write less code. The less code you have, the less places there are that can break
  2. Reuse code that’s the same. Later, when you need to change something, it’s easier (and less error prone) to change one place than to try and find all the places that you used the same code.
  3. It’s more natural to check a condition than it’s opposite

I thought of these things when I saw your PlayHitEffect() method. All three things applied to it could look something like this

public void PlayHitEffect(bool killer)
{
    ParticleSystem prefab = ShieldedHit;
    if (killer)
    {
        prefab = DeathHit;
    }
    Instantiate(prefab, transform.position, Quaternion.identity);
}

Here we just define which prefab to instantiate and then instantiate it. Note that I have removed the Destroy part, too. You don’t really need it. Particle systems can destroy themselves when they are done. You just need to set it on the particle system itself.
image
This will let the particle play, and then it will destroy itself when it is done

2 Likes

Thank you very much! Its always good to have another set of eyes go over your code. I must have looked at that else statement about 20 times trying to figure out the problem, and I just didn’t notice the {} were not there!

I have sorted it now. I had a look at the shortened code you supplied aswell, and it makes a lot of sense. I may well change things around a bit! thank you again.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms