Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Resolved How to access multipe instances of a script from another one?

Discussion in 'Scripting' started by DarkSaulo, Oct 27, 2022.

  1. DarkSaulo

    DarkSaulo

    Joined:
    Nov 10, 2020
    Posts:
    7
    The problem I am facing is that I have 4 enemies that use the same script to manage their AI, but for each one, variables like health, speed, damage and others will change depending on the enemy.
    What happens is that, when I try to reference these scripts, the Player script only gets the first one created, and with that, if the first enemy created deals 20 damage, others will do the same amount even if in their code it is 10, 5 or other.
    When I do the opposite there is no real problem because each enemy detects its own health agains player damage, but with the player that doesn't happen.

    I don't know if there is another way to reference a script into another when there are multiple instances of that one or how to fix it.

    Code (CSharp):
    1. public class PlayerStateMachine : MonoBehaviour
    2. {
    3.     private float _health = 100f;
    4.     EnemyStateMachine _enemy;
    5.  
    6.     void Awake()
    7.     {
    8.         _enemy = FindObjectOfType<EnemyStateMachine>();
    9.     }
    10.  
    11.     private void OnTriggerEnter(Collider other)
    12.     {
    13.         if (other.gameObject.tag == "Enemy1 Sword")
    14.         {
    15.             _health -= _enemy.Damage;
    16.         }
    17.         if (other.gameObject.tag == "Enemy2 Sword")
    18.         {
    19.             _health -= _enemy.Damage;
    20.         }
    21.         if (other.gameObject.tag == "Enemy3 Dagger")
    22.         {
    23.             _health -= _enemy.Damage;
    24.         }
    25.         if (other.gameObject.tag == "Enemy4 Sword")
    26.         {
    27.             _health -= _enemy.Damage;
    28.         }
    29.     }
    30. }
    What I need is the player to detect each enemy damage individually, even if they use the same script.
    Each enemy prefab has it's own enemy script that is a copy from another but with different numbers on its variables.
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    6,003
    Code (CSharp):
    1.     void Awake()
    2.     {
    3.         _enemy = FindObjectOfType<EnemyStateMachine>();
    4.     }
    This will only ever find the first instance in your scene hierarchy.

    You want to get the instance of the component in your OnTriggerEnter instead. So use GetComponent/TryGetComponent.

    Code (CSharp):
    1. private void OnTriggerEnter(Collider other)
    2. {
    3.     if (other.TryGetComponent(out EnemyStateMachine enemy))
    4.     {
    5.         _health -= enemy.Damage;
    6.     }
    7. }
     
  3. DarkSaulo

    DarkSaulo

    Joined:
    Nov 10, 2020
    Posts:
    7
    I found the solution, I just needed to delete FindObjectOfType and add a GetComponentInParent on the TriggerEnter.

    Code (CSharp):
    1. public class PlayerStateMachine : MonoBehaviour
    2. {
    3.     private float _health = 100f;
    4.     EnemyStateMachine _enemy;
    5.  
    6.     void Awake()
    7.     {
    8.      
    9.     }
    10.  
    11.     private void OnTriggerEnter(Collider other)
    12.     {
    13.         _enemy = other.GetComponentInParent<EnemyStateMachine>();
    14.  
    15.         if (other.gameObject.tag == "Enemy1 Sword")
    16.         {
    17.             _health -= _enemy.Damage;
    18.         }
    19.         if (other.gameObject.tag == "Enemy2 Sword")
    20.         {
    21.             _health -= _enemy.Damage;
    22.         }
    23.         if (other.gameObject.tag == "Enemy3 Dagger")
    24.         {
    25.             _health -= _enemy.Damage;
    26.         }
    27.         if (other.gameObject.tag == "Enemy4 Sword")
    28.         {
    29.             _health -= _enemy.Damage;
    30.         }
    31.     }
    32. }
     
  4. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    6,003
    At that point you don't need if statements at all any more either.

    And is the component actually on the parent of the collider? It would be better if you had it on the same object and used TryGetComponent instead.
     
    DarkSaulo likes this.
  5. DarkSaulo

    DarkSaulo

    Joined:
    Nov 10, 2020
    Posts:
    7
    You are right, the other if statements are not needed anymore, thank you.