#Event System (Scriptable Object) with multiplayer

1 messages · Page 1 of 1 (latest)

daring bay
#

Bank.cs

public class Bank : MonoBehaviour
{
    [Header("Events")]
    [SerializeField]
    public GameEvent onOpenBankChanged;
    void Update() {
        if(Input.GetKeyDown(KeyCode.Space)) {
            Debug.Log("Player: " + this);
            OpenBank(this);
        }
    }

    public void OpenBank(Component sender) {
        Debug.Log("Bank opened by: " + sender.gameObject.name);
         // THIS SHOWS THE BANK (cube)
        if(onOpenBankChanged != null) {
            onOpenBankChanged.Raise(sender);
        }
        
    }
}

GameEvents.cs

[CreateAssetMenu(fileName = "GameEvent", menuName = "Events/Game Event")]
public class GameEvent : ScriptableObject
{
    private readonly List<IGameEventListener> m_eventListeners = new List<IGameEventListener>();

    public void Raise(Component sender) {
        foreach(var listener in m_eventListeners) {
            listener.OnEventRaised(sender);
        }
    }

    public void RegisterListener(IGameEventListener listener) {
        if(!m_eventListeners.Contains(listener)) 
            m_eventListeners.Add(listener);
    }

    public void UnregisterListener(IGameEventListener listener) {
        if(m_eventListeners.Contains(listener))
            m_eventListeners.Remove(listener);
    }
}

And GameEventListener:

public class GameEventListener : MonoBehaviour, IGameEventListener {
    [Tooltip("Game event to listen to")]
    [SerializeField] private GameEvent @event;

    [Tooltip("Response to invoke when Event is raised")]
    [SerializeField] private UnityEvent response;

    public void OnEnable() {
        if(@event != null) @event.RegisterListener(this);
    }

    public void OnDisable() {
        @event.UnregisterListener(this);
    }

    public void OnEventRaised(Component sender) {
        response?.Invoke();
    }
}
#

I instance player when they press play (currently singleplayer, but I will reference the player in a better way later):
PlayerSpawnerController:

public class PlayerSpawnController : MonoBehaviour
{
    public GameObject _playerPrefab;
    // Start is called before the first frame update
    void Start()
    {
        if (Player.Instance == null && _playerPrefab != null)
    {
        // If no player instance exists and there's a prefab, instantiate the player
        GameObject playerObject = Instantiate(_playerPrefab, new Vector3(0, 1, 0), Quaternion.identity);
    }
    else
    {
        // If a player instance already exists or no prefab is set, do nothing
        Debug.LogWarning("Player instance already exists or player prefab is not set.");
    }
        

    }

    // Update is called once per frame
    void Update()
    {

    }
}
#

And the PlayerController contains a navmesh agent and other stuff that makes input work. It's a null object with a name and a camera that follows the player.

#

So the question is: When the "Player" presses "Space" it will say that the command has been triggered by "Cube" (which in this case is the bank)
Do I need to change my logic here to make it work or should I use some other kind of event based system to make this... work?

#

So sender == cube is my understanding. But can I somehow fetch the player that has made the command.. Or do I need to add like some other logic here?
There's a null object that contains the event listener that is "global" in the scene that takes care of all the commands being made.

#

Event System (Scriptable Object) with multiplayer

gentle tulip
daring bay
#

The "Client" player prefab in this case.

gentle tulip
#

Well, how is your "bank" gonna know that?

#

I mean, if it's in networking context, you probably have some way to get the local player, but that would depend on the specific networking framework.

daring bay
#

Started reading about Netcode for Unity, maybe that's the best start 🥲

gentle tulip
#

Unless you implement it yourself

#

To be honest, with this kind of questions I wouldn't recommend starting with networking yet