Home > Back-end >  Does an EventSystem need to be attached to a GameObject in order to work?
Does an EventSystem need to be attached to a GameObject in order to work?

Time:08-31

Ok so here is my EventSystem script

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

public class EventSystem : MonoBehaviour
{
    public static EventSystem instance;
    public event Action onDead;
    public event Action onScore;

    // Start is called before the first frame update
    void Awake()
    {
        instance = this;
    }

    // Update is called once per frame
    public void onDeadTrigger()
    {
        if (onDead != null) { onDead(); }

    }
    public void onScoreTrigger()
    {
        if (onScore != null) { onScore(); }

    }
}

I think because it isn't related to a GameObject ( it doesn't have to be attached to a GameObject in order to work ). Then if EventSystem doesn't inherit from MonoBehaviour, will this make any difference? and in addition, can we use Scriptable Object ?

And another small question that isn't related to the title but I'm a little bit confused about this.

I'm in the process of making Flappy Bird clone, when the bird touches the empty space between the pipes ( the trigger area ) then he scores a point. Which script should I invoke the Event ( the bird script or the score script attached to the trigger ) When the bird enters the trigger area both OnTriggerEnter2D will be called on both scripts so if I don't organize this well, my code will become spaghetti

CodePudding user response:

Suggestions:

In your case you don't need to inherit it from monoBehavior you can simply make class static and then you won't event need an instance of it so basically what I mean to say is make your class something like this:


using System;

public static class EventSystem {

    public static event Action OnDead;
    public static event Action OnScore;

    public static void OnDeadTrigger() => OnDead?.Invoke();

    public static void OnScoreTrigger() => OnScore?.Invoke();

    public static void ResetEvents() {
      
       OnDead = null;
       OnScore = null;
    }

}

So then you simply call it like this in any of your monobehaviours (or any where)



using UnityEngine;
using System;

public class CollisionHandler : MonoBehavior {

    private void OnCollisionEnter( collision other ) {
       
        if( other.gameObject.CompareTag( "coin" ) ) {

            EventSystem.OnScoreTrigger();
            EventSystem.ResetEvents();
        }
    }
}

using UnityEngine;
using System;

public class ScoreManager : MonoBehavior {

    public int score;

    private void Start() {
       
         EventSystem.OnScore  = OnScoreChanged;
    }

    private void OnScoreChanged() {

         score  ;
    }
}

Note: nullifying the static variables is sometimes important because they are not a components so they might not distroy or nullify their instance on scene reload so it sometimes through a null reference error just beware of that anyways...

Hope it helps... Happy coding :)

CodePudding user response:

If you do not require an object to be a component, you could do one of the following:

Create a ScriptableObject instance. The object is still part of the Unity lifecycle and can be customized via serialization, but is essentially just "an asset" and not a component on a prefab that needs to be spawned first.

If you do not need any communication with Unity (no serialization, no access via inspector, etc.) you can simply create a good 'ol class without inheritance. You can make it static or create a static instance (similar to what you did in Awake).

  • Related