WACK-A-MOLE QUEST: ‘Gotcha’ - Solutions

Quest: Wack-A-Mole Quest
Challenge: Gotcha

Feel free to share your solutions, ideas and creations below. If you get stuck, you can find some ideas here for completing this challenge.

Alright, I believe I barely got this working with minimal speghetti code. I’m interested to see what everyone else came up with. I started by duplicating the Celebration Particle System, unpacking it and tweaking it a bit. Once that was done I duplicated it once for each enemy, but didn’t make them children of the enemy GameObject.

public class Exploder : MonoBehaviour
{

    [SerializeField] private ParticleSystem capture;

	private void OnTriggerEnter(Collider other)
    {
        if (other.tag.Equals("Player"))
		{
            capture.transform.position = this.transform.GetChild(0).gameObject.transform.position;
            capture.Play();
            print("Aww, you got me ");
            Destroy(gameObject);
        }
    }
}

I wanted to only use one particle system and just reuse it for each enemy, but after .Play() it was disabled and I couldn’t figure out how to reset it. So I took the easy way out here and just duplicated it and kept it outside the GameObject to avoid issues with Destroy().

The second issue I ran into was the positioning. It turns out the box we see is the child GameObject known as Body and I had to do some quick googling to figure out how to call the child so I could position the explosion correctly.

Again, I think I’d like to make the particle effect a child to the body, but I couldn’t figure out how to get the effect to play and still destroy() the enemy.

This is my jank :slight_smile:

My solution was similar. I duplicated the selebration particle system, as I have no idea how to create a decent one. Shrunk it down to 0.1 on x/y/z and made it a prefab variant. I added it to the enemy prefab and instantiate it at the player’s location. Probably should have just made it part of the player, so it would look like a power up from killing the enemy.

    [SerializeField] GameObject killEffect;

    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Player"))
        {
            print("Aww, you got me");
            var killObject = Instantiate(killEffect);
            var particle = killObject.GetComponent<ParticleSystem>();
            particle.transform.position = other.transform.position;
            Destroy(particle, particle.main.duration);
            Destroy(gameObject);
        }
    }

This took me quite some time but I think I figured it out.
Not sure if it’s the right or a good way, but it works.

    ParticleSystem explosion;    
    [SerializeField] MeshRenderer meshRenderer;

    private void OnTriggerEnter(Collider other)
    {        
        explosion = GetComponentInChildren<ParticleSystem>();
        explosion.Play();        
        meshRenderer.enabled = false;        
        Destroy(gameObject, 1f);         
    }

I dragged the body of the enemy into the Meshrenderer SerializeField.

2 Likes

I found the cleanest solution was to instantiate a FX prefab at the body postion

Care if you leave the enemy around too long as you may double capture them

I placed the particle system on the enemy prefab, so if I destroy it too soon the particle won’t display.
that’s why I let the cube live for 1 second.
I might be able to fix it by also disabling the box collider.

But thanks for the reply, I wouldn’t have figured that out myself :slight_smile:

For this one, I created a resource folder and dropped a particle system into it. Once I had my effect I modified the Exploder class

    private void OnTriggerEnter(Collider other)
    {
        if(other.tag == "Player")
        {
            print("Aww, you got me");
            InstantiateParticles();
            Destroy(gameObject);
        }
    }

    void InstantiateParticles()
    {
        Vector3 enemyPosition = transform.GetChild(0).transform.position;
        Vector3 position = new Vector3(enemyPosition.x, 0.5f, enemyPosition.z);

        GameObject particles  = Instantiate(Resources.Load("Catch Particles"), position, Quaternion.identity) as GameObject;
        ParticleSystem catchParticles = particles.GetComponent<ParticleSystem>();
        catchParticles.Play();
        Destroy(particles, 2f);
    }
1 Like

Created a particle system as a child of the body object within the “TheEnemy” prefab, so it would move with it as it animates. I have a death delay so the effect will play before it gets destroyed.

As well, I disable the animator component so it won’t continue to move and take the particle system along with it.

public class Exploder : MonoBehaviour
{
    [SerializeField] ParticleSystem captureEffect;
    private float deathDelay = 0.5f;

    private void OnTriggerEnter(Collider other)
    {
        gameObject.GetComponent<Animator>().enabled = false;
        captureEffect.Play();
        Destroy(gameObject, deathDelay);
    }
}
  1. Create a ParticleSystem and turn it into a Prefab.
  2. Modify the Exploder class with a SerializedField for the ParticleSystem, and add two lines of code: one to instantiate the particles and one to destroy them after one evolution.
public class Exploder : MonoBehaviour
{
    [SerializeField] ParticleSystem explosionEffect;

    private void OnTriggerEnter(Collider other)
    {
        print("Aww, you got me");

        ParticleSystem instance = Instantiate(explosionEffect, other.transform.position, Quaternion.identity);
        Destroy(instance.gameObject, instance.main.duration);

        Destroy(gameObject);
    }
}

One final recommendation, because making particle effects is a thankless, time consuming task. There is a free asset from Unity Technologies called “Unity Particle Pack.” It has about 50 different particles from explosions to lightning to plasma to steam. They are all exceptional.

1 Like

I have made the ParticleSystem a component rather than a separate game object. This removed any problems with position or being destroyed. Happy with result.

Here is my solution. Just attach the Particle system in the Exploder.cs and everything will work okay.

public class Exploder : MonoBehaviour
{
    [SerializeField] private GameObject captureParticleSystem;
    private void OnTriggerEnter(Collider other)
    {
        print("Aww, you got me");
        Instantiate(captureParticleSystem, transform.position, Quaternion.Euler(-90f,0f,0f));
        Destroy(gameObject);         
    }
}

Privacy & Terms