You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

回合制战斗系统脚本中alreadyChosen变量未全局重置问题求助

问题分析与解决方案

核心问题根源

  • isPlayerTurn 和 actionsMade 是静态变量,所有脚本实例共享同一值,因此重置时所有角色都会同步感知到状态变化。
  • alreadyChosen 是非静态变量,每个玩家角色脚本都拥有独立的副本。当某一个角色实例触发 actionsMade >=3 的重置逻辑时,只会重置自身的 alreadyChosen,其他角色的该变量仍保持原有值,导致后续回合逻辑混乱。
  • 若将 alreadyChosen 设为静态,所有角色会共享这个状态,一旦某角色将其设为 true,所有角色都会无法再触发选择逻辑,最终只能执行一次行动。

解决方案一:使用集中式战斗管理器(推荐)

创建一个单例模式的战斗管理器,统一管理所有回合相关的状态变量,避免多实例状态不一致的问题。

1. 编写战斗管理器脚本

public class BattleManager : MonoBehaviour
{
    public static BattleManager Instance;

    // 统一管理回合状态变量
    public bool isPlayerTurn = true;
    public int actionsMade = 0;
    public bool alreadyChosen = false;
    public bool characterChosen = false;

    private void Awake()
    {
        // 单例初始化,确保全局唯一实例
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }
    }

    // 封装回合重置逻辑
    public void ResetPlayerTurn()
    {
        isPlayerTurn = false;
        actionsMade = 0;
        alreadyChosen = false;
        characterChosen = false;
    }
}

2. 修改角色脚本的 OnMouseDown 方法

将所有状态变量替换为战斗管理器的实例变量:

private void OnMouseDown()
{
    var battleManager = BattleManager.Instance;
    if(inBattle == true && battleStart == true)
    {
        if (renderer.tag == "Player" && isStunned == true)
        {
            print(renderer.transform.name + " is stunned!");
            battleManager.alreadyChosen = true;
        }
        if (renderer.tag == "Player" && !battleManager.alreadyChosen && battleManager.isPlayerTurn && !isStunned)
        {
            print(renderer.transform.name);
            battleManager.characterChosen = true;
            battleManager.alreadyChosen = true;
        }
        else if (renderer.tag == "Player" && battleManager.characterChosen)
        {
            print("Thanks");
            battleManager.characterChosen = false;
            battleManager.alreadyChosen = true;
            battleManager.actionsMade++;
        }
        if (renderer.tag == "Enemy" && battleManager.characterChosen)
        {
            print("Hit!");
            battleManager.characterChosen = false;
            battleManager.actionsMade++;
        }
        if (battleManager.actionsMade >= 3)
        {
            battleManager.ResetPlayerTurn();
        }
    }
}

解决方案二:遍历所有玩家实例重置状态

若不想引入管理器,可在回合结束时遍历所有玩家角色,统一重置 alreadyChosen:

private void OnMouseDown()
{
    if(inBattle == true && battleStart == true)
    {
        // 原有逻辑保持不变...
        
        if (actionsMade >= 3)
        {
            isPlayerTurn = false;
            actionsMade = 0;
            // 遍历所有玩家角色脚本,重置alreadyChosen
            foreach(var player in FindObjectsOfType<YourCharacterScript>())
            {
                if(player.renderer.tag == "Player")
                {
                    player.alreadyChosen = false;
                }
            }
        }
    }
}

注意:需将 alreadyChosen 设为 public,或添加公开的 setter 方法;FindObjectsOfType 性能较低,若场景中对象较多不推荐使用。

内容的提问来源于stack exchange,提问作者TylerGaming101

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 04:44:57