Event catch mistake

This class invokes the event.

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

public class SpecialTurn : BattleState
{

    public static event StateAction onEnterSpecial;
    public static event StateAction onExitSpecial;

    public override void EnterState()
    {
        if (onEnterSpecial != null)
        {
            StartCoroutine(timer());
            onEnterSpecial.Invoke();
            Debug.Log("Timerdan önce");
        }
    }

    public override void ExitState()
    {
        onExitSpecial?.Invoke();
    }

    public override void updateState()
    {
        throw new System.NotImplementedException();
    }

    public IEnumerator timer()
    {
        for (float time = 10; time >= 0; time -= Time.deltaTime)
        {
            //Add UI some timer component
            //Timer.setTime(time);
            Debug.Log("Time : " + time);
            yield return null;
        }
        ExitState();
    }
}

This class receives the onEnterSpecial event

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

public class PlayAreaHandler : MonoBehaviour
{
    private void OnEnable()
    {
        SpecialTurn.onEnterSpecial += enableEnemyTurnCardArea;
        SpecialTurn.onExitSpecial += disableEnemyTurnCardArea;
    }

    private void OnDisable()
    {
        SpecialTurn.onEnterSpecial -= enableEnemyTurnCardArea;
        SpecialTurn.onExitSpecial -= disableEnemyTurnCardArea;
    }

    public void enableEnemyTurnCardArea()
    {
        enemyTurnBox.SetActive(true);
    }

    public void disableEnemyTurnCardArea()
    {
        Debug.Log("Play area içindeyim");
        enemyTurnBox.SetActive(false);
    }
}

onSpecialEnter successfully invokes another class but does not invoke this. Do you have any idea why this happens?

Perhaps because of EnterState only starting the coroutine when an event is assigned. Whether this is the cause or not, it’s simply bad practice. Do not branch code based on whether someone other script is currently subscribed to an event, this causes the event subscription to have side-effects.

Use it like so:

    public override void EnterState()
    {
            StartCoroutine(timer());
            onEnterSpecial?.Invoke();
            Debug.Log("Timerdan önce");
    }

And you should be using non-static events since SpecialTurn doesn’t have the same lifetime as the events which may continue to be subscribed to when changing the scene, for example. It will also not support multiple instances of SpecialTurn.

1 Like

Firstly, thanks for your reply. We will fix that bad practice part that you mentioned.
Secondly, another class that also uses invoke of onEnterSpecial works fine but the enableEnemyTurnCardArea method of PlayerAreaHandler which also uses the same event does not work. Do you have any idea why this happens?

No idea. Did you try debugging? You can quickly find out whether and in what order the event is subscribed to / unsubscribed from, and invoked.

1 Like