using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; using UnityStandardAssets.Vehicles.Car; using XFramework; // 基于NavMesh 扩展现有AI功能 public class CarAIExtendCtrl : MonoBehaviour { UnityEngine.AI.NavMeshAgent thisAgent; [SerializeField] private Transform target; CarAIControl carAIControl; [SerializeField] MoveType moveType; [SerializeField] Vector3[] wayPoints; int curentIndex; [SerializeField] public float fllowKeepDis = 100;//跟随时保持的距离 bool stopDriving=true; Vector3 initialPos; // Start is called before the first frame update void Awake() { thisAgent = this.transform.GetComponentInChildren(); carAIControl = this.GetComponent(); initialPos = thisAgent.transform.localPosition; //SetFllowTarget(target); // SetWayPoint(wayPoints); } //设置目标点位 此后本车辆按照跟随模式移动 public void SetFllowTarget(Transform transform) { moveType = MoveType.fllow; target = transform; stopDriving = false; } //设置路径点位 此后本车辆按照路径点循环移动 默认从第一个点位开始移动 也可设置单个点位 public void SetWayPoint(Vector3 [] postion,int startIndex=0) { moveType = MoveType.wayPoints; wayPoints = postion; curentIndex = startIndex; stopDriving = false; } //改变控制模式 停止移动 等待设置目标点或跟随物体 public void ChangeCtrlType(MoveType moveType) { this.moveType = moveType; StopAIMove(); } //暂停后恢复移动 public void StartAIMove() { stopDriving = false; } //暂停移动 public void StopAIMove() { stopDriving = true; carAIControl.StopMove(); } float timer = 0.2f; Vector3[] naveMeshPathPoints;//通过寻路组件计算获得的细节路径点 // Update is called once per frame void Update() { thisAgent.transform.localPosition = initialPos; thisAgent.transform.localRotation = Quaternion.identity; if (stopDriving) return;//暂停模式不在设置路点 timer -= Time.unscaledTime; if (timer > 0) return;//0.2f执行一次即可 节省一定的运算性能 timer = 0.2f; bool hasPath =false; NavMeshPath navMeshPath = new NavMeshPath(); if (thisAgent.isOnNavMesh) { switch (moveType) { case MoveType.fllow: hasPath = thisAgent.SetDestination(target.position); break; case MoveType.wayPoints: if (Vector3.Distance(this.transform.position, wayPoints[curentIndex]) < 3 && curentIndex < wayPoints.Length - 1) { curentIndex++; } hasPath = thisAgent.SetDestination(wayPoints[curentIndex]); break; default: break; } if (hasPath && thisAgent.path.corners.Length > 1) { naveMeshPathPoints = thisAgent.path.corners; } else { naveMeshPathPoints = null; } if (naveMeshPathPoints != null) { switch (moveType) { case MoveType.fllow://跟随模式计算路径距离 并保持跟随距离 float pathDistance = 0; for (int i = 0; i < naveMeshPathPoints.Length - 1; i++) { pathDistance += Vector3.Distance(naveMeshPathPoints[i], naveMeshPathPoints[i + 1]); } if (pathDistance > fllowKeepDis)//超出保持距离时 保持移动 MoveToPostion(naveMeshPathPoints[1]); else carAIControl.StopMove(); break; case MoveType.wayPoints://即将到达最后一个点位时 不在发送移动命令 避免因刹车制动过慢导致无法停车 if (Vector3.Distance(this.transform.position, wayPoints[wayPoints.Length - 1]) < 5) { if (!stopDriving) { StopAIMove(); Debug.Log("arrive points"); EventCenter.Instance.EventTrigger("ArriveDestination"); } } else MoveToPostion(naveMeshPathPoints[1]); break; default: break; } } // Debug.Log(tempDist); //Speed_Order = Mathf.Lerp(Min_Speed_Rate, Max_Speed_Rate, tempDist / 50.0f); // Slow down the speed within 50m. } else { thisAgent.Warp(this.transform.position); } } //给AI控制器设置移动目标点位 void MoveToPostion(Vector3 targetPos) { carAIControl.StartMove(targetPos); } private void OnEnable() { if (carAIControl) carAIControl.enabled = true; } private void OnDisable() { if (carAIControl) carAIControl.enabled = false; } } public enum MoveType { fllow, wayPoints, }