Unity C#井字棋游戏changeMove状态切换失败问题求助
问题根源分析
你当前的核心问题是每个方块实例都拥有独立的changeMove私有字段:因为每个可点击方块都挂载了PutMove脚本,而PutMove继承自LogicOfGame,所以每个方块对象会单独初始化一份private bool changeMove。第一次点击方块A时,它自己的changeMove变为true,但点击方块B时,方块B的changeMove还是默认的false,自然只会执行放置X的逻辑,无法进入O的分支。
修复方案
以下两种方案都能解决全局回合状态共享的问题,按需选择:
方案一:使用静态字段共享回合状态
直接将changeMove改为静态字段,让所有方块实例共享同一个状态变量:
修改LogicOfGame.cs:
public class LogicOfGame : MonoBehaviour { public SpriteRenderer place; // 改为静态字段,全局共享回合状态 private static bool changeMove; public Image X; public Image O; public void ChangeMove() { // 先判断是否已放置棋子,避免重复操作 if (place.sprite != null) return; if (!changeMove) { place.sprite = X.sprite; } else { place.sprite = O.sprite; } // 无论放X还是O,最后切换回合状态 changeMove = !changeMove; } }
PutMove.cs保持不变:
public class PutMove : LogicOfGame { private void OnMouseDown() { ChangeMove(); } }
方案二:使用单例模式分离逻辑与交互
更符合Unity开发规范的做法是将游戏逻辑抽成全局单例管理类,避免每个方块都继承逻辑类:
- 创建一个空物体命名为
GameManager,挂载LogicOfGame脚本 - 修改
LogicOfGame.cs为单例管理类:
public class LogicOfGame : MonoBehaviour { // 全局单例实例 public static LogicOfGame Instance; public Image X; public Image O; private bool changeMove; void Awake() { // 确保全局只有一个逻辑实例 if (Instance == null) { Instance = this; } else { Destroy(gameObject); } } // 接收方块的SpriteRenderer作为参数,执行放置逻辑 public void PlacePiece(SpriteRenderer targetPlace) { if (targetPlace.sprite != null) return; targetPlace.sprite = !changeMove ? X.sprite : O.sprite; changeMove = !changeMove; } }
- 修改
PutMove.cs,不再继承逻辑类,直接调用单例方法:
public class PutMove : MonoBehaviour { private SpriteRenderer place; void Awake() { // 获取当前方块的SpriteRenderer组件 place = GetComponent<SpriteRenderer>(); } private void OnMouseDown() { LogicOfGame.Instance.PlacePiece(place); } }
内容的提问来源于stack exchange,提问作者Hayk
相关产品推荐
相关产品推荐

