首页 > 解决方案 > 为什么我的 Button 在 Unity 中没有获得正确的 Onclick 事件?

问题描述

我已经在 Unity 中为我的游戏实现了状态模式。因此我有一个主类(BattleSystem),它从调用不同的状态开始。这些状态之一是 AttackState。AttackState 有一个 attackButton,它是一个 UI 按钮(使用 UnityEngine.UI)。

我的 State 类如下所示:

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;
    }    
}

我的 StateMachine 类如下所示:

public abstract class StateMachine : MonoBehaviour
{
    protected State state;

    public void SetState(State state) {
        this.state = state;
        state.OnStateEnter();
    }
}

Button 在 BattleSystem 类中,如下所示:

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

我将 AttackButton 对象拖到 Unity 编辑器的检查器中的 attackButton 字段上。

我的 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;
    }
}

有趣的是,它的Debug.Log(battleSystem.attackButton.gameObject.name);作品并给了我游戏对象的名字。该事件尚未注册。我错过了什么?

我的场景图片:

场景

编辑:我发现这段代码有效:

btn.onClick.AddListener(() => Debug.Log("Test"));

把方法放在里面不行吗?这里发生了什么:D

标签: c#unity3d

解决方案


推荐阅读