如何在3D井字棋中以生成指定数量游戏对象为获胜条件
3D井字棋“生成指定数量对象”获胜条件实现思路
问题背景
开发3D井字棋游戏,点击触发OnMouseDown()时在网格位置生成名为cell的游戏对象,不使用UI及已有基础预制体,需实现“生成一定数量游戏对象”作为获胜条件,曾考虑寻路但不确定是否适用,求可行实现思路。
核心实现思路
1. 给生成的对象标记归属
每个生成的cell必须明确属于哪个玩家,避免统计混乱:
- 可以用标签区分(比如玩家1的cell用
Player1_Cell,玩家2的用Player2_Cell); - 也可以给cell附加一个极简脚本(比如
CellOwner),存储玩家ID(如public int ownerId;),比标签更灵活。
2. 实时维护玩家的有效对象计数
不要只在Start()里统计一次,每次生成或销毁cell时同步更新对应玩家的计数:
// 示例:用变量分别统计两个玩家的有效cell数量 private int player1Count = 0; private int player2Count = 0; // 生成玩家1的cell时调用 void SpawnPlayer1Cell(Vector3 spawnPos) { GameObject newCell = Instantiate(cell, spawnPos, Quaternion.identity); newCell.tag = "Player1_Cell"; player1Count++; CheckWin(); // 生成后立刻检查是否获胜 } // 销毁cell时同步更新计数(可在cell的OnDestroy里触发) void UpdateCountOnDestroy(string cellTag) { if (cellTag == "Player1_Cell") player1Count--; else if (cellTag == "Player2_Cell") player2Count--; }
3. 定义阈值并检查获胜条件
先确定获胜所需的对象数量(比如设为winThreshold = 4),每次计数更新后检查:
public int winThreshold = 4; // 自定义获胜所需的对象数量 void CheckWin() { if (player1Count >= winThreshold) { Debug.Log("玩家1获胜!"); EndGame(); } else if (player2Count >= winThreshold) { Debug.Log("玩家2获胜!"); EndGame(); } } void EndGame() { // 终止游戏逻辑,比如禁用所有点击交互 enabled = false; // 不用UI的话,可以用3D文本、音效等方式提示获胜 }
4. 修正现有代码的问题
你当前的代码存在几个影响逻辑的问题:
OnMouseDown()方法不能带参数(Unity的该回调是无参的),否则无法触发;DestroyGameObject()里生成cell后立刻销毁,会导致计数不准确,需调整生成与销毁的时机;- 要区分玩家1和玩家2的cell,避免同时生成
cell和negCell后又销毁的混乱逻辑。
关于寻路的说明
寻路完全不适合这个场景,它是用来计算移动路径的,和“统计对象数量判断获胜”的需求无关,不用考虑这种方案。
原代码参考
using System.Collections; using System.Collections.Generic; using UnityEngine; using TMPro; using UnityEngine.SceneManagement; public class Cell : MonoBehaviour { public GameObject cell; public GameObject negCell; public GameObject alter; public Transform transPos; [SerializeField] private bool isTapped = false; private int counted; public int gameObjectCount; void Start() { gameObjectCount = GameObject.FindGameObjectsWithTag("Cell1").Length; } void Update() { } public void OnMouseDown(int counted) //click and point to create and deestroy objects { counted = gameObjectCount; isTapped = true; transPos = alter.transform; Instantiate(cell, transform.position, Quaternion.identity); StartCoroutine(WaitForObject()); Debug.Log("Alter Destroyed!"); gameObjectCount++; DestroyGameObject(); return; } IEnumerator WaitForObject() { if (isTapped == true) { Instantiate(negCell, -transform.position, Quaternion.identity); isTapped = false; } yield return new WaitForSeconds(3f); DestroyGameObject(); } void DestroyGameObject() { if(gameObject == alter) { DestroyImmediate(alter, true); } else { DestroyImmediate(cell, true); } } }
内容的提问来源于stack exchange,提问作者Jesse Gober
相关产品推荐
相关产品推荐

