123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715 |
- using UnityEngine;
- using System.Collections;
- using System.Collections.Generic;
- namespace Pathfinding {
- using Pathfinding.Util;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [RequireComponent(typeof(Seeker))]
- [AddComponentMenu("Pathfinding/AI/AILerp (2D,3D)")]
- [HelpURL("http://arongranberg.com/astar/documentation/stable/class_pathfinding_1_1_a_i_lerp.php")]
- public class AILerp : VersionedMonoBehaviour, IAstarAI {
-
-
-
-
-
-
-
-
- public float repathRate {
- get {
- return this.autoRepath.period;
- }
- set {
- this.autoRepath.period = value;
- }
- }
-
-
-
-
- public bool canSearch {
- get {
- return this.autoRepath.mode != AutoRepathPolicy.Mode.Never;
- }
- set {
- this.autoRepath.mode = value ? AutoRepathPolicy.Mode.EveryNSeconds : AutoRepathPolicy.Mode.Never;
- }
- }
-
-
-
-
- public AutoRepathPolicy autoRepath = new AutoRepathPolicy();
-
- public bool canMove = true;
-
- public float speed = 3;
-
-
-
-
-
-
-
-
-
-
-
- [UnityEngine.Serialization.FormerlySerializedAs("rotationIn2D")]
- public OrientationMode orientation = OrientationMode.ZAxisForward;
-
-
-
-
-
- [System.Obsolete("Use orientation instead")]
- public bool rotationIn2D {
- get { return orientation == OrientationMode.YAxisForward; }
- set { orientation = value ? OrientationMode.YAxisForward : OrientationMode.ZAxisForward; }
- }
-
-
-
-
- public bool enableRotation = true;
-
- public float rotationSpeed = 10;
-
-
-
-
-
- public bool interpolatePathSwitches = true;
-
-
-
-
- public float switchPathInterpolationSpeed = 5;
-
- public bool reachedEndOfPath { get; private set; }
-
- public bool reachedDestination {
- get {
- if (!reachedEndOfPath || !interpolator.valid) return false;
-
- var dir = destination - interpolator.endPoint;
-
- if (orientation == OrientationMode.YAxisForward) dir.z = 0;
- else dir.y = 0;
-
-
- if (remainingDistance + dir.magnitude >= 0.05f) return false;
- return true;
- }
- }
- public Vector3 destination { get; set; }
-
-
-
-
-
-
-
-
- [System.NonSerialized]
- public bool updatePosition = true;
-
-
-
-
-
-
-
- [System.NonSerialized]
- public bool updateRotation = true;
-
-
-
-
-
-
-
-
-
- [System.Obsolete("Use the destination property or the AIDestinationSetter component instead")]
- public Transform target {
- get {
- var setter = GetComponent<AIDestinationSetter>();
- return setter != null ? setter.target : null;
- }
- set {
- targetCompatibility = null;
- var setter = GetComponent<AIDestinationSetter>();
- if (setter == null) setter = gameObject.AddComponent<AIDestinationSetter>();
- setter.target = value;
- destination = value != null ? value.position : new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
- }
- }
-
- public Vector3 position { get { return updatePosition ? tr.position : simulatedPosition; } }
-
- public Quaternion rotation {
- get { return updateRotation ? tr.rotation : simulatedRotation; }
- set {
- if (updateRotation) {
- tr.rotation = value;
- } else {
- simulatedRotation = value;
- }
- }
- }
- #region IAstarAI implementation
-
- void IAstarAI.Move (Vector3 deltaPosition) {
-
-
- }
-
- float IAstarAI.radius { get { return 0; } set {} }
-
- float IAstarAI.height { get { return 0; } set {} }
-
- float IAstarAI.maxSpeed { get { return speed; } set { speed = value; } }
-
- bool IAstarAI.canSearch { get { return canSearch; } set { canSearch = value; } }
-
- bool IAstarAI.canMove { get { return canMove; } set { canMove = value; } }
-
- public Vector3 velocity {
- get {
- return Time.deltaTime > 0.00001f ? (previousPosition1 - previousPosition2) / Time.deltaTime : Vector3.zero;
- }
- }
- Vector3 IAstarAI.desiredVelocity {
- get {
-
-
- return (this as IAstarAI).velocity;
- }
- }
-
- Vector3 IAstarAI.steeringTarget {
- get {
-
- return interpolator.valid ? interpolator.position + interpolator.tangent : simulatedPosition;
- }
- }
- #endregion
-
- public float remainingDistance {
- get {
- return Mathf.Max(interpolator.remainingDistance, 0);
- }
- set {
- interpolator.remainingDistance = Mathf.Max(value, 0);
- }
- }
-
- public bool hasPath {
- get {
- return interpolator.valid;
- }
- }
-
- public bool pathPending {
- get {
- return !canSearchAgain;
- }
- }
-
- public bool isStopped { get; set; }
-
- public System.Action onSearchPath { get; set; }
-
- protected Seeker seeker;
-
- protected Transform tr;
-
- protected ABPath path;
-
- protected bool canSearchAgain = true;
-
-
-
-
-
- protected Vector3 previousMovementOrigin;
- protected Vector3 previousMovementDirection;
-
-
-
-
- protected float pathSwitchInterpolationTime = 0;
- protected PathInterpolator interpolator = new PathInterpolator();
-
-
-
-
-
- bool startHasRun = false;
- Vector3 previousPosition1, previousPosition2, simulatedPosition;
- Quaternion simulatedRotation;
-
- [UnityEngine.Serialization.FormerlySerializedAs("target")][SerializeField][HideInInspector]
- Transform targetCompatibility;
- [SerializeField]
- [HideInInspector]
- [UnityEngine.Serialization.FormerlySerializedAs("repathRate")]
- float repathRateCompatibility = float.NaN;
- [SerializeField]
- [HideInInspector]
- [UnityEngine.Serialization.FormerlySerializedAs("canSearch")]
- bool canSearchCompability = false;
- protected AILerp () {
-
-
-
- destination = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
- }
-
-
-
-
- protected override void Awake () {
- base.Awake();
-
- tr = transform;
- seeker = GetComponent<Seeker>();
-
-
-
-
-
- seeker.startEndModifier.adjustStartPoint = () => simulatedPosition;
- }
-
-
-
-
-
-
- protected virtual void Start () {
- startHasRun = true;
- Init();
- }
-
- protected virtual void OnEnable () {
-
- seeker.pathCallback += OnPathComplete;
- Init();
- }
- void Init () {
- if (startHasRun) {
-
- Teleport(position, false);
- autoRepath.Reset();
- if (shouldRecalculatePath) SearchPath();
- }
- }
- public void OnDisable () {
- ClearPath();
-
- seeker.pathCallback -= OnPathComplete;
- }
-
- public void GetRemainingPath (List<Vector3> buffer, out bool stale) {
- buffer.Clear();
- if (!interpolator.valid) {
- buffer.Add(position);
- stale = true;
- return;
- }
- stale = false;
- interpolator.GetRemainingPath(buffer);
-
-
-
- buffer[0] = position;
- }
- public void Teleport (Vector3 position, bool clearPath = true) {
- if (clearPath) ClearPath();
- simulatedPosition = previousPosition1 = previousPosition2 = position;
- if (updatePosition) tr.position = position;
- reachedEndOfPath = false;
- if (clearPath) SearchPath();
- }
-
- protected virtual bool shouldRecalculatePath {
- get {
- return canSearchAgain && autoRepath.ShouldRecalculatePath(position, 0.0f, destination);
- }
- }
-
-
-
-
- [System.Obsolete("Use SearchPath instead")]
- public virtual void ForceSearchPath () {
- SearchPath();
- }
-
- public virtual void SearchPath () {
- if (float.IsPositiveInfinity(destination.x)) return;
- if (onSearchPath != null) onSearchPath();
-
- var currentPosition = GetFeetPosition();
-
-
-
- canSearchAgain = false;
-
-
- SetPath(ABPath.Construct(currentPosition, destination, null), false);
- }
-
-
-
-
-
-
-
- public virtual void OnTargetReached () {
- }
-
-
-
-
-
- protected virtual void OnPathComplete (Path _p) {
- ABPath p = _p as ABPath;
- if (p == null) throw new System.Exception("This function only handles ABPaths, do not use special path types");
- canSearchAgain = true;
-
-
- p.Claim(this);
-
-
- if (p.error) {
- p.Release(this);
- return;
- }
- if (interpolatePathSwitches) {
- ConfigurePathSwitchInterpolation();
- }
-
- var oldPath = path;
- path = p;
- reachedEndOfPath = false;
-
-
-
- if (path is RandomPath rpath) {
- destination = rpath.originalEndPoint;
- } else if (path is MultiTargetPath mpath) {
- destination = mpath.originalEndPoint;
- }
-
-
- if (path.vectorPath != null && path.vectorPath.Count == 1) {
- path.vectorPath.Insert(0, GetFeetPosition());
- }
-
- ConfigureNewPath();
-
-
-
-
-
- if (oldPath != null) oldPath.Release(this);
- if (interpolator.remainingDistance < 0.0001f && !reachedEndOfPath) {
- reachedEndOfPath = true;
- OnTargetReached();
- }
- }
-
-
-
-
-
-
-
-
- protected virtual void ClearPath () {
-
- if (seeker != null) seeker.CancelCurrentPathRequest();
- canSearchAgain = true;
- reachedEndOfPath = false;
-
- if (path != null) path.Release(this);
- path = null;
- interpolator.SetPath(null);
- }
-
- public void SetPath (Path path, bool updateDestinationFromPath = true) {
- if (updateDestinationFromPath && path is ABPath abPath && !(path is RandomPath)) {
- this.destination = abPath.originalEndPoint;
- }
- if (path == null) {
- ClearPath();
- } else if (path.PipelineState == PathState.Created) {
-
- canSearchAgain = false;
- seeker.CancelCurrentPathRequest();
- seeker.StartPath(path);
- autoRepath.DidRecalculatePath(destination);
- } else if (path.PipelineState == PathState.Returned) {
-
-
- if (seeker.GetCurrentPath() != path) seeker.CancelCurrentPathRequest();
- else throw new System.ArgumentException("If you calculate the path using seeker.StartPath then this script will pick up the calculated path anyway as it listens for all paths the Seeker finishes calculating. You should not call SetPath in that case.");
- OnPathComplete(path);
- } else {
-
- throw new System.ArgumentException("You must call the SetPath method with a path that either has been completely calculated or one whose path calculation has not been started at all. It looks like the path calculation for the path you tried to use has been started, but is not yet finished.");
- }
- }
- protected virtual void ConfigurePathSwitchInterpolation () {
- bool reachedEndOfPreviousPath = interpolator.valid && interpolator.remainingDistance < 0.0001f;
- if (interpolator.valid && !reachedEndOfPreviousPath) {
- previousMovementOrigin = interpolator.position;
- previousMovementDirection = interpolator.tangent.normalized * interpolator.remainingDistance;
- pathSwitchInterpolationTime = 0;
- } else {
- previousMovementOrigin = Vector3.zero;
- previousMovementDirection = Vector3.zero;
- pathSwitchInterpolationTime = float.PositiveInfinity;
- }
- }
- public virtual Vector3 GetFeetPosition () {
- return position;
- }
-
- protected virtual void ConfigureNewPath () {
- var hadValidPath = interpolator.valid;
- var prevTangent = hadValidPath ? interpolator.tangent : Vector3.zero;
- interpolator.SetPath(path.vectorPath);
- interpolator.MoveToClosestPoint(GetFeetPosition());
- if (interpolatePathSwitches && switchPathInterpolationSpeed > 0.01f && hadValidPath) {
- var correctionFactor = Mathf.Max(-Vector3.Dot(prevTangent.normalized, interpolator.tangent.normalized), 0);
- interpolator.distance -= speed*correctionFactor*(1f/switchPathInterpolationSpeed);
- }
- }
- protected virtual void Update () {
- if (shouldRecalculatePath) SearchPath();
- if (canMove) {
- Vector3 nextPosition;
- Quaternion nextRotation;
- MovementUpdate(Time.deltaTime, out nextPosition, out nextRotation);
- FinalizeMovement(nextPosition, nextRotation);
- }
- }
-
- public void MovementUpdate (float deltaTime, out Vector3 nextPosition, out Quaternion nextRotation) {
- if (updatePosition) simulatedPosition = tr.position;
- if (updateRotation) simulatedRotation = tr.rotation;
- Vector3 direction;
- nextPosition = CalculateNextPosition(out direction, isStopped ? 0f : deltaTime);
- if (enableRotation) nextRotation = SimulateRotationTowards(direction, deltaTime);
- else nextRotation = simulatedRotation;
- }
-
- public void FinalizeMovement (Vector3 nextPosition, Quaternion nextRotation) {
- previousPosition2 = previousPosition1;
- previousPosition1 = simulatedPosition = nextPosition;
- simulatedRotation = nextRotation;
- if (updatePosition) tr.position = nextPosition;
- if (updateRotation) tr.rotation = nextRotation;
- }
- Quaternion SimulateRotationTowards (Vector3 direction, float deltaTime) {
-
- if (direction != Vector3.zero) {
- Quaternion targetRotation = Quaternion.LookRotation(direction, orientation == OrientationMode.YAxisForward ? Vector3.back : Vector3.up);
-
- if (orientation == OrientationMode.YAxisForward) targetRotation *= Quaternion.Euler(90, 0, 0);
- return Quaternion.Slerp(simulatedRotation, targetRotation, deltaTime * rotationSpeed);
- }
- return simulatedRotation;
- }
-
-
- protected virtual Vector3 CalculateNextPosition (out Vector3 direction, float deltaTime) {
- if (!interpolator.valid) {
- direction = Vector3.zero;
- return simulatedPosition;
- }
- interpolator.distance += deltaTime * speed;
- if (interpolator.remainingDistance < 0.0001f && !reachedEndOfPath) {
- reachedEndOfPath = true;
- OnTargetReached();
- }
- direction = interpolator.tangent;
- pathSwitchInterpolationTime += deltaTime;
- var alpha = switchPathInterpolationSpeed * pathSwitchInterpolationTime;
- if (interpolatePathSwitches && alpha < 1f) {
-
-
- Vector3 positionAlongPreviousPath = previousMovementOrigin + Vector3.ClampMagnitude(previousMovementDirection, speed * pathSwitchInterpolationTime);
-
-
- return Vector3.Lerp(positionAlongPreviousPath, interpolator.position, alpha);
- } else {
- return interpolator.position;
- }
- }
- protected override int OnUpgradeSerializedData (int version, bool unityThread) {
- #pragma warning disable 618
- if (unityThread && targetCompatibility != null) target = targetCompatibility;
- #pragma warning restore 618
- if (version <= 3) {
- repathRate = repathRateCompatibility;
- canSearch = canSearchCompability;
- }
- return 4;
- }
- public virtual void OnDrawGizmos () {
- tr = transform;
- autoRepath.DrawGizmos(this.position, 0.0f);
- }
- }
- }
|