Reference same object with different tags

fss25

I'm currently developing a game where I have 3 types of enemies (Common, Elite and Boss which I'm using tags to define the type). Since I want to give different characteristics and spawning rate to every enemy type, I've been struggling finding a way better to call All enemies instead of calling with tags.

Like:

 bool enemyIsAlive()
    {
        if (GameObject.FindGameObjectWithTag("Common") == null)
        {
            return false;
        }

        return true;
    }

Here I'm trying to check if there's any enemy in the scene but I can't find a way to reference all enemies. I tried with "Find" but picks the name and the enemies gonna have different names since I can't use the same name for all.

Anyone can help me?

Arron Burch

Avoiding using Unity's GameObject Find functions is usually a good thing in the long run for game performance. When handling multiple enemies in a game, I tend to sway towards using a manager class that will be responsible for tracking the spawning and despawning of the enemies and then be used as the source of checking if an enemy is still alive.

For example, lets say you have a simple enemy class that can be either a Common, Elite or Boss. By putting this class onto an object (your enemy) in your hierarchy you can use the type field to say what type this enemy is, and then create a prefab of that enemy to spawn in at runtime.

using UnityEngine;

public class Enemy : MonoBehaviour
{
    public Type type;

    public enum Type
    {
        COMMON,
        ELITE,
        BOSS
    }

    private void OnEnable()
    {
        EnemySpawned();
    }

    private void OnDisable()
    {
        EnemyDied();
    }

    public void EnemySpawned()
    {
        Debug.Log("Enemy Spawned: " + type);
        EnemyManager.RegisterEnemy(this);
    }

    public void EnemyDied()
    {
        Debug.Log("Enemy Died: " + type);
        EnemyManager.UnregisterEnemy(this);
    }
}

You can see that when an enemy spawns EnemySpawned() is called which uses an EnemyManager to register itself so that it can keep track of it. The same happens when the enemy dies EnemyDied() is called which then tells the EnemyManager to unregister that enemy.

Here is the EnemyManager class:

using System.Collections.Generic;

public class EnemyManager
{
    private static Dictionary<Enemy.Type, int> enemies;

    public static void RegisterEnemy(Enemy enemy)
    {
        if (enemies == null)
        {
            enemies = new Dictionary<Enemy.Type, int>();
        }

        if (enemies.ContainsKey(enemy.type))
        {
            enemies[enemy.type] += 1;
        }
        else
        {
            enemies.Add(enemy.type, 1);
        }
    }

    public static void UnregisterEnemy(Enemy enemy)
    {
        if (enemies == null || !enemies.ContainsKey(enemy.type))
        {
            return;
        }

        enemies[enemy.type] -= 1;
    }

    public static bool IsEnemyTypeAlive(Enemy.Type enemyType)
    {
        return enemies != null && enemies.ContainsKey(enemyType) && enemies[enemyType] > 0;
    }
}

This does not need to be added to an object in the scene hierarchy as it uses static fields and functions.

As you can see the EnemyManager will keep a Dictionary of the enemy types and how many of those enemies are registered. (You could also keep a reference to the Enemy class itself instead of just a count so you could later access those enemies through the EnemyManager too, but for simplicities sake, we will just keep a count)

When an Enemy is registered the count is incremented and when an Enemy is unregistered the count is decremented.

We can then use this to see if enemies are still alive by their type, by checking if the dictionary has firstly had anything registered, then if the dictionary has had that specific enemy type registered, and finally if there are still any registered enemies of that type as they may have all been unregistered.

Here is a demo class then of how that check could be used:

using UnityEngine;

public class Demo : MonoBehaviour
{
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Q))
        {
            Debug.Log("Common Enemy Alive: " + IsCommonEnemyAlive());
        }

        if (Input.GetKeyDown(KeyCode.W))
        {
            Debug.Log("Elite Enemy Alive: " + IsEliteEnemyAlive());
        }

        if (Input.GetKeyDown(KeyCode.E))
        {
            Debug.Log("Boss Enemy Alive: " + IsBossEnemyAlive());
        }
    }

    public bool IsCommonEnemyAlive()
    {
        return EnemyManager.IsEnemyTypeAlive(Enemy.Type.COMMON);
    }

    public bool IsEliteEnemyAlive()
    {
        return EnemyManager.IsEnemyTypeAlive(Enemy.Type.ELITE);
    }

    public bool IsBossEnemyAlive()
    {
        return EnemyManager.IsEnemyTypeAlive(Enemy.Type.BOSS);
    }
}

It may seem more complicated, but this solution will scale a lot better than using the GameObject find functions especially if you need to check if the enemies exist often.

To take it even further you could look into System.Action delegates and events to decouple the enemies and the EnemyManager even further and simply raise events when enemies are spawned or die.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Reference to object not same as the object?

From Dev

Hibernate: generate different (unique) IDs for same object reference in a list

From Dev

Different object and reference

From Dev

Pass object by reference to a different object

From Dev

Reference a different column in that same table

From Dev

Same object in different classes?

From Dev

Different types of the same object

From Dev

Calling method from different class in same library, errors about object reference

From Dev

Using the same Reference for a new object

From Dev

Parsing xml with same tags and different attributes

From Dev

Universal reference producing different instances with the same address

From Dev

How to reference a class in a different package in the same project

From Dev

Storing same object in different arrays

From Dev

Same object property with different values

From Dev

Using same object in different packages

From Dev

how to toggle the same object for different object?

From Dev

Design pattern - different object in, same object returned

From Dev

how to toggle the same object for different object?

From Dev

Same object in one case, different object in another?

From Dev

Get reference of a function located in the same object

From Dev

Unity how to reference an object from a different one

From Dev

Share object reference between different JUnit tests

From Dev

Calling a method and passing an object reference and catching the return with same reference

From Dev

How is Java parameter reference and original reference (not object) the same?

From Dev

Dealing with different html tags in the same item field with scrapy

From Dev

Multiple <form> tags in different locations with the same target iframe?

From Dev

How to declare several stylable attributes with the same name for different tags?

From Dev

Is there a way to differentiate between tags of the same name fetched from different remotes?

From Dev

JAXB Unmarshalling with outer and inner tags having same name and different attributes

Related Related

  1. 1

    Reference to object not same as the object?

  2. 2

    Hibernate: generate different (unique) IDs for same object reference in a list

  3. 3

    Different object and reference

  4. 4

    Pass object by reference to a different object

  5. 5

    Reference a different column in that same table

  6. 6

    Same object in different classes?

  7. 7

    Different types of the same object

  8. 8

    Calling method from different class in same library, errors about object reference

  9. 9

    Using the same Reference for a new object

  10. 10

    Parsing xml with same tags and different attributes

  11. 11

    Universal reference producing different instances with the same address

  12. 12

    How to reference a class in a different package in the same project

  13. 13

    Storing same object in different arrays

  14. 14

    Same object property with different values

  15. 15

    Using same object in different packages

  16. 16

    how to toggle the same object for different object?

  17. 17

    Design pattern - different object in, same object returned

  18. 18

    how to toggle the same object for different object?

  19. 19

    Same object in one case, different object in another?

  20. 20

    Get reference of a function located in the same object

  21. 21

    Unity how to reference an object from a different one

  22. 22

    Share object reference between different JUnit tests

  23. 23

    Calling a method and passing an object reference and catching the return with same reference

  24. 24

    How is Java parameter reference and original reference (not object) the same?

  25. 25

    Dealing with different html tags in the same item field with scrapy

  26. 26

    Multiple <form> tags in different locations with the same target iframe?

  27. 27

    How to declare several stylable attributes with the same name for different tags?

  28. 28

    Is there a way to differentiate between tags of the same name fetched from different remotes?

  29. 29

    JAXB Unmarshalling with outer and inner tags having same name and different attributes

HotTag

Archive