123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713 |
- using UnityEngine;
- using System.Collections.Generic;
- using Pathfinding.Util;
- using Pathfinding.Serialization;
- namespace Pathfinding {
-
-
-
-
-
-
-
-
- public interface IGraphInternals {
- string SerializedEditorSettings { get; set; }
- void OnDestroy();
- void DestroyAllNodes();
- IEnumerable<Progress> ScanInternal();
- void SerializeExtraInfo(GraphSerializationContext ctx);
- void DeserializeExtraInfo(GraphSerializationContext ctx);
- void PostDeserialization(GraphSerializationContext ctx);
- void DeserializeSettingsCompatibility(GraphSerializationContext ctx);
- }
-
- public abstract class NavGraph : IGraphInternals {
-
- public AstarPath active;
-
-
-
-
- [JsonMember]
- public Guid guid;
-
- [JsonMember]
- public uint initialPenalty;
-
- [JsonMember]
- public bool open;
-
- public uint graphIndex;
-
-
-
-
- [JsonMember]
- public string name;
-
-
-
-
-
- [JsonMember]
- public bool drawGizmos = true;
-
-
-
-
-
- [JsonMember]
- public bool infoScreenOpen;
-
- [JsonMember]
- string serializedEditorSettings;
-
- internal bool exists { get { return active != null; } }
-
-
-
-
-
-
-
- public virtual int CountNodes () {
- int count = 0;
- GetNodes(node => count++);
- return count;
- }
-
- public void GetNodes (System.Func<GraphNode, bool> action) {
- bool cont = true;
- GetNodes(node => {
- if (cont) cont &= action(node);
- });
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- public abstract void GetNodes(System.Action<GraphNode> action);
-
-
-
-
- [System.Obsolete("Use the transform field (only available on some graph types) instead", true)]
- public Matrix4x4 matrix = Matrix4x4.identity;
-
-
-
-
- [System.Obsolete("Use the transform field (only available on some graph types) instead", true)]
- public Matrix4x4 inverseMatrix = Matrix4x4.identity;
-
-
-
-
- [System.Obsolete("Use the transform field (only available on some graph types) instead", true)]
- public void SetMatrix (Matrix4x4 m) {
- matrix = m;
- inverseMatrix = m.inverse;
- }
-
-
-
-
-
- [System.Obsolete("Use RelocateNodes(Matrix4x4) instead. To keep the same behavior you can call RelocateNodes(newMatrix * oldMatrix.inverse).")]
- public void RelocateNodes (Matrix4x4 oldMatrix, Matrix4x4 newMatrix) {
- RelocateNodes(newMatrix * oldMatrix.inverse);
- }
-
-
-
-
-
-
-
-
- protected void AssertSafeToUpdateGraph () {
- if (!active.IsAnyWorkItemInProgress && !active.isScanning) {
- throw new System.Exception("Trying to update graphs when it is not safe to do so. Graph updates must be done inside a work item or when a graph is being scanned. See AstarPath.AddWorkItem");
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- public virtual void RelocateNodes (Matrix4x4 deltaMatrix) {
- GetNodes(node => node.position = ((Int3)deltaMatrix.MultiplyPoint((Vector3)node.position)));
- }
-
-
-
-
-
- public NNInfoInternal GetNearest (Vector3 position) {
- return GetNearest(position, NNConstraint.None);
- }
-
-
-
- public NNInfoInternal GetNearest (Vector3 position, NNConstraint constraint) {
- return GetNearest(position, constraint, null);
- }
-
-
-
-
- public virtual NNInfoInternal GetNearest (Vector3 position, NNConstraint constraint, GraphNode hint) {
-
-
- float maxDistSqr = constraint == null || constraint.constrainDistance ? AstarPath.active.maxNearestNodeDistanceSqr : float.PositiveInfinity;
- float minDist = float.PositiveInfinity;
- GraphNode minNode = null;
- float minConstDist = float.PositiveInfinity;
- GraphNode minConstNode = null;
-
- GetNodes(node => {
- float dist = (position-(Vector3)node.position).sqrMagnitude;
- if (dist < minDist) {
- minDist = dist;
- minNode = node;
- }
- if (dist < minConstDist && dist < maxDistSqr && (constraint == null || constraint.Suitable(node))) {
- minConstDist = dist;
- minConstNode = node;
- }
- });
- var nnInfo = new NNInfoInternal(minNode);
- nnInfo.constrainedNode = minConstNode;
- if (minConstNode != null) {
- nnInfo.constClampedPosition = (Vector3)minConstNode.position;
- } else if (minNode != null) {
- nnInfo.constrainedNode = minNode;
- nnInfo.constClampedPosition = (Vector3)minNode.position;
- }
- return nnInfo;
- }
-
-
-
-
- public virtual NNInfoInternal GetNearestForce (Vector3 position, NNConstraint constraint) {
- return GetNearest(position, constraint);
- }
-
-
-
-
-
-
-
- protected virtual void OnDestroy () {
- DestroyAllNodes();
- }
-
-
-
-
- protected virtual void DestroyAllNodes () {
- GetNodes(node => node.Destroy());
- }
-
-
-
-
- [System.Obsolete("Use AstarPath.Scan instead")]
- public void ScanGraph () {
- Scan();
- }
-
-
-
-
-
-
- public void Scan () {
- active.Scan(this);
- }
-
-
-
-
-
-
-
- protected abstract IEnumerable<Progress> ScanInternal();
-
-
-
-
-
-
-
-
- protected virtual void SerializeExtraInfo (GraphSerializationContext ctx) {
- }
-
-
-
-
- protected virtual void DeserializeExtraInfo (GraphSerializationContext ctx) {
- }
-
-
-
-
- protected virtual void PostDeserialization (GraphSerializationContext ctx) {
- }
-
-
-
-
-
- protected virtual void DeserializeSettingsCompatibility (GraphSerializationContext ctx) {
- guid = new Guid(ctx.reader.ReadBytes(16));
- initialPenalty = ctx.reader.ReadUInt32();
- open = ctx.reader.ReadBoolean();
- name = ctx.reader.ReadString();
- drawGizmos = ctx.reader.ReadBoolean();
- infoScreenOpen = ctx.reader.ReadBoolean();
- }
-
- public virtual void OnDrawGizmos (RetainedGizmos gizmos, bool drawNodes) {
- if (!drawNodes) {
- return;
- }
-
-
-
- var hasher = new RetainedGizmos.Hasher(active);
- GetNodes(node => hasher.HashNode(node));
-
- if (!gizmos.Draw(hasher)) {
- using (var helper = gizmos.GetGizmoHelper(active, hasher)) {
- GetNodes((System.Action<GraphNode>)helper.DrawConnections);
- }
- }
- if (active.showUnwalkableNodes) DrawUnwalkableNodes(active.unwalkableNodeDebugSize);
- }
- protected void DrawUnwalkableNodes (float size) {
- Gizmos.color = AstarColor.UnwalkableNode;
- GetNodes(node => {
- if (!node.Walkable) Gizmos.DrawCube((Vector3)node.position, Vector3.one*size);
- });
- }
- #region IGraphInternals implementation
- string IGraphInternals.SerializedEditorSettings { get { return serializedEditorSettings; } set { serializedEditorSettings = value; } }
- void IGraphInternals.OnDestroy () { OnDestroy(); }
- void IGraphInternals.DestroyAllNodes () { DestroyAllNodes(); }
- IEnumerable<Progress> IGraphInternals.ScanInternal () { return ScanInternal(); }
- void IGraphInternals.SerializeExtraInfo (GraphSerializationContext ctx) { SerializeExtraInfo(ctx); }
- void IGraphInternals.DeserializeExtraInfo (GraphSerializationContext ctx) { DeserializeExtraInfo(ctx); }
- void IGraphInternals.PostDeserialization (GraphSerializationContext ctx) { PostDeserialization(ctx); }
- void IGraphInternals.DeserializeSettingsCompatibility (GraphSerializationContext ctx) { DeserializeSettingsCompatibility(ctx); }
- #endregion
- }
-
-
-
-
- [System.Serializable]
- public class GraphCollision {
-
-
-
-
- public ColliderType type = ColliderType.Capsule;
-
-
-
-
-
-
-
-
-
-
-
-
-
- public float diameter = 1F;
-
-
-
-
-
-
-
-
-
- public float height = 2F;
-
-
-
-
-
-
-
-
-
-
- public float collisionOffset;
-
-
-
-
- public RayDirection rayDirection = RayDirection.Both;
-
- public LayerMask mask;
-
- public LayerMask heightMask = -1;
-
-
-
-
-
-
-
-
- public float fromHeight = 100;
-
-
-
-
- public bool thickRaycast;
-
-
-
-
- public float thickRaycastDiameter = 1;
-
- public bool unwalkableWhenNoGround = true;
-
-
-
-
- public bool use2D;
-
- public bool collisionCheck = true;
-
- public bool heightCheck = true;
-
-
-
-
- public Vector3 up;
-
-
-
-
- private Vector3 upheight;
-
- private ContactFilter2D contactFilter;
-
-
-
-
- private static Collider2D[] dummyArray = new Collider2D[1];
-
-
-
-
-
- private float finalRadius;
-
-
-
-
- private float finalRaycastRadius;
-
- public const float RaycastErrorMargin = 0.005F;
-
-
-
-
-
-
-
- public void Initialize (GraphTransform transform, float scale) {
- up = (transform.Transform(Vector3.up) - transform.Transform(Vector3.zero)).normalized;
- upheight = up*height;
- finalRadius = diameter*scale*0.5F;
- finalRaycastRadius = thickRaycastDiameter*scale*0.5F;
- contactFilter = new ContactFilter2D { layerMask = mask, useDepth = false, useLayerMask = true, useNormalAngle = false, useTriggers = false };
- }
-
-
-
-
- public bool Check (Vector3 position) {
- if (!collisionCheck) {
- return true;
- }
- if (use2D) {
- switch (type) {
- case ColliderType.Capsule:
- case ColliderType.Sphere:
- return Physics2D.OverlapCircle(position, finalRadius, contactFilter, dummyArray) == 0;
- default:
- return Physics2D.OverlapPoint(position, contactFilter, dummyArray) == 0;
- }
- }
- position += up*collisionOffset;
- switch (type) {
- case ColliderType.Capsule:
- return !Physics.CheckCapsule(position, position+upheight, finalRadius, mask, QueryTriggerInteraction.Ignore);
- case ColliderType.Sphere:
- return !Physics.CheckSphere(position, finalRadius, mask, QueryTriggerInteraction.Ignore);
- default:
- switch (rayDirection) {
- case RayDirection.Both:
- return !Physics.Raycast(position, up, height, mask, QueryTriggerInteraction.Ignore) && !Physics.Raycast(position+upheight, -up, height, mask, QueryTriggerInteraction.Ignore);
- case RayDirection.Up:
- return !Physics.Raycast(position, up, height, mask, QueryTriggerInteraction.Ignore);
- default:
- return !Physics.Raycast(position+upheight, -up, height, mask, QueryTriggerInteraction.Ignore);
- }
- }
- }
-
-
-
-
- public Vector3 CheckHeight (Vector3 position) {
- RaycastHit hit;
- bool walkable;
- return CheckHeight(position, out hit, out walkable);
- }
-
-
-
-
-
-
- public Vector3 CheckHeight (Vector3 position, out RaycastHit hit, out bool walkable) {
- walkable = true;
- if (!heightCheck || use2D) {
- hit = new RaycastHit();
- return position;
- }
- if (thickRaycast) {
- var ray = new Ray(position+up*fromHeight, -up);
- if (Physics.SphereCast(ray, finalRaycastRadius, out hit, fromHeight+0.005F, heightMask, QueryTriggerInteraction.Ignore)) {
- return VectorMath.ClosestPointOnLine(ray.origin, ray.origin+ray.direction, hit.point);
- }
- walkable &= !unwalkableWhenNoGround;
- } else {
-
- if (Physics.Raycast(position+up*fromHeight, -up, out hit, fromHeight+0.005F, heightMask, QueryTriggerInteraction.Ignore)) {
- return hit.point;
- }
- walkable &= !unwalkableWhenNoGround;
- }
- return position;
- }
-
- RaycastHit[] hitBuffer = new RaycastHit[8];
-
-
-
-
-
-
-
-
-
- public RaycastHit[] CheckHeightAll (Vector3 position, out int numHits) {
- if (!heightCheck || use2D) {
- hitBuffer[0] = new RaycastHit {
- point = position,
- distance = 0,
- };
- numHits = 1;
- return hitBuffer;
- }
-
- #if UNITY_2017_1_OR_NEWER
- numHits = Physics.RaycastNonAlloc(position+up*fromHeight, -up, hitBuffer, fromHeight+0.005F, heightMask, QueryTriggerInteraction.Ignore);
- if (numHits == hitBuffer.Length) {
-
- hitBuffer = new RaycastHit[hitBuffer.Length*2];
- return CheckHeightAll(position, out numHits);
- }
- return hitBuffer;
- #else
- var result = Physics.RaycastAll(position+up*fromHeight, -up, fromHeight+0.005F, heightMask, QueryTriggerInteraction.Ignore);
- numHits = result.Length;
- return result;
- #endif
- }
- public void DeserializeSettingsCompatibility (GraphSerializationContext ctx) {
- type = (ColliderType)ctx.reader.ReadInt32();
- diameter = ctx.reader.ReadSingle();
- height = ctx.reader.ReadSingle();
- collisionOffset = ctx.reader.ReadSingle();
- rayDirection = (RayDirection)ctx.reader.ReadInt32();
- mask = (LayerMask)ctx.reader.ReadInt32();
- heightMask = (LayerMask)ctx.reader.ReadInt32();
- fromHeight = ctx.reader.ReadSingle();
- thickRaycast = ctx.reader.ReadBoolean();
- thickRaycastDiameter = ctx.reader.ReadSingle();
- unwalkableWhenNoGround = ctx.reader.ReadBoolean();
- use2D = ctx.reader.ReadBoolean();
- collisionCheck = ctx.reader.ReadBoolean();
- heightCheck = ctx.reader.ReadBoolean();
- }
- }
-
-
-
-
- public enum ColliderType {
-
- Sphere,
-
- Capsule,
-
- Ray
- }
-
- public enum RayDirection {
- Up,
- Down,
- Both
- }
- }
|