Unity GameManager脚本开发问题:如何实现按顺序完成目标的犯规判定
Unity顺序完成目标GameManager实现方案
前置准备
- 所有目标GameObject挂载
Target脚本,在Inspector面板按从小到大要求设置order字段值(1~5) - 目标Tag统一设置为
TargetBall
完整实现代码
目标标识脚本Target.cs
public class Target : MonoBehaviour { // 手动配置当前目标的顺序编号,按要求从小到大设置1、2、3、4、5 public int order; // 标记当前目标是否已完成 public bool isCompleted = false; }
游戏管理器脚本GameManager.cs
using UnityEngine; using System.Linq; public class GameManager : MonoBehaviour { // 单例实例,方便其他脚本调用管理器逻辑 public static GameManager Instance; // 当前需要完成的最小序号目标 private Target currentValidTarget; // 所有场景内的目标列表 private Target[] allTargets; // 剩余未完成目标数量 private int leftTargetCount; // 是否全部完成 private bool isAllCompleted = false; // 是否触发犯规 private bool isFoul = false; void Awake() { // 单例初始化 if (Instance == null) { Instance = this; } else { Destroy(gameObject); } } void Start() { // 加载场景内所有目标并按顺序排序 allTargets = GameObject.FindGameObjectsWithTag("TargetBall") .Select(go => go.GetComponent<Target>()) .OrderBy(t => t.order) .ToArray(); leftTargetCount = allTargets.Length; // 初始化第一个可操作目标 if (leftTargetCount > 0) { currentValidTarget = allTargets.First(t => !t.isCompleted); // 标识当前可操作目标,可自定义高亮逻辑 MarkCurrentValidTarget(); } } /// <summary> /// 外部调用:校验玩家操作的目标是否合法 /// </summary> /// <param name="operatedTarget">玩家操作的目标组件</param> /// <returns>操作是否合法</returns> public bool CheckTargetOperate(Target operatedTarget) { // 游戏已结束或已犯规直接返回不合法 if (isAllCompleted || isFoul) return false; // 操作的不是当前允许的最小目标,判定犯规 if (operatedTarget.order != currentValidTarget.order) { isFoul = true; // 可在此补充自定义犯规逻辑,比如弹出提示、游戏失败、扣分等 Debug.Log("犯规:未按顺序操作目标"); return false; } // 操作合法,标记目标完成 operatedTarget.isCompleted = true; leftTargetCount--; // 刷新下一个可操作目标 RefreshCurrentValidTarget(); return true; } /// <summary> /// 刷新当前可操作的最小目标 /// </summary> void RefreshCurrentValidTarget() { if (leftTargetCount == 0) { isAllCompleted = true; EndGame(); return; } currentValidTarget = allTargets.First(t => !t.isCompleted); // 更新目标标识 MarkCurrentValidTarget(); } /// <summary> /// 标识当前可操作的目标,可自定义高亮逻辑 /// </summary> void MarkCurrentValidTarget() { // 示例:将当前可操作目标设为红色,其他未完成目标设为白色 foreach (var target in allTargets) { if(target.isCompleted) continue; var render = target.GetComponent<Renderer>(); if (render != null) { render.material.color = target == currentValidTarget ? Color.red : Color.white; } } } /// <summary> /// 游戏结束逻辑 /// </summary> void EndGame() { Debug.Log("所有目标已按顺序完成"); } void OnGUI() { if (isFoul) { GUI.Label(new Rect(0, 0, 300, 20), "操作犯规!未按顺序完成目标"); return; } if (isAllCompleted) { GUI.Label(new Rect(0, 0, 200, 20), "所有目标已完成"); } else { GUI.Label(new Rect(0, 0, 300, 20), $"剩余目标数量:{leftTargetCount},当前需完成序号:{currentValidTarget.order}"); } } }
调用说明
在玩家操作目标的逻辑(比如点击、碰撞触发目标)中,获取目标上的Target组件,调用GameManager.Instance.CheckTargetOperate(目标组件)即可自动完成合法性校验、状态更新。如果返回值为true表示操作合法,可执行对应的目标完成表现(比如销毁、隐藏目标)。
内容的提问来源于stack exchange,提问作者evolltn
相关产品推荐
相关产品推荐

