Script doesn't work on duplicates.

So, i wanted to make an zombie survival game with infinite waves and i have made an attack system where if i enter an certain collider on the enemy, it will play its attack animation and it’s hitbox will be activated. Now the problem is that when i duplicate the enemy the script or function (not sure) only works on the main enemy, not the copy. And whenever i destroy the “main” enemy i get an error leading to the attack area script. The prefab is exactly the same and i used the instantiate function. If you don’t understand my problem yet, take a look at this video i made :

As you can see whenever i enter any of the duplicates “attack area” the animation only plays on the main prefab.

Here is the Attack Area script:

using System.Collections.Generic;
using UnityEngine;

public class AttackArea : MonoBehaviour {


    Animator animator;
    DetectHit detectHit;

    Collider collider;

    void Start ()
    {
        animator = GameObject.FindGameObjectWithTag ("Enemy").GetComponent<Animator> ();
        detectHit = GameObject.FindGameObjectWithTag ("Hitbox").GetComponent<DetectHit> ();

        collider = GetComponent<Collider> ();
   
    }
   
    void Update ()
    {
       
    }


    void OnTriggerEnter(Collider collider)
    {

        detectHit.enabled = true;

        if (collider.tag == "Player")
        {
            detectHit.enabled = true;
            animator.SetBool ("isAttacking", true);
            animator.SetBool ("isWalking", false);
            animator.SetBool ("isDead", false);
        }
    }

    void OnTriggerExit (Collider col)
    {
        if (col.tag == "Player")
        {
            detectHit.enabled = false;

            animator.SetBool ("isAttacking", false);
            animator.SetBool ("isWalking", true);
            animator.SetBool ("isDead", false);
        }
    }

}

Any kind of help will be appreciated, thank you.

When you find the object with tag, it returns 1 object. Just 1.
If the enemy and areas are duplicated, you should make those variables specific (local) for the script, and look them up with GetComponent in start. That way they’re cached and refer to that specific enemy/hitbox/whatever.

To add a tiny bit to the already good answer above, a lot of functions have singular and plural versions, so check out this:

FindGameObjectsWithTag: Unity - Scripting API: GameObject.FindGameObjectsWithTag

You will need to iterate through the objects found (And also put them in a collection of some sort), but that’s described in the link.

Sorry, yes, I should have included that in my answer. I was going to be, but kinda forgot. Those are good to know about, but if the script is supposed to work how I imagine it is, the local ones (variables) will be preferable. These look like they’re on the enemy, so you wouldn’t want to find a list of enemies or hitboxes (I imagine) :slight_smile:

1 Like

Could you show an example of some sort, i’m not sure if i understand and do i have to do this in the attackarea script or the spawner script or both of them.

Finding objects with tag is going to lead you in circles. It’s always going to give you a global list of all of them, which means you’re going to have to do a hell of a lot of work to figure out which is the right one.

The tag system is a bit of a dead end in the long run anyway, since you can only have one tag per object. If you use the tag system for more than one purpose, they’re eventually going to collide, and you’ll have to rewrite it anyway.

Instead, you can use GetComponentInChildren() or GetComponentInParent(), which will crawl down or up the hierarchy respectively to find that component in the object.

You can also just make the objects public and drag in the reference in the inspector.

1 Like