回合制战斗系统脚本中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
相关产品推荐
相关产品推荐

