Why does my Button not get the Onclick event?

I have implemented the state pattern for my game in Unity.
Thus I have a main class (BattleSystem) which starts by calling different states.
One of those states is the AttackState. The AttackState has an attackButton which is an UI Button (using UnityEngine.UI).

My State class looks like this:

   public abstract class State : MonoBehaviour
    {
        protected BattleSystem battleSystem;
 
        public abstract void Tick();
 
        public virtual void OnStateEnter() { }
        public virtual void OnStateExit() { }
 
        public State(BattleSystem battleSystem) {
            this.battleSystem = battleSystem;
        } 
    }

My StateMachine class looks like this:

    public abstract class StateMachine : MonoBehaviour
    {
        protected State state;
 
        public void SetState(State state) {
            this.state = state;
            state.OnStateEnter();
        }
    }

The Button is in the BattleSystem class like this:

   public class BattleSystem : StateMachine
    {
        public Button attackButton;
     // Start is called before the first frame update
    void Start()
    {
        SetState(new AttackState(this));
    }

I dragged the AttackButton object onto my attackButton field in the inspector in the Unity editor.

My AttackState.cs:

 using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
 
    public class AttackState : State
    {
 
        public AttackState(BattleSystem battleSystem) : base(battleSystem)
        {
 
        }
 
        public override void Tick()
        {
         
        }
 
        public override void OnStateEnter()
        {
         
 
            Debug.Log("AttackState");
            battleSystem.attackButton.onClick.AddListener(delegate () { this.Attack(); });
            Debug.Log(battleSystem.attackButton.gameObject.name);
 
        }
 
        public void Attack() {
            Debug.Log("Attacking");
            foreach (Transform child in battleSystem.cardDropZone.transform)
            {
                Card card = (Card)child.GetComponent("Card");
 
                // inflict damage to opponent equal to attack of cards 
                if (battleSystem.canDamageBeInflicted(card))
                {
                    battleSystem.inflictDamage(card);
                    // adjust crystalCount
                    TurnUtilities.crystalCount -= card.crystalCost;
 
                    // Move card to graveyard after it has been used
                    battleSystem.sendToGraveyard(child);
 
                    battleSystem.attackButton.GetComponentInChildren<Text>().text = "End Turn";
 
                }
                else
                {
                    Debug.Log("not enough crystals");
                }
            }
 
            if (PlayerIsDead())
            {
                battleSystem.isPlayerDead = true;
                battleSystem.SetState(new GameEndingState(battleSystem));
            }
            if (EnemyIsDead())
            {
                battleSystem.isEnemyDead = true;
                battleSystem.SetState(new GameEndingState(battleSystem));
            }
        }
 
 
        bool PlayerIsDead()
        {
 
            if (battleSystem.playerHealthbar.value <= 0)
            {
                return true;
            }
 
            return false;
 
        }
 
 
        bool EnemyIsDead()
        {
            if (battleSystem.enemyHealthbar.value <= 0)
            {
                return true;
            }
 
            return false;
        }
    }

The funny thing is that the Debug.Log(battleSystem.attackButton.gameObject.name); works and gives me the name of the GameObject. The event is not being registered though. What did I miss?

P.S.:
The button is getting highlighted when I go over it. The name of the Button is getting printed on the console. Really don’t know what I am doing wrong…

Picture of my Scene:

I read your whole post and nowhere do I see mention of adding an OnClick listener to the button. Maybe I missed something?

It is in the AttackState.cs OnStateEnter Method? :smile: