Unity游戏对象链状跟随玩家异常:围堵玩家问题修复咨询
修复链状队伍跟随问题
问题根源
- 每个鸡对象的
ChickenManager都维护独立的chickenList,无法统一管理全局队列顺序 chickenOrder变量从未被正确赋值,所有鸡默认都是0号,导致全部扎堆跟随玩家的同一目标点- 碰撞触发逻辑错误,每个鸡只往自己的列表添加自身,没有全局的队列注册机制
修复方案
- 改用全局单例管理队列:创建全局队伍管理器,统一维护所有加入队列的鸡对象,避免每个鸡各自维护列表
- 正确分配队列顺序:当鸡被玩家触碰时,由全局管理器分配唯一的
chickenOrder,确保每个鸡明确自己在队列中的位置 - 调整跟随目标计算:每个鸡的跟随目标设为队列前一个对象的"身后"固定偏移(基于前对象的朝向),避免重叠扎堆
修改后的代码实现
1. 全局队伍管理器(新增)
public class ChickenQueueManager : MonoBehaviour { public static ChickenQueueManager Instance; public List<GameObject> chickenQueue = new List<GameObject>(); public float followOffset = 0.5f; // 队列中每个对象的间距 private void Awake() { if (Instance == null) Instance = this; else Destroy(gameObject); } // 加入队列,返回该鸡的顺序编号 public int AddToQueue(GameObject chicken) { chickenQueue.Add(chicken); return chickenQueue.Count - 1; } // 获取前一个队列对象 public GameObject GetPreviousChicken(int currentOrder) { if (currentOrder <= 0) return null; // 0号直接跟随玩家 return chickenQueue[currentOrder - 1]; } }
2. 修改后的ChickenManager脚本
public class ChickenManager : MonoBehaviour { Transform player; bool shouldFollow; int chickenOrder; [SerializeField] NavMeshAgent navMeshAgent; float followOffset; void Start() { player = GameObject.FindGameObjectWithTag("Player").transform; navMeshAgent = GetComponent<NavMeshAgent>(); followOffset = ChickenQueueManager.Instance.followOffset; // 给导航代理设置停止距离,避免过度贴近目标 navMeshAgent.stoppingDistance = followOffset * 0.3f; } void Update() { if (shouldFollow) FollowTarget(); } private void OnCollisionEnter(Collision collision) { if (collision.gameObject.CompareTag("Player") && !shouldFollow) { // 由全局管理器分配队列顺序 chickenOrder = ChickenQueueManager.Instance.AddToQueue(gameObject); shouldFollow = true; } } void FollowTarget() { Vector3 targetPosition; if (chickenOrder == 0) { // 0号鸡跟随玩家身后偏移位置 targetPosition = player.position - player.forward * followOffset; } else { GameObject previousChicken = ChickenQueueManager.Instance.GetPreviousChicken(chickenOrder); if (previousChicken != null) { // 跟随前一个鸡的身后偏移位置 targetPosition = previousChicken.transform.position - previousChicken.transform.forward * followOffset; } else { // 异常情况 fallback 到玩家位置 targetPosition = player.position - player.forward * followOffset; } } navMeshAgent.SetDestination(targetPosition); // 让鸡朝向移动方向 if (navMeshAgent.velocity.magnitude > 0.1f) { transform.rotation = Quaternion.LookRotation(navMeshAgent.velocity.normalized); } } }
额外优化建议
- 可以添加队列移除逻辑(比如鸡离开玩家范围时从队列中移除)
- 根据游戏场景调整
followOffset和stoppingDistance的值,优化队列疏密程度 - 给鸡添加动画状态切换,让跟随动作更自然
内容的提问来源于stack exchange,提问作者Tuan Do
相关产品推荐
相关产品推荐

