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

Question Triggering Event affect all prefabs instances

Discussion in 'Scripting' started by Multik_ID, Feb 25, 2023.

  1. Multik_ID

    Multik_ID

    Joined:
    Dec 1, 2021
    Posts:
    3
    Hi, guys! I am new in C# and Unity3D and I'm struggle using events so I need HELP.
    So I'm making hypercasual game to improve my skills. In the game I want if player hits an item to different things happened. For example: triggering bomb collider will destroy the bomb and play explosive animation, triggering dollar — destroy it, play dollar animation, add score.
    PROBLEM !!! When Player hits bomb ALL bombs and money destroying and playing animation. I want to affect on every prafab independetly. I DON"T HAVE ANY STATIC FIELDS.



    I have classes Bomb and Money that are inherited from abstract class Item. (Bomb and Money differs only with methods, so I include only Bomb).

    In Item.cs I get refference to an event script.

    Code (CSharp):
    1. public abstract class Item : MonoBehaviour
    2. {
    3.     protected OnCollisionEvent _onCollisionEventScript;
    4.  
    5.     private void Awake()
    6.     {
    7.         _onCollisionEventScript = FindObjectOfType<OnCollisionEvent>();
    8.     }
    9.  
    10.     protected virtual void HandleAnimation() { }
    11.  
    12.     protected virtual void DestroyOnHitting() { }
    In Bomb.cs I subscribe it to an event.

    Code (CSharp):
    1. public class Bomb : Item
    2. {
    3.     private void OnEnable()
    4.     {
    5.         _onCollisionEventScript.InteractOnCollision += HandleAnimation;
    6.         _onCollisionEventScript.InteractOnCollision += DestroyOnHitting;
    7.     }
    8.  
    9.     private void OnDisable()
    10.     {
    11.         _onCollisionEventScript.InteractOnCollision -= HandleAnimation;
    12.         _onCollisionEventScript.InteractOnCollision -= DestroyOnHitting;
    13.     }
    14.  
    15.     protected override void HandleAnimation()
    16.     {
    17.         Debug.Log("EXPLOSION");
    18.     }
    19.  
    20.     protected override void DestroyOnHitting()
    21.     {
    22.         Destroy(gameObject);
    23.     }
    24. }
    In OnCollisionEvent.cs, which is attached to Player, I invoke the event in "voidOnTriggerEnter()"

    Code (CSharp):
    1. public class OnCollisionEvent : MonoBehaviour
    2. {
    3.     public event UnityAction InteractOnCollision;
    4.  
    5.     private void OnTriggerEnter(Collider other)
    6.     {
    7.         InteractOnCollision?.Invoke();
    8.     }
    9. }
    In SpawManager.cs I spawn random prefab from List of prefabs at fixed position along Xaxis and at random position along Yaxis

    Code (CSharp):
    1. public class SpawnManager : MonoBehaviour
    2. {
    3.     [SerializeField] private List<Item> ItemPrefabs;
    4.     [SerializeField] private float SpawnRepeatRate;
    5.  
    6.     private readonly List<Item> _items = new();
    7.     private float _time = 0f;
    8.  
    9.     private void Start()
    10.     {
    11.         foreach (var itemPrefab in ItemPrefabs)
    12.             _items.Add(itemPrefab);
    13.     }
    14.  
    15.     private void Update()
    16.     {
    17.         _time += Time.deltaTime;
    18.  
    19.         Item randomItem = _items[Random.Range(0, _items.Count)];
    20.  
    21.         if (_time >= SpawnRepeatRate)
    22.         {
    23.             Instantiate(randomItem, GetRandomSpawnPosition(), Quaternion.identity);
    24.  
    25.             _time = 0f;
    26.         }
    27.     }
    28.  
    29.     private Vector3 GetRandomSpawnPosition()
    30.     {
    31.         int[] CoordinatesOnY = new int[11];
    32.         CoordinatesOnY[0] = 2;
    33.  
    34.         for (int i = 1; i < CoordinatesOnY.Length; i++)
    35.             CoordinatesOnY[i] = CoordinatesOnY[i - 1] + 2;
    36.  
    37.         int randomSpawnPositionAlongY = Random.Range(CoordinatesOnY[0], CoordinatesOnY.Length);
    38.  
    39.         Vector3 spawnPosition = new Vector3(24f, randomSpawnPositionAlongY, 0f);
    40.  
    41.         return spawnPosition;
    42.     }
    43. }
    Is my mistake on using events and passing references or in implementing SpawnManager and passing references?
     
  2. TzuriTeshuba

    TzuriTeshuba

    Joined:
    Aug 6, 2019
    Posts:
    185
  3. Multik_ID

    Multik_ID

    Joined:
    Dec 1, 2021
    Posts:
    3
    Thank you for replying :)
    "OnCollisionEvent.cs" is attached to Player whereas "Item.cs" is abstract one and its child's attached to object "Bomb", so I can't use "GetComponent<OnCollisionEven>()" because it's attached to different object which is Player.

    I tried to use Singleton and it didn't work either.
     
  4. mopthrow

    mopthrow

    Joined:
    May 8, 2020
    Posts:
    343
    I'm not sure events are the best solution to this. Every Item subscribes to the collision event, so when the collision happens, every listening Item (all of them!) are destroyed. (Line 7 script 1)

    Events are powerful, but try to use them only when you need them or you risk overcomplicating something unnecessarily. In this case there is a more direct way to do what you want:

    In your OnTriggerEnter method, you can use other.gameObject and do whatever you want with the thing that was hit.

    Right now your OnTrigger function is on your player. This could grow to a long list of checks the more things the player could hit so it might be better to have the other object hold the Trigger function instead, then it can check if it was the player that hit them and explode themselves. Either that or give your hittables an IHittable interface and just check for that. If every hittable will always derive from Item, then you can use this to avoid a lot of checks too.
     
    Last edited: Feb 25, 2023
    Multik_ID likes this.
  5. Multik_ID

    Multik_ID

    Joined:
    Dec 1, 2021
    Posts:
    3
    Oooohhhh Now I see the cause.
    I kinda have just learned about events and wanted to try them out, but it seems I choose a wrong case.
    Thank you a lot for spotting. Now it's more clear for me :)
    And thanks for IHittable tip, I'll try it )
     
    mopthrow likes this.