- IconBase: 修复(N)后缀车辆名翻译, 添加OnDestroy取消订阅防止MissingReference - AnserWindowCtrl: 添加LanguageChanged订阅, 障碍提示实时翻译 - PlanningPlaneCtrl: 修复路径检查Count<0改为<1, 允许单段路径 - CarAIExtendCtrl: 空wayPoints数组防护 - GameObjectCreater: 重复key用索引赋值替代Add - NetHelper: 优先返回10.x/192.168.x局域网IP, 跳过WSL虚拟网卡 - 海岛/沙漠/丘陵: Terrain Layer设为Floor(8), NavigationStatic - 沙漠: TerrainLayer smoothness设为0 - 新增本地化条目: 携带装备/搭载人员/装备名称/空袭/维修厂等
179 lines
5.7 KiB
C#
179 lines
5.7 KiB
C#
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<UnityEngine.AI.NavMeshAgent>();
|
|
carAIControl = this.GetComponent<CarAIControl>();
|
|
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 (wayPoints == null || wayPoints.Length == 0) return;
|
|
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,
|
|
}
|