Boat Attack使用了Universal RP的许多新图形功能,可以用于探索 Universal RP 的使用方式和技巧。
您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

128 行
3.4 KiB

using BoatAttack;
using System.Collections;
using System.Collections.Generic;
using Unity.Entities;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.AI;
class PathData
{
public Vector3[] pathPoints;
public int currentPathPoint;
public WaypointGroup.Waypoint currentWaypoint;
public bool foundPath;
public bool nearEnd;
public Vector3 storedPosition;
};
public class AIController_DOTS : MonoBehaviour
{
static AIController_DOTS main;
public float nearDistanceSquared = 8f;
Dictionary<Entity, PathData> paths;
private void Awake()
{
if (main != null && main != this)
{
Destroy(this);
return;
}
main = this;
paths = new Dictionary<Entity, PathData>();
}
private void Update()
{
foreach (var path in paths)
{
if (path.Value.nearEnd || !path.Value.foundPath)
CalculatePath(path.Value);
}
}
public static void Register(Entity entity, Vector3 pos)
{
if (main.paths.ContainsKey(entity))
return;
PathData data = new PathData();
data.currentWaypoint = WaypointGroup.instance.GetClosestWaypoint(pos);
data.storedPosition = pos;
data.nearEnd = true;
main.paths.Add(entity, data);
}
public static void GetInputs(Entity entity, float3 pos, quaternion rot, out float throttle, out float steering)
{
main.GetInputsInternal(entity, pos, rot, out throttle, out steering);
}
void GetInputsInternal(Entity entity, float3 pos, quaternion rot, out float throttle, out float steering)
{
throttle = steering = 0;
//Do we have data?
PathData data;
if (!paths.TryGetValue(entity, out data) || data.pathPoints == null)
return;
data.storedPosition = pos; //Store position for navmesh calculations
if (data.currentPathPoint < data.pathPoints.Length && data.foundPath)
{
//Get angle to the destination and the side
Vector3 normDir = data.pathPoints[data.currentPathPoint] - (Vector3)pos;
normDir = normDir.normalized;
var forward = math.forward(rot);
float dot = Vector3.Dot(normDir, forward);
//float angle = Mathf.Acos (dot) * Mathf.Rad2Deg;
float targetSide = Vector3.Cross(forward, normDir).y;//positive on right side, negative on left side
steering = Mathf.Clamp(targetSide, -1.0f, 1.0f);
throttle = dot > 0 ? 1f : 0.25f;
if (Vector3.Distance(pos, data.pathPoints[data.currentPathPoint]) < nearDistanceSquared) // If we are close to the current point on the path get the next
{
//Debug.Log($"Distance: {Vector3.Distance(pos, data.pathPoints[data.currentPathPoint])} SqrMag: {(data.storedPosition - data.pathPoints[data.currentPathPoint]).sqrMagnitude}");
data.currentPathPoint++; // Move on to next point
if (data.currentPathPoint >= data.pathPoints.Length)
data.nearEnd = true;
}
}
}
void CalculatePath(PathData data)
{
var wp = WaypointGroup.instance.GetNextWaypoint(data.currentWaypoint);
var offset = (UnityEngine.Random.value * 2f - 1f) * wp.WPwidth * Vector3.left;
var curWPPos = wp.point + wp.rotation * offset;
var navPath = new NavMeshPath(); // New nav path
NavMesh.CalculatePath(data.storedPosition, curWPPos, 255, navPath);
if (navPath.status == NavMeshPathStatus.PathComplete) // if the path is good(complete) use it
{
data.currentWaypoint = wp;
data.pathPoints = navPath.corners;
data.currentPathPoint = 1;
data.foundPath = true;
data.nearEnd = false;
}
else if (navPath == null || navPath.status == NavMeshPathStatus.PathInvalid) // if the path is bad, we havent found a path
{
data.foundPath = false;
}
}
}