Unity飞行AI追逐正常,触发避障时出现抖动问题求助
Unity飞行AI避障时抖动问题修复方案
开发Unity飞行AI时,单纯追逐目标功能正常,但添加避障系统后,触发避障时AI出现明显抖动。通过调试确认,抖动根源是AI在追逐状态和避障状态之间频繁切换。
原代码问题分析
- 无状态切换缓冲:每帧通过
Physics.SphereCast检测障碍,某帧未检测到就立即切回追逐,导致状态在两帧间反复跳转。 - 避障方向计算不合理:
Vector3.Cross(hit.point, hit.normal)生成的避让方向未结合原追逐路径,且未做归一化,导致移动方向突变。 - 移动方式生硬:直接使用
Vector3.MoveTowards设置位置,两种状态的移动方向没有平滑过渡,加剧抖动。
修复方案及修改后代码
通过添加状态缓冲、优化避障方向计算、实现平滑移动过渡来解决问题:
using Cinemachine; using UnityEngine; public class EnemyNew : MonoBehaviour { [Header("Settings")] public int HP; public float speed; public float detectionRadius; public int gunsCount; public Vector3 stoppingDistance; public LayerMask obstacleLayer; [Tooltip("连续检测到障碍的帧数阈值,达到后才触发避障")] public int obstacleDetectThreshold = 2; [Tooltip("连续未检测到障碍的帧数阈值,达到后才切回追逐")] public int obstacleClearThreshold = 3; [Tooltip("避障方向与原追逐方向的混合权重,0=完全追逐,1=完全避障")] public float avoidanceWeight = 0.7f; [HideInInspector] public bool alive; [HideInInspector] public float distance; [Header("Components")] public Rocket target; private AudioSource audioSource; // 状态缓冲相关变量 private int obstacleDetectCount = 0; private bool isAvoiding = false; void Start() { alive = true; audioSource = GetComponent<AudioSource>(); } void FixedUpdate() { if (!alive || !target?.isAlive ?? false) return; distance = Vector3.Distance(transform.position, target.transform.position); if (distance > 100) return; Vector3 chaseDirection = (target.transform.position + stoppingDistance - transform.position).normalized; bool obstacleDetected = Physics.SphereCast(transform.position, transform.localScale.magnitude, chaseDirection, out RaycastHit hit, detectionRadius, obstacleLayer); // 状态缓冲逻辑,避免单帧误判导致状态跳变 if (obstacleDetected) { obstacleDetectCount++; if (obstacleDetectCount >= obstacleDetectThreshold) { isAvoiding = true; } } else { obstacleDetectCount--; if (obstacleDetectCount <= 0) { isAvoiding = false; obstacleDetectCount = 0; } } Vector3 moveDirection = chaseDirection; if (isAvoiding) { // 计算优化后的避障方向:垂直于障碍法线,且尽量贴合原追逐路径 Vector3 obstacleNormal = hit.normal.normalized; Vector3 avoidanceDirection = Vector3.Cross(chaseDirection, obstacleNormal).normalized; // 混合追逐与避障方向,实现平滑过渡 moveDirection = Vector3.Lerp(chaseDirection, avoidanceDirection, avoidanceWeight).normalized; Debug.Log("Avoiding"); } else { Debug.Log("Chasing"); } // 平滑移动,避免生硬跳转 transform.position += moveDirection * speed * Time.deltaTime; // 可选:让AI朝向移动方向,增强飞行自然感 transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(moveDirection), Time.deltaTime * 5f); } }
关键修改点说明
- 状态缓冲机制:通过
obstacleDetectCount计数,只有连续检测到障碍达到阈值才进入避障状态,连续未检测到达到阈值才切回追逐,彻底解决状态频繁切换问题。 - 优化避障方向:基于原追逐方向和障碍法线计算避让路径,确保AI避障时尽量保持原有飞行轨迹,同时通过权重混合实现方向平滑过渡。
- 平滑移动逻辑:直接通过方向向量累加位置,配合旋转平滑,替代原有的
Vector3.MoveTowards生硬移动方式,消除抖动感。
内容的提问来源于stack exchange,提问作者kotan4ik
相关产品推荐
相关产品推荐

