# Table of Contents - [A* Pathfinding Project - A* Pathfinding Project](#a-pathfinding-project-a-pathfinding-project) - [Get Started - A* Pathfinding Project](#get-started-a-pathfinding-project) - [Deploying - A* Pathfinding Project](#deploying-a-pathfinding-project) - [Installation Guide - A* Pathfinding Project](#installation-guide-a-pathfinding-project) - [Misc - A* Pathfinding Project](#misc-a-pathfinding-project) - [Groups - A* Pathfinding Project](#groups-a-pathfinding-project) - [Agent Movement - A* Pathfinding Project](#agent-movement-a-pathfinding-project) - [Example Scenes - A* Pathfinding Project](#example-scenes-a-pathfinding-project) - [Graph Generation - A* Pathfinding Project](#graph-generation-a-pathfinding-project) - [Upgrade Guide - A* Pathfinding Project](#upgrade-guide-a-pathfinding-project) - [AstarPath - A* Pathfinding Project](#astarpath-a-pathfinding-project) - [Classes - A* Pathfinding Project](#classes-a-pathfinding-project) - [Changelog - A* Pathfinding Project](#changelog-a-pathfinding-project) - [Architecture overview - A* Pathfinding Project](#architecture-overview-a-pathfinding-project) - [Get Started Guide - A* Pathfinding Project](#get-started-guide-a-pathfinding-project) - [Using navmeshes - A* Pathfinding Project](#using-navmeshes-a-pathfinding-project) - [Graph Types - A* Pathfinding Project](#graph-types-a-pathfinding-project) - [The A* Inspector - A* Pathfinding Project](#the-a-inspector-a-pathfinding-project) - [Migrating from Unity Navigation - A* Pathfinding Project](#migrating-from-unity-navigation-a-pathfinding-project) - [Error messages - A* Pathfinding Project](#error-messages-a-pathfinding-project) - [Recast graph in a 3D game - A* Pathfinding Project](#recast-graph-in-a-3d-game-a-pathfinding-project) - [Movement scripts - A* Pathfinding Project](#movement-scripts-a-pathfinding-project) - [Optimization - A* Pathfinding Project](#optimization-a-pathfinding-project) - [Graph Updates during Runtime - A* Pathfinding Project](#graph-updates-during-runtime-a-pathfinding-project) - [Bitmask Tutorial - A* Pathfinding Project](#bitmask-tutorial-a-pathfinding-project) - [Useful Classes - A* Pathfinding Project](#useful-classes-a-pathfinding-project) - [Recast graph with doors - A* Pathfinding Project](#recast-graph-with-doors-a-pathfinding-project) - [Searching for paths - A* Pathfinding Project](#searching-for-paths-a-pathfinding-project) - [Deploying for mobile/uwp - A* Pathfinding Project](#deploying-for-mobile-uwp-a-pathfinding-project) - [Frequently Asked Questions - A* Pathfinding Project](#frequently-asked-questions-a-pathfinding-project) - [Fast Facts - A* Pathfinding Project](#fast-facts-a-pathfinding-project) - [Keyboard Shortcuts - A* Pathfinding Project](#keyboard-shortcuts-a-pathfinding-project) - [Collections - A* Pathfinding Project](#collections-a-pathfinding-project) - [Grid Graph Rules - A* Pathfinding Project](#grid-graph-rules-a-pathfinding-project) - [Recast graph on a moving surface - A* Pathfinding Project](#recast-graph-on-a-moving-surface-a-pathfinding-project) - [AABBTree - A* Pathfinding Project](#aabbtree-a-pathfinding-project) - [Path Types - A* Pathfinding Project](#path-types-a-pathfinding-project) - [Utilities - A* Pathfinding Project](#utilities-a-pathfinding-project) - [Recast graph with tags - A* Pathfinding Project](#recast-graph-with-tags-a-pathfinding-project) - [Using Modifiers - A* Pathfinding Project](#using-modifiers-a-pathfinding-project) - [Recast graph on a terrain - A* Pathfinding Project](#recast-graph-on-a-terrain-a-pathfinding-project) - [Using nodes - A* Pathfinding Project](#using-nodes-a-pathfinding-project) - [Navmesh Cutting - A* Pathfinding Project](#navmesh-cutting-a-pathfinding-project) - [Local Avoidance - A* Pathfinding Project](#local-avoidance-a-pathfinding-project) - [AABBComparer - A* Pathfinding Project](#aabbcomparer-a-pathfinding-project) - [Key - A* Pathfinding Project](#key-a-pathfinding-project) - [Modifiers - A* Pathfinding Project](#modifiers-a-pathfinding-project) - [Pathfinding - A* Pathfinding Project](#pathfinding-a-pathfinding-project) - [Graph Types - A* Pathfinding Project](#graph-types-a-pathfinding-project) - [Node - A* Pathfinding Project](#node-a-pathfinding-project) - [NNConstraint - A* Pathfinding Project](#nnconstraint-a-pathfinding-project) - [CloseNode - A* Pathfinding Project](#closenode-a-pathfinding-project) - [BBTreeBox - A* Pathfinding Project](#bbtreebox-a-pathfinding-project) - [NearestNodeConstraint - A* Pathfinding Project](#nearestnodeconstraint-a-pathfinding-project) - [GetNearest - A* Pathfinding Project](#getnearest-a-pathfinding-project) - [Wandering AI Tutorial - A* Pathfinding Project](#wandering-ai-tutorial-a-pathfinding-project) - [Multiple agent types - A* Pathfinding Project](#multiple-agent-types-a-pathfinding-project) - [Recast graph in a 2D game - A* Pathfinding Project](#recast-graph-in-a-2d-game-a-pathfinding-project) - [BBTree - A* Pathfinding Project](#bbtree-a-pathfinding-project) - [Recast graph with off-mesh links - A* Pathfinding Project](#recast-graph-with-off-mesh-links-a-pathfinding-project) - [Infinite procedurally generated world - A* Pathfinding Project](#infinite-procedurally-generated-world-a-pathfinding-project) - [BoxWithDist - A* Pathfinding Project](#boxwithdist-a-pathfinding-project) - [Saving and Loading Graphs - A* Pathfinding Project](#saving-and-loading-graphs-a-pathfinding-project) - [Working with tags - A* Pathfinding Project](#working-with-tags-a-pathfinding-project) - [Accessing graph data - A* Pathfinding Project](#accessing-graph-data-a-pathfinding-project) - [NearbyNodesIterator - A* Pathfinding Project](#nearbynodesiterator-a-pathfinding-project) - [TraversalCosts - A* Pathfinding Project](#traversalcosts-a-pathfinding-project) - [ITraversalProvider - A* Pathfinding Project](#itraversalprovider-a-pathfinding-project) - [GraphMask - A* Pathfinding Project](#graphmask-a-pathfinding-project) - [Agent-Specific Pathfinding - A* Pathfinding Project](#agent-specific-pathfinding-a-pathfinding-project) - [ProjectionParams - A* Pathfinding Project](#projectionparams-a-pathfinding-project) - [PathfindingTag - A* Pathfinding Project](#pathfindingtag-a-pathfinding-project) - [Pathfinding in 2D - A* Pathfinding Project](#pathfinding-in-2d-a-pathfinding-project) - [TraversalConstraint - A* Pathfinding Project](#traversalconstraint-a-pathfinding-project) - [Lightweight Local Avoidance Simulation - A* Pathfinding Project](#lightweight-local-avoidance-simulation-a-pathfinding-project) - [Large worlds - A* Pathfinding Project](#large-worlds-a-pathfinding-project) - [Utilities for turn-based games - A* Pathfinding Project](#utilities-for-turn-based-games-a-pathfinding-project) - [Moving a graph at runtime - A* Pathfinding Project](#moving-a-graph-at-runtime-a-pathfinding-project) - [CircularBuffer - A* Pathfinding Project](#circularbuffer-a-pathfinding-project) - [Circling a target - A* Pathfinding Project](#circling-a-target-a-pathfinding-project) - [GridLookup - A* Pathfinding Project](#gridlookup-a-pathfinding-project) - [Detecting obstacles along a line - A* Pathfinding Project](#detecting-obstacles-along-a-line-a-pathfinding-project) - [Spherical world - A* Pathfinding Project](#spherical-world-a-pathfinding-project) - [Creating graphs during runtime - A* Pathfinding Project](#creating-graphs-during-runtime-a-pathfinding-project) - [Path Types - A* Pathfinding Project](#path-types-a-pathfinding-project) - [Item - A* Pathfinding Project](#item-a-pathfinding-project) - [Root - A* Pathfinding Project](#root-a-pathfinding-project) - [Extending The System - A* Pathfinding Project](#extending-the-system-a-pathfinding-project) - [Pathfinding from editor scripts - A* Pathfinding Project](#pathfinding-from-editor-scripts-a-pathfinding-project) - [Manual Player Movement - A* Pathfinding Project](#manual-player-movement-a-pathfinding-project) - [VersionedMonoBehaviour - A* Pathfinding Project](#versionedmonobehaviour-a-pathfinding-project) - [Hexagonal Turn Based - A* Pathfinding Project](#hexagonal-turn-based-a-pathfinding-project) - [Point graph in a 3D game - A* Pathfinding Project](#point-graph-in-a-3d-game-a-pathfinding-project) - [ProceduralGraphMover - A* Pathfinding Project](#proceduralgraphmover-a-pathfinding-project) - [Navmesh Graph - A* Pathfinding Project](#navmesh-graph-a-pathfinding-project) - [HierarchicalBitset - A* Pathfinding Project](#hierarchicalbitset-a-pathfinding-project) - [DebugLimitsCtx - A* Pathfinding Project](#debuglimitsctx-a-pathfinding-project) - [Editing graph connections manually - A* Pathfinding Project](#editing-graph-connections-manually-a-pathfinding-project) - [DestroyGraphPromise - A* Pathfinding Project](#destroygraphpromise-a-pathfinding-project) - [Off-mesh links - A* Pathfinding Project](#off-mesh-links-a-pathfinding-project) - [GetNearest - A* Pathfinding Project](#getnearest-a-pathfinding-project) - [DummyGraphUpdateContext - A* Pathfinding Project](#dummygraphupdatecontext-a-pathfinding-project) - [Iterator - A* Pathfinding Project](#iterator-a-pathfinding-project) - [AllocatorData - A* Pathfinding Project](#allocatordata-a-pathfinding-project) - [Writing Graph Generators - A* Pathfinding Project](#writing-graph-generators-a-pathfinding-project) - [BatchedEvents - A* Pathfinding Project](#batchedevents-a-pathfinding-project) - [NativeCircularBuffer - A* Pathfinding Project](#nativecircularbuffer-a-pathfinding-project) - [High performance ECS - A* Pathfinding Project](#high-performance-ecs-a-pathfinding-project) - [AddWorkItem - A* Pathfinding Project](#addworkitem-a-pathfinding-project) - [Using high performance ECS - A* Pathfinding Project](#using-high-performance-ecs-a-pathfinding-project) - [Adding custom nodes to point graphs - A* Pathfinding Project](#adding-custom-nodes-to-point-graphs-a-pathfinding-project) - [Header - A* Pathfinding Project](#header-a-pathfinding-project) - [SlabAllocator - A* Pathfinding Project](#slaballocator-a-pathfinding-project) - [Grid - A* Pathfinding Project](#grid-a-pathfinding-project) - [Spherical Worlds - A* Pathfinding Project](#spherical-worlds-a-pathfinding-project) - [List - A* Pathfinding Project](#list-a-pathfinding-project) - [ConstantPath - A* Pathfinding Project](#constantpath-a-pathfinding-project) - [Rules - A* Pathfinding Project](#rules-a-pathfinding-project) - [GetNearestBorder - A* Pathfinding Project](#getnearestborder-a-pathfinding-project) - [Linecast - A* Pathfinding Project](#linecast-a-pathfinding-project) - [Voxelization - A* Pathfinding Project](#voxelization-a-pathfinding-project) - [Writing Custom Grid Graph Rules - A* Pathfinding Project](#writing-custom-grid-graph-rules-a-pathfinding-project) - [Jobs - A* Pathfinding Project](#jobs-a-pathfinding-project) - [NextBlock - A* Pathfinding Project](#nextblock-a-pathfinding-project) - [Navmesh - A* Pathfinding Project](#navmesh-a-pathfinding-project) - [FollowerEntity - A* Pathfinding Project](#followerentity-a-pathfinding-project) - [ScanAsync - A* Pathfinding Project](#scanasync-a-pathfinding-project) - [Scan - A* Pathfinding Project](#scan-a-pathfinding-project) - [SlabListExtensions - A* Pathfinding Project](#slablistextensions-a-pathfinding-project) - [UpdateGraphs - A* Pathfinding Project](#updategraphs-a-pathfinding-project) - [SpanExtensions - A* Pathfinding Project](#spanextensions-a-pathfinding-project) - [UnsafeSpan - A* Pathfinding Project](#unsafespan-a-pathfinding-project) - [AstarColor - A* Pathfinding Project](#astarcolor-a-pathfinding-project) - [RVO - A* Pathfinding Project](#rvo-a-pathfinding-project) - [EuclideanEmbedding - A* Pathfinding Project](#euclideanembedding-a-pathfinding-project) - [AgentIndex - A* Pathfinding Project](#agentindex-a-pathfinding-project) - [Heuristic Optimization - A* Pathfinding Project](#heuristic-optimization-a-pathfinding-project) - [RVOAgent - A* Pathfinding Project](#rvoagent-a-pathfinding-project) - [AstarData - A* Pathfinding Project](#astardata-a-pathfinding-project) - [JobCopyFromEntitiesToRVOSimulator - A* Pathfinding Project](#jobcopyfromentitiestorvosimulator-a-pathfinding-project) - [NavmeshUpdates - A* Pathfinding Project](#navmeshupdates-a-pathfinding-project) - [RVOSystem - A* Pathfinding Project](#rvosystem-a-pathfinding-project) - [NavGraph - A* Pathfinding Project](#navgraph-a-pathfinding-project) - [JobCopyFromRVOSimulatorToEntities - A* Pathfinding Project](#jobcopyfromrvosimulatortoentities-a-pathfinding-project) - [AgentCylinderShape - A* Pathfinding Project](#agentcylindershape-a-pathfinding-project) - [NavmeshCut - A* Pathfinding Project](#navmeshcut-a-pathfinding-project) - [AgentMovementPlane - A* Pathfinding Project](#agentmovementplane-a-pathfinding-project) - [GraphModifier - A* Pathfinding Project](#graphmodifier-a-pathfinding-project) - [OffMeshLinks - A* Pathfinding Project](#offmeshlinks-a-pathfinding-project) - [Progress - A* Pathfinding Project](#progress-a-pathfinding-project) - [AgentMovementPlaneSource - A* Pathfinding Project](#agentmovementplanesource-a-pathfinding-project) - [AgentOffMeshLinkLocalAvoidanceDisabled - A* Pathfinding Project](#agentoffmeshlinklocalavoidancedisabled-a-pathfinding-project) - [PathHandler - A* Pathfinding Project](#pathhandler-a-pathfinding-project) - [AgentOffMeshLinkMovementDisabled - A* Pathfinding Project](#agentoffmeshlinkmovementdisabled-a-pathfinding-project) - [ECS - A* Pathfinding Project](#ecs-a-pathfinding-project) - [RWLock - A* Pathfinding Project](#rwlock-a-pathfinding-project) - [GraphUpdateProcessor - A* Pathfinding Project](#graphupdateprocessor-a-pathfinding-project) - [AgentOffMeshLinkTraversal - A* Pathfinding Project](#agentoffmeshlinktraversal-a-pathfinding-project) - [AbortOffMeshLinkTraversal - A* Pathfinding Project](#abortoffmeshlinktraversal-a-pathfinding-project) - [AgentShouldRecalculatePath - A* Pathfinding Project](#agentshouldrecalculatepath-a-pathfinding-project) - [GlobalNodeStorage - A* Pathfinding Project](#globalnodestorage-a-pathfinding-project) - [PathReturnQueue - A* Pathfinding Project](#pathreturnqueue-a-pathfinding-project) - [HierarchicalGraph - A* Pathfinding Project](#hierarchicalgraph-a-pathfinding-project) - [AgentOffMeshLinkTraversalContext - A* Pathfinding Project](#agentoffmeshlinktraversalcontext-a-pathfinding-project) - [AIGizmosSystem - A* Pathfinding Project](#aigizmossystem-a-pathfinding-project) - [GraphUpdateLock - A* Pathfinding Project](#graphupdatelock-a-pathfinding-project) - [PathProcessor - A* Pathfinding Project](#pathprocessor-a-pathfinding-project) - [WorkItemProcessor - A* Pathfinding Project](#workitemprocessor-a-pathfinding-project) - [DrawerCallback - A* Pathfinding Project](#drawercallback-a-pathfinding-project) - [AIMovementSystemGroup - A* Pathfinding Project](#aimovementsystemgroup-a-pathfinding-project) - [AIMoveSystem - A* Pathfinding Project](#aimovesystem-a-pathfinding-project) - [TimeScaledRateManager - A* Pathfinding Project](#timescaledratemanager-a-pathfinding-project) - [ComponentRef - A* Pathfinding Project](#componentref-a-pathfinding-project) - [AutoRepathPolicy - A* Pathfinding Project](#autorepathpolicy-a-pathfinding-project) - [DestinationEntity - A* Pathfinding Project](#destinationentity-a-pathfinding-project) - [DestinationEntitySystem - A* Pathfinding Project](#destinationentitysystem-a-pathfinding-project) - [UpdateDestinationJob - A* Pathfinding Project](#updatedestinationjob-a-pathfinding-project) - [DestinationMoveInCircleSystem - A* Pathfinding Project](#destinationmoveincirclesystem-a-pathfinding-project) - [UpdateDestinationJob - A* Pathfinding Project](#updatedestinationjob-a-pathfinding-project) - [DestinationMoveInCircle - A* Pathfinding Project](#destinationmoveincircle-a-pathfinding-project) - [DrawGizmosJobUtils - A* Pathfinding Project](#drawgizmosjobutils-a-pathfinding-project) - [DestinationPoint - A* Pathfinding Project](#destinationpoint-a-pathfinding-project) - [EntityAccess - A* Pathfinding Project](#entityaccess-a-pathfinding-project) - [EntityAccessHelper - A* Pathfinding Project](#entityaccesshelper-a-pathfinding-project) - [EntityStorageCache - A* Pathfinding Project](#entitystoragecache-a-pathfinding-project) - [FallbackResolveMovementSystem - A* Pathfinding Project](#fallbackresolvemovementsystem-a-pathfinding-project) - [ResolvedMovement - A* Pathfinding Project](#resolvedmovement-a-pathfinding-project) - [MovementControl - A* Pathfinding Project](#movementcontrol-a-pathfinding-project) - [CopyJob - A* Pathfinding Project](#copyjob-a-pathfinding-project) - [CopyRotationJob - A* Pathfinding Project](#copyrotationjob-a-pathfinding-project) - [FollowerControlSystem - A* Pathfinding Project](#followercontrolsystem-a-pathfinding-project) - [GravityState - A* Pathfinding Project](#gravitystate-a-pathfinding-project) - [EntityDoesNotExistException - A* Pathfinding Project](#entitydoesnotexistexception-a-pathfinding-project) - [InitManagedStateSystem - A* Pathfinding Project](#initmanagedstatesystem-a-pathfinding-project) - [ManagedState - A* Pathfinding Project](#managedstate-a-pathfinding-project) - [JobAlignAgentWithMovementDirection - A* Pathfinding Project](#jobalignagentwithmovementdirection-a-pathfinding-project) - [ManagedSettings - A* Pathfinding Project](#managedsettings-a-pathfinding-project) - [JobClearTemporaryData - A* Pathfinding Project](#jobcleartemporarydata-a-pathfinding-project) - [JobApplyGravity - A* Pathfinding Project](#jobapplygravity-a-pathfinding-project) - [JobControl - A* Pathfinding Project](#jobcontrol-a-pathfinding-project) - [JobDrawFollowerGizmosBase - A* Pathfinding Project](#jobdrawfollowergizmosbase-a-pathfinding-project) - [JobManagedMovementOverrideAfterControl - A* Pathfinding Project](#jobmanagedmovementoverrideaftercontrol-a-pathfinding-project) - [JobManagedMovementOverrideBeforeControl - A* Pathfinding Project](#jobmanagedmovementoverridebeforecontrol-a-pathfinding-project) - [JobManagedMovementOverrideBeforeMovement - A* Pathfinding Project](#jobmanagedmovementoverridebeforemovement-a-pathfinding-project) - [JobManagedOffMeshLinkTransition - A* Pathfinding Project](#jobmanagedoffmeshlinktransition-a-pathfinding-project) - [JobDrawFollowerGizmos - A* Pathfinding Project](#jobdrawfollowergizmos-a-pathfinding-project) - [JobManagedOffMeshLinkTransitionCleanup - A* Pathfinding Project](#jobmanagedoffmeshlinktransitioncleanup-a-pathfinding-project) - [JobPrepareAgentRaycasts - A* Pathfinding Project](#jobprepareagentraycasts-a-pathfinding-project) - [JobMoveAgent - A* Pathfinding Project](#jobmoveagent-a-pathfinding-project) - [FollowerEntityProxy - A* Pathfinding Project](#followerentityproxy-a-pathfinding-project) - [JobRepairPath - A* Pathfinding Project](#jobrepairpath-a-pathfinding-project) - [PathTracerInfo - A* Pathfinding Project](#pathtracerinfo-a-pathfinding-project) - [JobRepairPathHelpers - A* Pathfinding Project](#jobrepairpathhelpers-a-pathfinding-project) - [JobStartOffMeshLinkTransition - A* Pathfinding Project](#jobstartoffmeshlinktransition-a-pathfinding-project) - [JobSyncEntitiesToTransforms - A* Pathfinding Project](#jobsyncentitiestotransforms-a-pathfinding-project) - [Scheduler - A* Pathfinding Project](#scheduler-a-pathfinding-project) - [JobUpdateMovementStatistics - A* Pathfinding Project](#jobupdatemovementstatistics-a-pathfinding-project) - [ManagedAgentOffMeshLinkTraversal - A* Pathfinding Project](#managedagentoffmeshlinktraversal-a-pathfinding-project) - [ManagedEntityAccess - A* Pathfinding Project](#managedentityaccess-a-pathfinding-project) - [LateSyncSystem - A* Pathfinding Project](#latesyncsystem-a-pathfinding-project) - [ManagedMovementOverrideAfterControl - A* Pathfinding Project](#managedmovementoverrideaftercontrol-a-pathfinding-project) - [ManagedMovementOverrideBeforeControl - A* Pathfinding Project](#managedmovementoverridebeforecontrol-a-pathfinding-project) - [ManagedMovementOverride - A* Pathfinding Project](#managedmovementoverride-a-pathfinding-project) - [ManagedMovementOverrideBeforeMovement - A* Pathfinding Project](#managedmovementoverridebeforemovement-a-pathfinding-project) - [ManagedMovementOverrides - A* Pathfinding Project](#managedmovementoverrides-a-pathfinding-project) - [JobMovementPlaneFromGraph - A* Pathfinding Project](#jobmovementplanefromgraph-a-pathfinding-project) - [MovementPlaneFromGraphSystem - A* Pathfinding Project](#movementplanefromgraphsystem-a-pathfinding-project) - [JobMovementPlaneFromNavmeshNormal - A* Pathfinding Project](#jobmovementplanefromnavmeshnormal-a-pathfinding-project) - [MovementStatistics - A* Pathfinding Project](#movementstatistics-a-pathfinding-project) - [MovementSettings - A* Pathfinding Project](#movementsettings-a-pathfinding-project) - [MovementStatisticsSystem - A* Pathfinding Project](#movementstatisticssystem-a-pathfinding-project) - [MovementState - A* Pathfinding Project](#movementstate-a-pathfinding-project) - [OrientationYAxisForward - A* Pathfinding Project](#orientationyaxisforward-a-pathfinding-project) - [MovementTarget - A* Pathfinding Project](#movementtarget-a-pathfinding-project) - [PhysicsSceneRef - A* Pathfinding Project](#physicssceneref-a-pathfinding-project) - [ReadyToTraverseOffMeshLink - A* Pathfinding Project](#readytotraverseoffmeshlink-a-pathfinding-project) - [PollPendingPathsSystem - A* Pathfinding Project](#pollpendingpathssystem-a-pathfinding-project) - [RepairPathSystem - A* Pathfinding Project](#repairpathsystem-a-pathfinding-project) - [SchedulePathSearchSystem - A* Pathfinding Project](#schedulepathsearchsystem-a-pathfinding-project) - [JobCheckStaleness - A* Pathfinding Project](#jobcheckstaleness-a-pathfinding-project) - [JobRecalculatePaths - A* Pathfinding Project](#jobrecalculatepaths-a-pathfinding-project) - [JobShouldRecalculatePaths - A* Pathfinding Project](#jobshouldrecalculatepaths-a-pathfinding-project) - [SearchState - A* Pathfinding Project](#searchstate-a-pathfinding-project) - [SimulateMovement - A* Pathfinding Project](#simulatemovement-a-pathfinding-project) - [SimulateMovementControl - A* Pathfinding Project](#simulatemovementcontrol-a-pathfinding-project) - [SimulateMovementFinalize - A* Pathfinding Project](#simulatemovementfinalize-a-pathfinding-project) - [SimulateMovementRepair - A* Pathfinding Project](#simulatemovementrepair-a-pathfinding-project) - [SyncDestinationTransformSystem - A* Pathfinding Project](#syncdestinationtransformsystem-a-pathfinding-project) - [SyncPositionWithTransform - A* Pathfinding Project](#syncpositionwithtransform-a-pathfinding-project) - [SyncRotationWithTransform - A* Pathfinding Project](#syncrotationwithtransform-a-pathfinding-project) --- # A* Pathfinding Project - A* Pathfinding Project A\* Pathfinding Project ======================= Welcome to the A\* Pathfinding Project Documentation. Here you will find tutorials, as well as detailed information about the classes and methods in the package. I hope you will be able to find what you are looking for. If you cannot find what you are looking for here, check out the [forum](http://forum.arongranberg.com/) . Often, there is already an existing thread about the issue that you are trying to solve. ![](https://arongranberg.com/astar/docs/images/generated/scenes/Recast3D/overviewwithgraphs.png) Get Started ----------- If you haven't installed the package yet, check out the [Installation Guide](https://arongranberg.com/astar/docs/installation.html) . Check out the [get started](https://arongranberg.com/astar/docs/getstarted.html) tutorial to start using the package. Or, if you want to dive right in, check out the included [Example Scenes](https://arongranberg.com/astar/docs/examplescenes.html) . Upgrading from an earlier version? ---------------------------------- Take a look at the [Upgrade Guide](https://arongranberg.com/astar/docs/upgrading.html) . Accessing the documentation from the Unity Editor ------------------------------------------------- You can easily access the documentation from inside the Unity Editor. If you find a class which is confusing, simply click on the small ❓ icon in the upper right corner of the inspector. This will open the online documentation for that class. Or if you are interested in a particular field, right-click on that field and click the **Show in online documentation** button that will show up. This is implemented for most components and properties, but not all of them so far. In particular, it is not yet implemented for the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component and graph inspectors. ![](https://arongranberg.com/astar/docs/images/inspector_doc_links.png) Buy Pro ------- The A\* Pathfinding Project has a Free version and a Pro version. The Pro version has a lot of cool extra features, such as multithreading, automatic navmesh generation and more. Check out the [Free vs Pro comparison page](http://www.arongranberg.com/astar/freevspro) . You can buy the Pro version [here](http://www.arongranberg.com/astar/buy) . --- # Get Started - A* Pathfinding Project Get Started =========== * [Installation Guide](https://arongranberg.com/astar/docs/installation.html) * [Get Started Guide](https://arongranberg.com/astar/docs/getstarted.html) * [Using navmeshes](https://arongranberg.com/astar/docs/getstarted2.html) * [The A\* Inspector](https://arongranberg.com/astar/docs/inspector.html) * [Graph Types](https://arongranberg.com/astar/docs/graphtypes.html) * [Architecture overview](https://arongranberg.com/astar/docs/architecture.html) * [Migrating from Unity Navigation](https://arongranberg.com/astar/docs/migratingfromunity.html) * [Error messages](https://arongranberg.com/astar/docs/errormessages.html) --- # Deploying - A* Pathfinding Project Deploying ========= * [Optimization](https://arongranberg.com/astar/docs/optimization.html) * [Deploying for mobile/uwp](https://arongranberg.com/astar/docs/iphone.html) --- # Installation Guide - A* Pathfinding Project Installation Guide ================== This page shows you how to install the package. Contents -------- * [Introduction](https://arongranberg.com/astar/docs/installation.html#installation-intro) * [Installing from the Unity Asset Store](https://arongranberg.com/astar/docs/installation.html#installation-assetstore) * [Importing Example Scenes](https://arongranberg.com/astar/docs/installation.html#installation-assetstore-examples) * [Installing using the Package Manager via a Scoped Registry](https://arongranberg.com/astar/docs/installation.html#installation-upm) * [Assembly Definitions References](https://arongranberg.com/astar/docs/installation.html#asmdefs) * [Installation Errors](https://arongranberg.com/astar/docs/installation.html#installation-errors) Introduction ------------ You can either install the package from the Unity Asset Store, or from the package website via a custom package manager registry. Both alternatives work fine, but the custom registry is a bit more robust (until Unity improves their package manager), and it allows you to access beta versions of the package. Installing from the Unity Asset Store ------------------------------------- 1. Make sure you are logged in to the same Unity account in the Unity editor that you purchased the package with. 2. If you are upgrading from version 4, **you must delete your previous installation before upgrading**, to avoid conflicts. You may also want to check out the [Upgrade Guide](https://arongranberg.com/astar/docs/upgrading.html) . If you have previously installed the beta version via a scoped registry, you can continue using that method instead. 3. Open the Unity Package Manager. ![](https://arongranberg.com/astar/docs/images/installation/package_manager_menu@2x.png) 4. Open the "My Assets" tab. 5. Click on the A\* Pathfinding Project package. 6. Click on "Import to project". ![](https://arongranberg.com/astar/docs/images/installation/import_from_my_assets.png) Note The package will be imported into the **Packages** folder in Unity. It will not be present in your **Assets** folder. ### Importing Example Scenes It is also recommended to import the example scenes. These are confusingly not accessible from the same place in the package manager. 1. After you have imported the package, go to "In Project" (in the package manager). 2. Click on the "A\* Pathfinding Project \[custom\]" package (there may be two A\* packages in this view, make sure you click on the right one). 3. Go to the "Samples" tab. 4. Click "Import". ![](https://arongranberg.com/astar/docs/images/installation/import_samples.png) All dependencies should be imported automatically. See [Assembly Definitions References](https://arongranberg.com/astar/docs/installation.html#asmdefs) , if you are using .asmdef files for your code. Installing using the Package Manager via a Scoped Registry ---------------------------------------------------------- You can also install the A\* Pathfinding Project using a scoped registry via the [package website](https://www.arongranberg.com/astar/download_upm) . This is used to gain access to beta versions, and it's also easier to switch between different versions of the package using this method. Follow the instructions on the linked page to add the scoped registry to your project, and then you can install the package using the package manager. Nothing else needs to be done after you have imported the package. You can optionally import the example scenes from the Unity Package Manager. By default, they are not imported. See [Assembly Definitions References](https://arongranberg.com/astar/docs/installation.html#asmdefs) , if you are using .asmdef files for your code. Assembly Definitions References ------------------------------- If you are using [Assembly Definition Files (.asmdef)](https://docs.unity3d.com/Manual/ScriptCompilationAssemblyDefinitionFiles.html) in your project, you will need to add a few references to be able to use pathfinding from your own code. Note If you've never heard of .asmdef files, you are probably not using them, and you can skip this section. 1. Find all .asmdef files that you use for **your code** (not the ones in the pathfinding package, or any other unrelated 3rd party libraries). 2. In the "Assembly Definition References" section, add the "AstarPathfindingProject", "ALINE", and "PackageTools" assemblies as references. 3. Enable "Use GUIDs" for improved compatibility. 4. Click **Apply**. ![](https://arongranberg.com/astar/docs/images/installation/asmdef_dependencies.png) Installation Errors ------------------- Here's a list of errors that you might encounter when importing the package and how to fix them. **"Metadata file 'Library/PackageCache/com.unity.ext.nunit@1.0.6/net40/unity-custom/nunit.framework.dll' could not be found"** This error is caused by a Unity bug. Restarting Unity usually resolves the error. **The type or namespace name 'Pathfinding' could not be found** If the package seems properly installed, this might arise in your own scripts when you try to use the package. This is usually caused by using [.asmdef](https://docs.unity3d.com/Manual/ScriptCompilationAssemblyDefinitionFiles.html) files in your project. You will need to select the one relevant for your script, and add the **AstarPathfindingProject** assembly as a reference. See [Assembly Definitions References](https://arongranberg.com/astar/docs/installation.html#asmdefs) **Other errors** If you encounter other errors, these are good things to try: * Make sure you are using a supported version of Unity. * Make sure dependencies seem properly installed. * Try to delete the package, and install it again. * Restart Unity. --- # Misc - A* Pathfinding Project Misc ==== * [Upgrade Guide](https://arongranberg.com/astar/docs/upgrading.html) * [Bitmask Tutorial](https://arongranberg.com/astar/docs/bitmasks.html) * [Frequently Asked Questions](https://arongranberg.com/astar/docs/faq.html) * [Fast Facts](https://arongranberg.com/astar/docs/facts.html) * [Keyboard Shortcuts](https://arongranberg.com/astar/docs/shortcuts.html) --- # Groups - A* Pathfinding Project Groups ====== [Useful Classes](https://arongranberg.com/astar/docs/relevant.html) These are the classes you will use most. [Path Types](https://arongranberg.com/astar/docs/paths.html) Collection of the most used path types. [Utilities](https://arongranberg.com/astar/docs/utils.html) Collection of utility classes which might be useful. [Modifiers](https://arongranberg.com/astar/docs/modifiers.html) Collection of the most used modifiers. [Graph Types](https://arongranberg.com/astar/docs/graphs.html) Collection of the most used graph types. --- # Agent Movement - A* Pathfinding Project Agent Movement ============== * [Movement scripts](https://arongranberg.com/astar/docs/movementscripts.html) * [Searching for paths](https://arongranberg.com/astar/docs/callingpathfinding.html) * [Using Modifiers](https://arongranberg.com/astar/docs/modifiers2.html) * [Local Avoidance](https://arongranberg.com/astar/docs/localavoidance.html) * [Wandering AI Tutorial](https://arongranberg.com/astar/docs/wander.html) * [Multiple agent types](https://arongranberg.com/astar/docs/multipleagenttypes.html) * [Agent-Specific Pathfinding](https://arongranberg.com/astar/docs/traversal_provider.html) * [Pathfinding in 2D](https://arongranberg.com/astar/docs/pathfinding2d.html) * [Utilities for turn-based games](https://arongranberg.com/astar/docs/turnbased.html) * [Circling a target](https://arongranberg.com/astar/docs/move_in_circle.html) * [Detecting obstacles along a line](https://arongranberg.com/astar/docs/linecasting.html) * [Manual Player Movement](https://arongranberg.com/astar/docs/playermovement.html) * [Pathfinding from editor scripts](https://arongranberg.com/astar/docs/editormode.html) * [Using high performance ECS](https://arongranberg.com/astar/docs/ecs.html) --- # Example Scenes - A* Pathfinding Project Example Scenes ============== Overview of the example scenes in the package. ![](https://arongranberg.com/astar/docs/images/generated/marketing/montage.png) There are multiple example scenes included in the package. They are located in the folder **ExampleScenes**. If you are using the Unity Package Manager, you may have to import the examples scenes separately, using a button in the package manager. For detailed instructions, take a look at the [Installation Guide](https://arongranberg.com/astar/docs/installation.html) . * [Recast graph in a 3D game](https://arongranberg.com/astar/docs/example_recast3d.html) * [Recast graph with doors](https://arongranberg.com/astar/docs/example_recast_doors.html) * [Recast graph on a moving surface](https://arongranberg.com/astar/docs/example_recast_moving.html) * [Recast graph with tags](https://arongranberg.com/astar/docs/example_recast_tags.html) * [Recast graph on a terrain](https://arongranberg.com/astar/docs/example_recast_terrain.html) * [Recast graph in a 2D game](https://arongranberg.com/astar/docs/example_recast2d.html) * [Recast graph with off-mesh links](https://arongranberg.com/astar/docs/example_recast_offmeshlinks.html) * [Infinite procedurally generated world](https://arongranberg.com/astar/docs/example_infinite_world.html) * [Lightweight Local Avoidance Simulation](https://arongranberg.com/astar/docs/example_local_avoidance_lightweight.html) * [Path Types](https://arongranberg.com/astar/docs/example_path_types.html) * [Hexagonal Turn Based](https://arongranberg.com/astar/docs/example_turn_based.html) * [Spherical world](https://arongranberg.com/astar/docs/example_spherical.html) * [Navmesh Graph](https://arongranberg.com/astar/docs/example_navmeshgraph.html) * [Point graph in a 3D game](https://arongranberg.com/astar/docs/example_pointgraph.html) * [High performance ECS](https://arongranberg.com/astar/docs/example_ecs.html) --- # Graph Generation - A* Pathfinding Project Graph Generation ================ * [Graph Types](https://arongranberg.com/astar/docs/graphtypes.html) * [Using navmeshes](https://arongranberg.com/astar/docs/getstarted2.html) * [Graph Updates during Runtime](https://arongranberg.com/astar/docs/graphupdates.html) * [Grid Graph Rules](https://arongranberg.com/astar/docs/gridrules.html) * [Using nodes](https://arongranberg.com/astar/docs/usingnodes.html) * [Navmesh Cutting](https://arongranberg.com/astar/docs/navmeshcutting.html) * [Working with tags](https://arongranberg.com/astar/docs/tags.html) * [Saving and Loading Graphs](https://arongranberg.com/astar/docs/saveloadgraphs.html) * [Accessing graph data](https://arongranberg.com/astar/docs/accessingdata.html) * [Large worlds](https://arongranberg.com/astar/docs/largeworlds.html) * [Moving a graph at runtime](https://arongranberg.com/astar/docs/moving_graph.html) * [Off-mesh links](https://arongranberg.com/astar/docs/offmeshlinks2.html) * [Creating graphs during runtime](https://arongranberg.com/astar/docs/runtimegraphs.html) * [Extending The System](https://arongranberg.com/astar/docs/extending.html) * [Editing graph connections manually](https://arongranberg.com/astar/docs/editinggraphs.html) * [Adding custom nodes to point graphs](https://arongranberg.com/astar/docs/creatingpointnodes.html) * [Spherical Worlds](https://arongranberg.com/astar/docs/spherical.html) --- # Upgrade Guide - A* Pathfinding Project Upgrade Guide ============= This page helps you upgrade from an older version of the A\* Pathfinding Project to a newer one. Contents -------- * [Upgrading to 5.4 from 5.x](https://arongranberg.com/astar/docs/upgrading.html#v5_4) * [New and more accurate traversal costs on navmesh/recast graphs](https://arongranberg.com/astar/docs/upgrading.html#upgrade-traversalcosts) * [Replace NNConstraint with NearestNodeConstraint](https://arongranberg.com/astar/docs/upgrading.html#upgrade-nnconstraint) * [New ways to set traversal constraints and costs on paths](https://arongranberg.com/astar/docs/upgrading.html#upgrade-traversalconstraint) * [Overhauled ITraversalProvider](https://arongranberg.com/astar/docs/upgrading.html#upgrade-itraversalprovider) * [GraphMask changes](https://arongranberg.com/astar/docs/upgrading.html#upgrade-graphmask) * [Upgrading to 5.0 from 4.x](https://arongranberg.com/astar/docs/upgrading.html#v5) * [Installing the update](https://arongranberg.com/astar/docs/upgrading.html#deleteOld) * [Use ai.SetPath instead of Seeker.StartPath](https://arongranberg.com/astar/docs/upgrading.html#setpath) * [Seeker.pathCallback is deprecated](https://arongranberg.com/astar/docs/upgrading.html#pathCallback) * [Scans happen during OnEnable instead of during Awake](https://arongranberg.com/astar/docs/upgrading.html#scanAwake) * [Pathfinding tags are now represented by a struct](https://arongranberg.com/astar/docs/upgrading.html#pathfindingTagStruct) * [Removed support for RVOSquareObstacle](https://arongranberg.com/astar/docs/upgrading.html#rvoSquareObstacle) * [Deprecated RVONavmesh](https://arongranberg.com/astar/docs/upgrading.html#rvonavmesh) * [Changed interface for custom graphs](https://arongranberg.com/astar/docs/upgrading.html#customGraph) * [Graph updates do more work asynchronously](https://arongranberg.com/astar/docs/upgrading.html#asyncGraphUpdates) * [Use GraphUpdateObject.ApplyJob instead of Apply for grid graphs](https://arongranberg.com/astar/docs/upgrading.html#graphUpdateObjectGrid) * [Batch grid node updates for better performance](https://arongranberg.com/astar/docs/upgrading.html#manulGridUpdates) * [Costs in hexagonal graphs were incorrectly scaled](https://arongranberg.com/astar/docs/upgrading.html#hexagonCosts) * [NavGraph.GetNearest now always takes constraints into account](https://arongranberg.com/astar/docs/upgrading.html#getnearestconstraints) * [Movement scripts no longer use Update and FixedUpdate](https://arongranberg.com/astar/docs/upgrading.html#aiupdate) * [ProceduralGridMover is now ProceduralGraphMover](https://arongranberg.com/astar/docs/upgrading.html#graphmover) * [Namespace Structure](https://arongranberg.com/astar/docs/upgrading.html#namespaces) * [General upgrade notes](https://arongranberg.com/astar/docs/upgrading.html#older) Upgrading to 5.4 from 5.x ------------------------- Version 5.4 brings a lot of new features and improvements, and there are some breaking changes. Most code will continue to work without any changes, a few things will log compilation warnings, letting you know that you should update your code. And yet fewer things will cause compilation errors, or runtime errors, which you'll have to fix before using the new version. ### New and more accurate traversal costs on navmesh/recast graphs Making regions harder or easier to traverse has been made more intuitive and accurate. Instead of only allowing a cost for entering a node (which is not very accurate on navmesh/recast graphs as their nodes can vary so much in size), you can now set a cost multiplier which is scaled by the distance traversed inside the node. So for example a multiplier of 2 means that the node is twice as expensive to traverse, compared to the default. You can find this in the Seeker or [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) inspectors under the **Tags** foldout, called "Cost per world unit". In the inspector, the multiplier is multiplied by 1000 to make it correspond to the cost of moving 1 world unit. ![](https://arongranberg.com/astar/docs/images/tagpopup@2x.png) The previous tag penalties are still there, but they are now called "cost per node", or [TraversalCosts.tagEntryCosts](https://arongranberg.com/astar/docs/traversalcosts.html#tagEntryCosts) in the code. If you have previously been using tag penalties on navmesh/recast graphs, consider switching to the new cost multipliers. You may have to fiddle a bit with the values to get similar behavior, but it should be more accurate and easier to understand. On grid graphs, using the cost multipliers is also a good choice, and likely more intuitive, but using costs per node is also fine. What you choose depends on what you find most intuitive. ### Replace NNConstraint with NearestNodeConstraint The [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) class has been replaced with the new [NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) struct. It works in a similar way, but is now a struct instead of a class, and thus avoids GC allocations in many situations. In particular, the annoying allocation of a single NNConstraint for every pathfinding request is now avoided, and pathfinding can now be completely GC-free for most games. There are compatibility methods in place, so for the most part you can continue to use your old code. However, for best performance, you should use the new struct instead. Before: `var constraint = NNConstraint.Walkable; constraint.graphMask = GraphMask.FromGraphName("My Graph"); constraint.constrainTags = true; constraint.tags = 1 << 0; constraint.constrainWalkability = true; constraint.walkable = true; constraint.constrainDistance = false; [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (Vector3.zero, constraint); `After: `var constraint = NearestNodeConstraint.Walkable; constraint.graphMask = GraphMask.FromGraphName("My Graph"); // The constrainTags boolean does not exist anymore. // It always filters on tags (though setting it to ~0 will make all tags pass). constraint.tags = 1 << 0; // The walkability constraint is now an enum, for clarity constraint.walkable = NearestNodeConstraint.WalkabilityConstraint.Walkable; // The max distance is now a nullable float, instead of a bool. // Setting it to null will use the default value set on the AstarPath component. constraint.maxDistance = float.PositiveInfinity; // Set a filter function instead of subclassing the NNConstraint constraint.filter = node => { return ((Vector3)node.position).y > 0; }; // You can also set a traversal provider directly on the constraint. constraint.traversalProvider = new MyTraversalProvider(); [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (Vector3.zero, constraint); ` See [NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) [AstarPath.GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html) ### New ways to set traversal constraints and costs on paths The new [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint.html) and [TraversalCosts](https://arongranberg.com/astar/docs/traversalcosts.html) structs allow you to set which nodes are traversable and what the costs are for traversing them. This is a more uniform way of handling traversal constraints and costs, and fixes many edge cases with the old system. When creating custom paths, you would previously set various fields on the path object itself, but now you should set the constraints and costs on the [Path.traversalConstraint](https://arongranberg.com/astar/docs/path.html#traversalConstraint) and [Path.traversalCosts](https://arongranberg.com/astar/docs/path.html#traversalCosts) fields instead. Before: `var path = ABPath.Construct(Vector3.zero, Vector3.one, null); path.enabledTags = 1 << 0; path.nnConstraint.graphMask = GraphMask.FromGraphName("My Graph"); path.tagPenalties = new uint[32]; path.tagPenalties[5] = 1000; path.traversalProvider = new SomeTraversalProvider(); `After: `var path = ABPath.Construct(Vector3.zero, Vector3.one, null); path.traversalConstraint.tags = 1 << 0; path.traversalConstraint.graphMask = GraphMask.FromGraphName("My Graph"); path.traversalCosts.tagEntryCosts = new uint[32]; path.traversalCosts.tagEntryCosts[5] = 1000; // New field for traversal costs which is more intuitive on navmesh/recast graphs path.traversalCosts.tagCostMultipliers = new float[32]; path.traversalCosts.tagCostMultipliers[5] = 2; // Make tag 5 twice as costly to traverse // The traversal provider for costs and traversal constraints are now separate, // so you must assign it in two places. var traversalProvider = new SomeTraversalProvider(); path.traversalConstraint.traversalProvider = traversalProvider; path.traversalCosts.traversalProvider = traversalProvider; `The [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint.html) can also be directly converted into the corresponding [NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) : `var nearestNodeConstraint = traversalConstraint.ToNearestNodeConstraint(); // Use the nearest node constraint to find the closest node var nearest = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (transform.position, nearestNodeConstraint); ` See [Path.traversalConstraint](https://arongranberg.com/astar/docs/path.html#traversalConstraint) [Path.traversalCosts](https://arongranberg.com/astar/docs/path.html#traversalCosts) [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint.html) [TraversalCosts](https://arongranberg.com/astar/docs/traversalcosts.html) ### Overhauled ITraversalProvider The ITraversalProvider interface has been changed to use the new [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint.html) and [TraversalCosts](https://arongranberg.com/astar/docs/traversalcosts.html) structs. This allows for a more flexible and powerful way to define traversal costs and constraints. If you have implemented your own ITraversalProvider, you will need to update your implementation to use the new structs. Warning Since the ITraversalProvider interface has default implementations for all methods, you will not get any compiler errors, even if your method signatures are wrong. So check your implementation carefully. However, if you try to use the ITraversalProvider for pathfinding, you will get an error at runtime if you are using the old implementation. Before: `public class MyTraversalProvider : ITraversalProvider { public bool CanTraverse (Path path, GraphNode node) { return DefaultITraversalProvider.CanTraverse(path, node); } public bool CanTraverse (Path path, GraphNode from, GraphNode to) { return CanTraverse(path, to); } public uint GetTraversalCost (Path path, GraphNode node) { return DefaultITraversalProvider.GetTraversalCost(path, node); } } `After: `public class MyTraversalProvider : ITraversalProvider { public bool CanTraverse (ref TraversalConstraint traversalConstraint, GraphNode node) { return DefaultITraversalProvider.CanTraverse(ref traversalConstraint, node); } public bool CanTraverse (ref TraversalConstraint traversalConstraint, GraphNode from, GraphNode to) { return CanTraverse(ref traversalConstraint, to); } public float GetTraversalCostMultiplier (ref TraversalCosts traversalCosts, GraphNode node) { return DefaultITraversalProvider.GetTraversalCostMultiplier(ref traversalCosts, node); } public uint GetConnectionCost (ref TraversalCosts traversalCosts, GraphNode from, GraphNode to) { return DefaultITraversalProvider.GetConnectionCost(ref traversalCosts, from, to); } } `Important changes: * The CanTraverse method now takes a TraversalConstraint struct as the first parameter instead of a Path object. * The GetTraversalCost method has been replaced with GetConnectionCost and GetTraversalCostMultiplier methods, which take a TraversalCosts struct as the first parameter. * The GetTraversalCost method corresponds directly to the GetConnectionCost method, but for most games, the GetTraversalCostMultiplier method is a better choice. * The new GetConnectionCost method receives information about both the start and end node, allowing much more flexibility. Take a look at the previous sections which describe the TraversalConstraint and TraversalCosts structs for more information. See [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) [TraversalCosts](https://arongranberg.com/astar/docs/traversalcosts.html) [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint.html) ### GraphMask changes The [GraphMask](https://arongranberg.com/astar/docs/graphmask.html) struct has had its internal representation changed to be more flexible. This means that the old implicit conversion from an integer to a GraphMask is no longer available. This is a breaking change, but it should be easy to fix. Before: `GraphMask mask = -1; mask = 1 << 5; mask = 1 << 3 | 1 << 5; `After: `GraphMask mask = GraphMask.everything; mask = GraphMask.FromGraphIndex(5); mask = GraphMask.FromGraphIndex(3) | GraphMask.FromGraphIndex(5); // Also consider using mask = GraphMask.FromGraphName("My Graph"); `Previously, the graph mask has not been able to represent graphs with indices larger than 31. Now, it can represent all combinations of graphs up to index 30, and combinations of up to 3 indices that are larger than 31. This means that for the very rare games where you need more than 31 graphs, the graph mask should no longer be a problem for the vast majority of cases. Upgrading to 5.0 from 4.x ------------------------- There have been many changes in the 5.0 release. For most people, the upgrade should be smooth and require no changes to your code, but there are a few breaking changes which may require you to update your code or tweak some settings. ### Installing the update When you upgrade, make sure to delete your old AstarPathfindingProject folder before importing the new version. Not doing this can sometimes cause problems due to old files being left over. See [Installation Guide](https://arongranberg.com/astar/docs/installation.html) ### Use ai.SetPath instead of Seeker.StartPath The built-in movement scripts no longer listen for **all** paths that their attached Seeker component calculates; instead, they only listen for paths that they request. If you have been relying on this by calling seeker.StartPath from another script and expecting the movement scripts to start following the path, you will need to change this to call [ai.SetPath](https://arongranberg.com/astar/docs/iastarai/setpath.html#SetPath) instead. This has been the recommended way to do it for a long time, but now it is required. There is some compatibility code which will keep your code working for now, but it will log a warning every time it happens. Note This does not affect you if you have written your own custom movement script. In that case, you should continue using the Seeker. Previously, your code may have looked like: `var ai = GetComponent(); var seeker = GetComponent(); seeker.StartPath(ai.position, ai.destination); `You should replace that with something like: `var ai = GetComponent(); var path = ABPath.Construct(ai.position, ai.destination); ai.SetPath(path); ` See [Searching for paths](https://arongranberg.com/astar/docs/callingpathfinding.html) for more info ### Seeker.pathCallback is deprecated The Seeker.pathCallback field is now deprecated. You should instead send a callback to the StartPath method every time. Note This only affects you if you are writing your own movement script. If you are using one of the built-in movement scripts, then you should use [ai.SetPath](https://arongranberg.com/astar/docs/iastarai/setpath.html#SetPath) as described in the previous section. Previously, your code may have looked like: `Seeker seeker; void OnEnable () { seeker = GetComponent(); seeker.pathCallback += OnPathComplete; } void OnDisable () { seeker.pathCallback -= OnPathComplete; } void DoSomething() { seeker.StartPath(transform.position, target.position); } void OnPathComplete (Path path) { // Do something with the path } ` You should replace that with something like: `Seeker seeker; OnPathDelegate onPathComplete; void OnEnable () { seeker = GetComponent(); onPathComplete = OnPathComplete; } void DoSomething() { seeker.StartPath(transform.position, target.position, onPathComplete); } void OnPathComplete (Path path) { // Do something with the path } ` See [Searching for paths](https://arongranberg.com/astar/docs/callingpathfinding.html) for more info ### Scans happen during OnEnable instead of during Awake Scanning when the game starts now happens during early **OnEnable** instead of during early **Awake**. This should typically not cause any issues, since it's good practice in Unity to not depend on other components being initialized in **Awake**. But this may cause issues if you have been depending on this very specific initialization order. ### Pathfinding tags are now represented by a struct The type of some tag fields has changed from int to [PathfindingTag](https://arongranberg.com/astar/docs/pathfindingtag.html) . If you have assigned a tag to those fields before, you will now first need to convert it to a PathfindingTag: `GetComponent().setTag = new PathfindingTag((uint)tag); ` You can also use the [PathfindingTag.FromName](https://arongranberg.com/astar/docs/pathfindingtag/fromname.html#FromName) method to get a tag from a string. If you want to show a tag enum in the inspector, you can expose a public field of type [PathfindingTag](https://arongranberg.com/astar/docs/pathfindingtag.html) . It will automatically be shown as a dropdown with the tag names. ### Removed support for RVOSquareObstacle The RVOSquareObstacle has been removed. It never worked particularly well and the performance was poor. However, the local avoidance system now takes the pathfinding graph into account much better (if this is enabled on the RVOSimulator component), so you can use graph updates to update the pathfinding graph instead. ### Deprecated RVONavmesh The RVONavmesh component has been deprecated. This is now handled automatically by enabling the [RVOSimulator.useNavmeshAsObstacle](https://arongranberg.com/astar/docs/rvosimulator.html#useNavmeshAsObstacle) option. ### Changed interface for custom graphs If you have written your own custom graph class, several methods have changed their signature. You can read more about what your code needs to do in [Writing Graph Generators](https://arongranberg.com/astar/docs/writinggraphgenerators.html) . ### Graph updates do more work asynchronously Graph updates for grid graphs and recast graphs do more work asynchronously now. This is usually a pure win as it improves your framerate. However, graph updates may take more frames to complete now, since the game can run while the graph updates are being calculated. If you want to ensure that the graph updates are done immediately, you can call [AstarPath.FlushGraphUpdates](https://arongranberg.com/astar/docs/astarpath/flushgraphupdates.html#FlushGraphUpdates) . ### Use GraphUpdateObject.ApplyJob instead of Apply for grid graphs Graph updates for grid graphs no longer call the GraphUpdateObject.Apply method; instead, the GraphUpdateObject.ApplyJob method is called. If you have been inheriting from the GraphUpdateObject to make custom graph updates, you may need to convert your code so that it works with Burst. See You may also be interested in [Writing Custom Grid Graph Rules](https://arongranberg.com/astar/docs/gridruleswrite.html) ### Batch grid node updates for better performance Due to the new burst and job system, individual node updates are a bit slower than they used to be, but batch updates can be significantly faster. If you have been updating node walkability manually like this: `var grid = AstarPath.active.data.gridGraph; grid.GetNodes(node => { if (someCondition) { node.Walkable = false; } }); grid.GetNodes(node => grid.CalculateConnections(node); ` You should now do: `var grid = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .gridGraph; grid.GetNodes(node => { if (someCondition) { node.Walkable = false; } }); grid.RecalculateAllConnections(); `Or you can use the new convenience method [GridGraph.SetWalkability](https://arongranberg.com/astar/docs/gridgraph/setwalkability.html#SetWalkability) : `// Perform the update when it is safe to do so [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) (() => { var grid = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .gridGraph; // Mark all nodes in a 10x10 square, in the top-left corner of the graph, as unwalkable. grid.SetWalkability(new bool[10*10], new IntRect(0, 0, 9, 9)); }); `Similarly, if you have been using [GridGraph.CalculateConnectionsForCellAndNeighbours](https://arongranberg.com/astar/docs/gridgraph/calculateconnectionsforcellandn.html#CalculateConnectionsForCellAndNeighbours) to update **many** nodes, I strongly recommend that you use [GridGraph.RecalculateAllConnections](https://arongranberg.com/astar/docs/gridgraph/recalculateallconnections.html#RecalculateAllConnections) or [GridGraph.RecalculateConnectionsInRegion](https://arongranberg.com/astar/docs/gridgraph/recalculateconnectionsinregion.html#RecalculateConnectionsInRegion) instead. If you have been just updating one or two nodes, then it's fine to continue using [GridGraph.CalculateConnectionsForCellAndNeighbours](https://arongranberg.com/astar/docs/gridgraph/calculateconnectionsforcellandn.html#CalculateConnectionsForCellAndNeighbours) . If you are doing more complex updates of the graph, you may instead want to write a custom grid graph rule. Grid graph rules are a new feature in 5.0 which allows you to write code that integrates much more tightly with the scanning process. This also means that they work automatically with graph updates and the [ProceduralGraphMover](https://arongranberg.com/astar/docs/proceduralgraphmover.html) component. See [Writing Custom Grid Graph Rules](https://arongranberg.com/astar/docs/gridruleswrite.html) ### Costs in hexagonal graphs were incorrectly scaled Costs between nodes in hexagonal graphs were sqrt(3/2)≈1.22 times too large. The connection costs are now approximately 1000\*the distance between the nodes, as they should be. For example, if you have set the hexagon width to 1, then the cost to move between two adjacent hexagons is now 1000 instead of 1224 like it was before. For almost all users, this will not affect anything; however, it may improve pathfinding performance a bit. If you have been using penalties on your graph, then you may have to divide them by 1.22 to get the same behavior. Similarly, if you have been using the [ConstantPath](https://arongranberg.com/astar/docs/constantpath.html) to get a set of nodes, you may have to divide the maxGScore parameter by 1.22. ### NavGraph.GetNearest now always takes constraints into account [NavGraph.GetNearest](https://arongranberg.com/astar/docs/navgraph/getnearest.html) will now always take the constraint into account. Previously, this depended on the graph type, and it was generally hard to use to get consistent results across graph types. The NavGraph.GetNearestForce method has been removed and replaced by the NavGraph.GetNearest method, as they now do the same thing. Note Not to be confused with [AstarPath.GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) , which has always taken constraints into account. ### Movement scripts no longer use Update and FixedUpdate The AIPath and RichAI scripts no longer use the Update and FixedUpdate methods. Instead, a separate script ( [BatchedEvents](https://arongranberg.com/astar/docs/batchedevents.html) ) is used which allows all components of a specific type to be processed at once. This is slightly faster and is also required for the [AIBase.rvoDensityBehavior](https://arongranberg.com/astar/docs/aibase.html#rvoDensityBehavior) implementation. If you have been overriding the Update or FixedUpdate methods, you will need to change your code to instead override the OnUpdate method. ### ProceduralGridMover is now ProceduralGraphMover The ProceduralGridMover component has been renamed to [ProceduralGraphMover](https://arongranberg.com/astar/docs/proceduralgraphmover.html) , since it now supports more than just grids. If you have been referencing it in a script, you'll need to change the name you use to reference it. ### Namespace Structure Namespace structure has been significantly improved. I have tried to keep most changes to internal classes that are not used often by users, but you may have to adjust your **using** statements slightly. Here's a summary of the changes: * [Pathfinding.Graphs.Grid](https://arongranberg.com/astar/docs/grid.html) has been added, and a lot of classes related to the grid graph have been moved there. * [Pathfinding.Graphs.Grid.Jobs](https://arongranberg.com/astar/docs/jobs.html) is new and contains a lot of internal grid scanning code. * [Pathfinding.Graphs.Grid.Rules](https://arongranberg.com/astar/docs/rules.html) is new and contains grid graph rules. * [Pathfinding.Graphs.Navmesh](https://arongranberg.com/astar/docs/navmesh.html) replaces Pathfinding.Recast. * [Pathfinding.Graphs.Navmesh.Voxelization](https://arongranberg.com/astar/docs/voxelization.html) replaces Pathfinding.Voxels. Sadly, C# doesn't support public namespace aliases, so these changes cannot be made backwards compatible. General upgrade notes --------------------- If you are having problems upgrading, try to delete the AstarPathfindingProject folder in Unity and import the package again. This can help remove old scripts which are not included in the project anymore but since UnityPackages merges directories, they are still there. If you have problems with some compiler messages saying that some members or functions do not exist in a class, it is likely that your project contains a class with that name in the global namespace. This causes a conflict between the classes. To solve it, the simplest solution is to put the conflicting class in a namespace or just rename it. --- # AstarPath - A* Pathfinding Project Class AstarPath Extends [VersionedMonoBehaviour](https://arongranberg.com/astar/docs/versionedmonobehaviour.html) ================================================================================================================== Public Core component for the A\* Pathfinding System. This class handles all of the pathfinding system, calculates all paths and stores the info. This class is a singleton class, meaning there should only exist at most one active instance of it in the scene. See [The A\* Inspector](https://arongranberg.com/astar/docs/inspector.html) [Using the AstarPath class directly](https://arongranberg.com/astar/docs/callingpathfinding.html#calling-directly) Inner Types ----------- [DebugLimitsCtx](https://arongranberg.com/astar/docs/debuglimitsctx.html) [DestroyGraphPromise](https://arongranberg.com/astar/docs/destroygraphpromise.html) [DummyGraphUpdateContext](https://arongranberg.com/astar/docs/dummygraphupdatecontext.html) Public Methods -------------- [AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html) (...) Add a work item to be processed when pathfinding is paused. [AllocateNodes](https://arongranberg.com/astar/docs/astarpath/allocatenodes.html#AllocateNodes) (result, count, createNode, variantsPerNode) Allocate a bunch of nodes at once. [DrawGizmos](https://arongranberg.com/astar/docs/astarpath/drawgizmos.html#DrawGizmos) () Calls OnDrawGizmos on all graphs. [FlushGraphUpdates](https://arongranberg.com/astar/docs/astarpath/flushgraphupdates.html#FlushGraphUpdates) () Forces graph updates to complete in a single frame. [FlushWorkItems](https://arongranberg.com/astar/docs/astarpath/flushworkitems.html#FlushWorkItems) () Forces work items to complete in a single frame. [GetNavmeshBorderData](https://arongranberg.com/astar/docs/astarpath/getnavmeshborderdata.html#GetNavmeshBorderData) (readLock) Obstacle data for navmesh edges. [GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html) (...) [GetNearestBorder](https://arongranberg.com/astar/docs/astarpath/getnearestborder.html) (position, ..., hit) Finds the closest navmesh border to the given position. [GetTagNames](https://arongranberg.com/astar/docs/astarpath/gettagnames.html#GetTagNames) () Returns tag names. [IsPointOnNavmesh](https://arongranberg.com/astar/docs/astarpath/ispointonnavmesh.html#IsPointOnNavmesh) (position) True if the point is on a walkable part of the navmesh, as seen from above. [Linecast](https://arongranberg.com/astar/docs/astarpath/linecast.html) (start, end, \[hit\]) True if there is an obstacle between **start** and **end** on the navmesh. [LockGraphDataForReading](https://arongranberg.com/astar/docs/astarpath/lockgraphdataforreading.html#LockGraphDataForReading) () Allows you to access read-only graph data in jobs safely. [LockGraphDataForWriting](https://arongranberg.com/astar/docs/astarpath/lockgraphdataforwriting.html#LockGraphDataForWriting) () Aquires an exclusive lock on the graph data asynchronously. [LockGraphDataForWritingSync](https://arongranberg.com/astar/docs/astarpath/lockgraphdataforwritingsync.html#LockGraphDataForWritingSync) () Aquires an exclusive lock on the graph data. [PausePathfinding](https://arongranberg.com/astar/docs/astarpath/pausepathfinding.html#PausePathfinding) () Blocks until all pathfinding threads are paused and blocked. [PausePathfindingSoon](https://arongranberg.com/astar/docs/astarpath/pausepathfindingsoon.html#PausePathfindingSoon) () Blocks the path queue so that e.g work items can be performed. [QueueGraphUpdates](https://arongranberg.com/astar/docs/astarpath/queuegraphupdates.html#QueueGraphUpdates) () Will apply queued graph updates as soon as possible, regardless of [batchGraphUpdates](https://arongranberg.com/astar/docs/astarpath.html#batchGraphUpdates) . [Scan](https://arongranberg.com/astar/docs/astarpath/scan.html) (\[...\]) Scans a... [ScanAsync](https://arongranberg.com/astar/docs/astarpath/scanasync.html) (\[...\]) Scans a... [Snapshot](https://arongranberg.com/astar/docs/astarpath/snapshot.html#Snapshot) (bounds, graphMask) Captures a snapshot of a part of the graphs, to allow restoring it later. [UpdateGraphs](https://arongranberg.com/astar/docs/astarpath/updategraphs.html) (..., \[delay\]) Update all graphs... Public Static Methods --------------------- [BlockUntilCalculated](https://arongranberg.com/astar/docs/astarpath/blockuntilcalculated.html#BlockUntilCalculated) (path) Blocks until the path has been calculated. [FindAstarPath](https://arongranberg.com/astar/docs/astarpath/findastarpath.html#FindAstarPath) () Used outside of play mode to initialize the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) object even if it has not been selected in the inspector yet. [FindTagNames](https://arongranberg.com/astar/docs/astarpath/findtagnames.html#FindTagNames) () Tries to find an [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) object and return tag names. [StartPath](https://arongranberg.com/astar/docs/astarpath/startpath.html#StartPath) (path, pushToFront=…, assumeInPlayMode=…) Adds the path to a queue so that it will be calculated as soon as possible. Public Variables ---------------- IsAnyGraphUpdateInProgress Returns if any graph updates are being calculated right now. Public ##### bool IsAnyGraphUpdateInProgress Returns if any graph updates are being calculated right now. Note This does \*not\* includes other types of work items such as navmesh cutting or anything added by [AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) . See [IsAnyWorkItemInProgress](https://arongranberg.com/astar/docs/astarpath.html#IsAnyWorkItemInProgress) IsAnyGraphUpdateQueued Returns if any graph updates are waiting to be applied. Public ##### bool IsAnyGraphUpdateQueued Returns if any graph updates are waiting to be applied. Note This is false while the updates are being performed. This does \*not\* includes other types of work items such as navmesh cutting or anything added by [AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) . IsAnyWorkItemInProgress Returns if any work items are in progress right now. Public ##### bool IsAnyWorkItemInProgress Returns if any work items are in progress right now. Note This includes pretty much all types of graph updates. Such as normal graph updates, navmesh cutting and anything added by [AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) . IsUsingMultithreading Returns whether or not multithreading is used. Public ##### bool IsUsingMultithreading Returns whether or not multithreading is used. Note This uses info about if threads are running right now, it does not use info from the settings on the A\* object. NumParallelThreads Number of parallel pathfinders. Public ##### int NumParallelThreads Number of parallel pathfinders. Returns the number of concurrent processes which can calculate paths at once. When using multithreading, this will be the number of threads, if not using multithreading it is always 1 (since only 1 coroutine is used). See [IsUsingMultithreading](https://arongranberg.com/astar/docs/astarpath.html#IsUsingMultithreading) batchGraphUpdates Throttle graph updates and batch them to improve performance. Public ##### bool batchGraphUpdates = false Throttle graph updates and batch them to improve performance. If toggled, graph updates will batched and executed less often (specified by [graphUpdateBatchingInterval](https://arongranberg.com/astar/docs/astarpath.html#graphUpdateBatchingInterval) ). This can have a positive impact on pathfinding throughput since the pathfinding threads do not need to be stopped as often, and it reduces the overhead per graph update. All graph updates are still applied, they are just batched together so that more of them are applied at the same time. Do not use this if you want minimal latency between a graph update being requested and it being applied. This only applies to graph updates requested using the [UpdateGraphs](https://arongranberg.com/astar/docs/astarpath/updategraphs.html#UpdateGraphs3) method. Not those requested using [AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) . If you want to apply graph updates immediately at some point, you can call [FlushGraphUpdates](https://arongranberg.com/astar/docs/astarpath/flushgraphupdates.html#FlushGraphUpdates) . See [Graph Updates during Runtime](https://arongranberg.com/astar/docs/graphupdates.html) colorSettings Reference to the color settings for this [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) object. Public ##### [AstarColor](https://arongranberg.com/astar/docs/astarcolor.html) colorSettings Reference to the color settings for this [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) object. Color settings include for example which color the nodes should be in, in the sceneview. data Holds all graph data. Public ##### [AstarData](https://arongranberg.com/astar/docs/astardata.html) data Holds all graph data. debugFloor Low value to use for certain [debugMode](https://arongranberg.com/astar/docs/astarpath.html#debugMode) modes. Public ##### float debugFloor = 0 Low value to use for certain [debugMode](https://arongranberg.com/astar/docs/astarpath.html#debugMode) modes. For example if [debugMode](https://arongranberg.com/astar/docs/astarpath.html#debugMode) is set to G, this value will determine when the node will be completely red. Note Only relevant in the editor See [debugRoof](https://arongranberg.com/astar/docs/astarpath.html#debugRoof) [debugMode](https://arongranberg.com/astar/docs/astarpath.html#debugMode) debugMode The mode to use for drawing nodes in the sceneview. Public ##### [GraphDebugMode](https://arongranberg.com/astar/docs/pathfinding.html#GraphDebugMode) debugMode The mode to use for drawing nodes in the sceneview. Note Only relevant in the editor See [GraphDebugMode](https://arongranberg.com/astar/docs/pathfinding.html#GraphDebugMode) debugRoof High value to use for certain [debugMode](https://arongranberg.com/astar/docs/astarpath.html#debugMode) modes. Public ##### float debugRoof = 20000 High value to use for certain [debugMode](https://arongranberg.com/astar/docs/astarpath.html#debugMode) modes. For example if [debugMode](https://arongranberg.com/astar/docs/astarpath.html#debugMode) is set to G, this value will determine when the node will be completely green. For the penalty debug mode, the nodes will be colored green when they have a penalty less than [debugFloor](https://arongranberg.com/astar/docs/astarpath.html#debugFloor) and red when their penalty is greater or equal to this value and something between red and green otherwise. Note Only relevant in the editor See [debugFloor](https://arongranberg.com/astar/docs/astarpath.html#debugFloor) [debugMode](https://arongranberg.com/astar/docs/astarpath.html#debugMode) effectiveHeuristicScale The effective heuristic scale. Public ##### float effectiveHeuristicScale The effective heuristic scale. This is the heuristic scale used for pathfinding. Zero is returned if [heuristic](https://arongranberg.com/astar/docs/astarpath.html#heuristic) is set to None, otherwise [heuristicScale](https://arongranberg.com/astar/docs/astarpath.html#heuristicScale) is returned. See [heuristic](https://arongranberg.com/astar/docs/astarpath.html#heuristic) euclideanEmbedding Holds settings for heuristic optimization. Public ##### [EuclideanEmbedding](https://arongranberg.com/astar/docs/euclideanembedding.html) euclideanEmbedding = new [EuclideanEmbedding](https://arongranberg.com/astar/docs/euclideanembedding.html) () Holds settings for heuristic optimization. See [Heuristic Optimization](https://arongranberg.com/astar/docs/heuristicopt.html) A\* Pro Feature This is an A\* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A\* Pathfinding Project or the functionality might be limited. The Pro version can be bought [here](http://www.arongranberg.com/astar/buy) fullGetNearestSearch Do a full GetNearest search for all graphs. Public ##### bool fullGetNearestSearch = false Do a full GetNearest search for all graphs. Additional searches will normally only be done on the graph which in the first fast search seemed to have the closest node. With this setting on, additional searches will be done on all graphs since the first check is not always completely accurate. More technically: GetNearestForce on all graphs will be called if true, otherwise only on the one graph which's GetNearest search returned the best node. Usually faster when disabled, but higher quality searches when enabled. Note For the PointGraph this setting doesn't matter much as it has only one search mode. graphUpdateBatchingInterval Minimum number of seconds between each batch of graph updates. Public ##### float graphUpdateBatchingInterval = 0.2F Minimum number of seconds between each batch of graph updates. If [batchGraphUpdates](https://arongranberg.com/astar/docs/astarpath.html#batchGraphUpdates) is true, this defines the minimum number of seconds between each batch of graph updates. This can have a positive impact on pathfinding throughput since the pathfinding threads do not need to be stopped as often, and it reduces the overhead per graph update. All graph updates are still applied however, they are just batched together so that more of them are applied at the same time. Do not use this if you want minimal latency between a graph update being requested and it being applied. This only applies to graph updates requested using the [UpdateGraphs](https://arongranberg.com/astar/docs/astarpath/updategraphs.html#UpdateGraphs3) method. Not those requested using [AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) . See [Graph Updates during Runtime](https://arongranberg.com/astar/docs/graphupdates.html) graphUpdateDebugMode How to visualize graph updates in the editor. Public ##### [GraphUpdateDebugMode](https://arongranberg.com/astar/docs/pathfinding.html#GraphUpdateDebugMode) graphUpdateDebugMode = GraphUpdateDebugMode.Nothing How to visualize graph updates in the editor. This is used to visualize the bounds of graph updates, and how they affect the graph. If [showGraphsInStandalonePlayer](https://arongranberg.com/astar/docs/astarpath.html#showGraphsInStandalonePlayer) is enabled, the visualization will also be shown in a standalone player. ![](https://arongranberg.com/astar/docs/images/graph_update_debug_mode_inspector@2x.png) ![](https://arongranberg.com/astar/docs/images/graph_update_debug_mode.png) See [GraphUpdateDebugMode](https://arongranberg.com/astar/docs/pathfinding.html#GraphUpdateDebugMode) for more info about the different modes. graphs Shortcut to [AstarData.graphs](https://arongranberg.com/astar/docs/astardata.html#graphs) . Public ##### [NavGraph](https://arongranberg.com/astar/docs/navgraph.html) \[\] graphs Shortcut to [AstarData.graphs](https://arongranberg.com/astar/docs/astardata.html#graphs) . heuristic The distance function to use as a heuristic. Public ##### [Heuristic](https://arongranberg.com/astar/docs/pathfinding.html#Heuristic) heuristic = Heuristic.Euclidean The distance function to use as a heuristic. The heuristic, often referred to as just 'H' is the estimated cost from a node to the target. Different heuristics affect how the path picks which one to follow from multiple possible with the same length See [Pathfinding.Heuristic](https://arongranberg.com/astar/docs/pathfinding.html#Heuristic) for more details and descriptions of the different modes. [Wikipedia: Admissible heuristic](https://en.wikipedia.org/wiki/Admissible_heuristic) [Wikipedia: A\* search algorithm](https://en.wikipedia.org/wiki/A*_search_algorithm) [Wikipedia: Dijkstra's Algorithm](https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm) Warning Reducing the heuristic scale below 1, or disabling the heuristic, can significantly increase the cpu cost for pathfinding, especially for large graphs. heuristicScale The scale of the heuristic. Public ##### float heuristicScale = 1F The scale of the heuristic. If a value lower than 1 is used, the pathfinder will search more nodes (slower). If 0 is used, the pathfinding algorithm will be reduced to dijkstra's algorithm. This is equivalent to setting [heuristic](https://arongranberg.com/astar/docs/astarpath.html#heuristic) to None. If a value larger than 1 is used the pathfinding will (usually) be faster because it expands fewer nodes, but the paths may no longer be the optimal (i.e the shortest possible paths). Usually you should leave this to the default value of 1. Warning Reducing the heuristic scale below 1, or disabling the heuristic, can significantly increase the cpu cost for pathfinding, especially for large graphs. See [Wikipedia: Admissible heuristic](https://en.wikipedia.org/wiki/Admissible_heuristic) [Wikipedia: A\* search algorithm](https://en.wikipedia.org/wiki/A*_search_algorithm) [Wikipedia: Dijkstra's Algorithm](https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm) isScanning True while any graphs are being scanned. Public ##### bool isScanning True while any graphs are being scanned. This is primarily relevant when scanning graph asynchronously. Note Not to be confused with graph updates. This will be false during [OnLatePostScan](https://arongranberg.com/astar/docs/astarpath.html#OnLatePostScan) and during the [GraphModifier.EventType](https://arongranberg.com/astar/docs/graphmodifier.html#EventType) .LatePostScan event. See [IsAnyGraphUpdateQueued](https://arongranberg.com/astar/docs/astarpath.html#IsAnyGraphUpdateQueued) [IsAnyGraphUpdateInProgress](https://arongranberg.com/astar/docs/astarpath.html#IsAnyGraphUpdateInProgress) lastScanTime The time it took for the last call to [Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) to complete. Public ##### float lastScanTime The time it took for the last call to [Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) to complete. logPathResults The amount of debugging messages. Public ##### [PathLog](https://arongranberg.com/astar/docs/pathfinding.html#PathLog) logPathResults = PathLog.Normal The amount of debugging messages. Use less debugging to improve performance (a bit) or just to get rid of the Console spamming. Use more debugging (heavy) if you want more information about what the pathfinding scripts are doing. The InGame option will display the latest path log using in-game GUI. ![](https://arongranberg.com/astar/docs/images/path_logging@2x.png) manualDebugFloorRoof If set, the [debugFloor](https://arongranberg.com/astar/docs/astarpath.html#debugFloor) and [debugRoof](https://arongranberg.com/astar/docs/astarpath.html#debugRoof) values will not be automatically recalculated. Public ##### bool manualDebugFloorRoof = false If set, the [debugFloor](https://arongranberg.com/astar/docs/astarpath.html#debugFloor) and [debugRoof](https://arongranberg.com/astar/docs/astarpath.html#debugRoof) values will not be automatically recalculated. Note Only relevant in the editor maxFrameTime Max number of milliseconds to spend on pathfinding during each frame. Public ##### float maxFrameTime = 1F Max number of milliseconds to spend on pathfinding during each frame. At least 500 nodes will be searched each frame (if there are that many to search). When using multithreading this value is irrelevant. maxNearestNodeDistance Maximum distance to search for nodes. Public ##### float maxNearestNodeDistance = 100 Maximum distance to search for nodes. When searching for the nearest node to a point, this is the limit (in world units) for how far away it is allowed to be. This is relevant if you try to request a path to a point that cannot be reached and it thus has to search for the closest node to that point which can be reached (which might be far away). If it cannot find a node within this distance then the path will fail. ![](https://arongranberg.com/astar/docs/images/max_nearest_node_distance@2x.png) See [NearestNodeConstraint.maxDistance](https://arongranberg.com/astar/docs/nearestnodeconstraint.html#maxDistance) maxNearestNodeDistanceSqr Max Nearest Node Distance Squared. Public ##### float maxNearestNodeDistanceSqr Max Nearest Node Distance Squared. See [maxNearestNodeDistance](https://arongranberg.com/astar/docs/astarpath.html#maxNearestNodeDistance) navmeshUpdates Handles navmesh cuts. Public ##### [NavmeshUpdates](https://arongranberg.com/astar/docs/navmeshupdates.html) navmeshUpdates = new [NavmeshUpdates](https://arongranberg.com/astar/docs/navmeshupdates.html) () Handles navmesh cuts. See [Pathfinding.NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) offMeshLinks Holds all active off-mesh links. Public Readonly ##### [OffMeshLinks](https://arongranberg.com/astar/docs/offmeshlinks.html) offMeshLinks Holds all active off-mesh links. scanOnStartup If true, all graphs will be scanned when the game starts, during OnEnable. Public ##### bool scanOnStartup = true If true, all graphs will be scanned when the game starts, during OnEnable. If you disable this, you will have to call [AstarPath.active.Scan](https://arongranberg.com/astar/docs/astarpath/scan.html) yourself to enable pathfinding. Alternatively you could load a saved graph from a file. If a startup cache has been generated (see [Saving and Loading Graphs](https://arongranberg.com/astar/docs/saveloadgraphs.html) ), it always takes priority, and the graphs will be loaded from the cache instead of scanned. This can be useful to disable if you want to scan your graphs asynchronously, or if you have a procedural world which has not been created yet at the start of the game. See [Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) [ScanAsync](https://arongranberg.com/astar/docs/astarpath/scanasync.html#ScanAsync) showGraphs Shows or hides graph inspectors. Public ##### bool showGraphs = false Shows or hides graph inspectors. Used internally by the editor. See [showNavGraphs](https://arongranberg.com/astar/docs/astarpath.html#showNavGraphs) [showGraphsInStandalonePlayer](https://arongranberg.com/astar/docs/astarpath.html#showGraphsInStandalonePlayer) showGraphsInStandalonePlayer Shows or hides the graph visualizations in standalone games. Public ##### bool showGraphsInStandalonePlayer = false Shows or hides the graph visualizations in standalone games. Normally, graph visualizations are only shown in the editor. If this is set to true, the graph visualizations will also be shown in standalone games. Note In the editor, this setting has no effect. [showNavGraphs](https://arongranberg.com/astar/docs/astarpath.html#showNavGraphs) will be ignored in standalone builds, and this value will be used instead. See [NavGraph.drawGizmos](https://arongranberg.com/astar/docs/navgraph.html#drawGizmos) showNavGraphs Visualize graphs in the scene view (editor only). Public ##### bool showNavGraphs = true Visualize graphs in the scene view (editor only). ![](https://arongranberg.com/astar/docs/images/navmeshgraph_graph.png) See [showGraphsInStandalonePlayer](https://arongranberg.com/astar/docs/astarpath.html#showGraphsInStandalonePlayer) showSearchTree If enabled, nodes will draw a line to their 'parent'. Public ##### bool showSearchTree = false If enabled, nodes will draw a line to their 'parent'. This will show the search tree for the latest path. Note Only relevant in the editor showUnwalkableNodes Toggle to show unwalkable nodes. Public ##### bool showUnwalkableNodes = true Toggle to show unwalkable nodes. Note Only relevant in the editor See [unwalkableNodeDebugSize](https://arongranberg.com/astar/docs/astarpath.html#unwalkableNodeDebugSize) threadCount Number of pathfinding threads to use. Public ##### [ThreadCount](https://arongranberg.com/astar/docs/pathfinding.html#ThreadCount) threadCount = ThreadCount.One Number of pathfinding threads to use. Multithreading puts pathfinding in another thread, this is great for performance on 2+ core computers since the framerate will barely be affected by the pathfinding at all. * None indicates that the pathfinding is run in the Unity thread as a coroutine * Automatic will try to adjust the number of threads to the number of cores and memory on the computer. Less than 512mb of memory or a single core computer will make it revert to using no multithreading. It is recommended that you use one of the "Auto" settings that are available. The reason is that even if your computer might be beefy and have 8 cores. Other computers might only be quad core or dual core in which case they will not benefit from more than 1 or 3 threads respectively (you usually want to leave one core for the unity thread). If you use more threads than the number of cores on the computer it is mostly just wasting memory, it will not run any faster. The extra memory usage is not trivially small. Each thread needs to keep a small amount of data for each node in all the graphs. It is not the full graph data but it is proportional to the number of nodes. The automatic settings will inspect the machine it is running on and use that to determine the number of threads so that no memory is wasted. The exception is if you only have one (or maybe two characters) active at time. Then you should probably just go with one thread always since it is very unlikely that you will need the extra throughput given by more threads. Keep in mind that more threads primarily increases throughput by calculating different paths on different threads, it will not calculate individual paths any faster. Warning If you are modifying the pathfinding core scripts or if you are directly modifying graph data without using any of the safe wrappers (like [AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) ), multithreading can cause strange errors and cause pathfinding to stop working if you are not careful. Note WebGL does not support threads at all (since javascript is single-threaded) so no threads will be used on that platform. This setting only applies to pathfinding. Graph updates use the Unity Job System, which uses a different thread pool. See CalculateThreadCount A\* Pro Feature This is an A\* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A\* Pathfinding Project or the functionality might be limited. The Pro version can be bought [here](http://www.arongranberg.com/astar/buy) unwalkableNodeDebugSize Size of the red cubes shown in place of unwalkable nodes. Public ##### float unwalkableNodeDebugSize = 0.3F Size of the red cubes shown in place of unwalkable nodes. Note Only relevant in the editor. Does not apply to grid graphs. See [showUnwalkableNodes](https://arongranberg.com/astar/docs/astarpath.html#showUnwalkableNodes) Public Static Variables ----------------------- Branch Which branch of the A\* Pathfinding Project is this release. Public Static Readonly ##### string Branch = "master" Which branch of the A\* Pathfinding Project is this release. Used when checking for updates so that users of the development versions can get notifications of development updates. Distribution Used by the editor to guide the user to the correct place to download updates. Public Static Readonly ##### [AstarDistribution](https://arongranberg.com/astar/docs/astarpath.html#AstarDistribution) Distribution = AstarDistribution.PackageManager Used by the editor to guide the user to the correct place to download updates. On65KOverflow Called when **pathID** overflows 65536 and resets back to zero. Public Static ##### System.Action On65KOverflow Called when **pathID** overflows 65536 and resets back to zero. Note This callback will be cleared every time it is called, so if you want to register to it repeatedly, register to it directly on receiving the callback as well. OnAwakeSettings Called on Awake before anything else is done. Public Static ##### System.Action OnAwakeSettings Called on Awake before anything else is done. This is called at the start of the Awake call, right after [active](https://arongranberg.com/astar/docs/astarpath.html#active) has been set, but this is the only thing that has been done. Use this when you want to set up default settings for an [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component created during runtime since some settings can only be changed in Awake (such as multithreading related stuff) `// Create a new AstarPath object on Start and apply some default settings public void Start () { [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[OnAwakeSettings](https://arongranberg.com/astar/docs/astarpath.html#OnAwakeSettings) += ApplySettings; [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) astar = gameObject.AddComponent<[AstarPath](https://arongranberg.com/astar/docs/astarpath.html) >(); } public void ApplySettings () { // Unregister from the delegate [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[OnAwakeSettings](https://arongranberg.com/astar/docs/astarpath.html#OnAwakeSettings) -= ApplySettings; // For example threadCount should not be changed after the Awake call // so here's the only place to set it if you create the component during runtime [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[threadCount](https://arongranberg.com/astar/docs/astarpath.html#threadCount) = [ThreadCount](https://arongranberg.com/astar/docs/pathfinding.html#ThreadCount) .One; } ` OnGraphPostScan Called for each graph after they have been scanned. Public Static ##### OnGraphDelegate OnGraphPostScan Called for each graph after they have been scanned. All other graphs might not have been scanned yet. In most cases it is recommended to create a custom class which inherits from [Pathfinding.GraphModifier](https://arongranberg.com/astar/docs/graphmodifier.html) instead. OnGraphPreScan Called for each graph before they are scanned. Public Static ##### OnGraphDelegate OnGraphPreScan Called for each graph before they are scanned. In most cases it is recommended to create a custom class which inherits from [Pathfinding.GraphModifier](https://arongranberg.com/astar/docs/graphmodifier.html) instead. OnGraphsUpdated Called when any graphs are updated. Public Static ##### OnScanDelegate OnGraphsUpdated Called when any graphs are updated. Register to for example recalculate the path whenever a graph changes. In most cases it is recommended to create a custom class which inherits from [Pathfinding.GraphModifier](https://arongranberg.com/astar/docs/graphmodifier.html) instead. OnLatePostScan Called after scanning has completed fully. Public Static ##### OnScanDelegate OnLatePostScan Called after scanning has completed fully. This is called as the last thing in the Scan function. In most cases it is recommended to create a custom class which inherits from [Pathfinding.GraphModifier](https://arongranberg.com/astar/docs/graphmodifier.html) instead. OnPathPostSearch Called for each path after searching. Public Static ##### OnPathDelegate OnPathPostSearch Called for each path after searching. Be careful when using multithreading since this will be called from a different thread. OnPathPreSearch Called for each path before searching. Public Static ##### OnPathDelegate OnPathPreSearch Called for each path before searching. Be careful when using multithreading since this will be called from a different thread. OnPathsCalculated Called right after callbacks on paths have been called. Public Static ##### System.Action OnPathsCalculated Called right after callbacks on paths have been called. A path's callback function runs on the main thread when the path has been calculated. This is done in batches for all paths that have finished their calculation since the last frame. This event will trigger right after a batch of callbacks have been called. If you do not want to use individual path callbacks, you can use this instead to poll all pending paths and see which ones have completed. This is better than doing it in e.g. the Update loop, because here you will have a guarantee that all calculated paths are still valid. Immediately after this callback has finished, other things may invalidate calculated paths, like for example graph updates. This is used by the ECS integration to update all entities' pending paths, without having to store a callback for each agent, and also to avoid the ECS synchronization overhead that having individual callbacks would entail. OnPostScan Called after scanning. Public Static ##### OnScanDelegate OnPostScan Called after scanning. This is called before applying links, flood-filling the graphs and other post processing. In most cases it is recommended to create a custom class which inherits from [Pathfinding.GraphModifier](https://arongranberg.com/astar/docs/graphmodifier.html) instead. OnPreScan Called before starting the scanning. Public Static ##### OnScanDelegate OnPreScan Called before starting the scanning. In most cases it is recommended to create a custom class which inherits from [Pathfinding.GraphModifier](https://arongranberg.com/astar/docs/graphmodifier.html) instead. Version The version number for the A\* Pathfinding Project. Public Static Readonly ##### System.Version Version = new System.Version(5, 4, 5) The version number for the A\* Pathfinding Project. active Returns the active [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) object in the scene. Public Static ##### [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) active Returns the active [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) object in the scene. Note This is only set if the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) object has been initialized (which happens in Awake). Public Enums ------------ AstarDistribution Information about where the package was downloaded. Public ##### AstarDistribution | | | | --- | --- | | WebsiteDownload | | | AssetStore | | | PackageManager | | Information about where the package was downloaded. Private/Protected Members ------------------------- [AstarPath](https://arongranberg.com/astar/docs/astarpath/astarpath.html#AstarPath) () [Awake](https://arongranberg.com/astar/docs/versionedmonobehaviour/awake.html#Awake) () [BlockUntilAsyncScanComplete](https://arongranberg.com/astar/docs/astarpath/blockuntilasyncscancomplete.html#BlockUntilAsyncScanComplete) () Blocks until the currently running async scan (if any) has completed. [ClosestRaycastableGraph](https://arongranberg.com/astar/docs/astarpath/closestraycastablegraph.html#ClosestRaycastableGraph) (point) [DestroyNode](https://arongranberg.com/astar/docs/astarpath/destroynode.html#DestroyNode) (node) Internal method to destroy a given node. [DirtyBounds](https://arongranberg.com/astar/docs/astarpath/dirtybounds.html#DirtyBounds) (bounds) [GetNextPathID](https://arongranberg.com/astar/docs/astarpath/getnextpathid.html#GetNextPathID) () Returns the next free path ID. [InitializeColors](https://arongranberg.com/astar/docs/astarpath/initializecolors.html#InitializeColors) () [InitializeNode](https://arongranberg.com/astar/docs/astarpath/initializenode.html#InitializeNode) (node) Initializes temporary path data for a node. [InitializeNodes](https://arongranberg.com/astar/docs/astarpath/initializenodes.html#InitializeNodes) (nodes) [InitializePathProcessor](https://arongranberg.com/astar/docs/astarpath/initializepathprocessor.html#InitializePathProcessor) () Initializes the [pathProcessor](https://arongranberg.com/astar/docs/astarpath.html#pathProcessor) field. IsInsideWorkItem Returns if this code is currently being exectuted inside a work item. Internal ##### bool IsInsideWorkItem Returns if this code is currently being exectuted inside a work item. Note This includes pretty much all types of graph updates. Such as normal graph updates, navmesh cutting and anything added by [AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) . In contrast to [IsAnyWorkItemInProgress](https://arongranberg.com/astar/docs/astarpath.html#IsAnyWorkItemInProgress) this is only true when work item code is being executed, it is not true in-between the updates to a work item that takes several frames to complete. [LogPathResults](https://arongranberg.com/astar/docs/astarpath/logpathresults.html#LogPathResults) (debugStringBuilder, path) Prints path results to the log. [OnDestroy](https://arongranberg.com/astar/docs/astarpath/ondestroy.html#OnDestroy) () Clears up variables and other stuff, destroys graphs. [OnDisable](https://arongranberg.com/astar/docs/astarpath/ondisable.html#OnDisable) () Cleans up graphs to avoid memory leaks. [OnEnable](https://arongranberg.com/astar/docs/astarpath/onenable.html#OnEnable) () Called after this component is enabled. [OnGUI](https://arongranberg.com/astar/docs/astarpath/ongui.html#OnGUI) () Draws the InGame debugging (if enabled) [OnUpgradeSerializedData](https://arongranberg.com/astar/docs/versionedmonobehaviour/onupgradeserialize.html#OnUpgradeSerializedData) (migrations, unityThread) Handle serialization backwards compatibility. [PerformBlockingActions](https://arongranberg.com/astar/docs/astarpath/performblockingactions.html#PerformBlockingActions) (force=…) [RecalculateDebugLimits](https://arongranberg.com/astar/docs/astarpath/recalculatedebuglimits.html#RecalculateDebugLimits) () [Reset](https://arongranberg.com/astar/docs/versionedmonobehaviour/reset.html#Reset) () Handle serialization backwards compatibility. [ScanInternal](https://arongranberg.com/astar/docs/astarpath/scaninternal.html#ScanInternal) (graphsToScan, async) [ShutdownPathfindingThreads](https://arongranberg.com/astar/docs/astarpath/shutdownpathfindingthreads.html#ShutdownPathfindingThreads) () [TickAsyncScanUntilCompletion](https://arongranberg.com/astar/docs/astarpath/tickasyncscanuntilcompletion.html#TickAsyncScanUntilCompletion) (task) [TryQueueGraphUpdates](https://arongranberg.com/astar/docs/astarpath/tryqueuegraphupdates.html#TryQueueGraphUpdates) () Calls [QueueGraphUpdates](https://arongranberg.com/astar/docs/astarpath/queuegraphupdates.html#QueueGraphUpdates) , unless we should wait for a larger batch. [Update](https://arongranberg.com/astar/docs/astarpath/update.html#Update) () Checks if any work items need to be executed then runs pathfinding for a while (if not using multithreading because then the calculation happens in other threads) and then returns any calculated paths to the scripts that requested them. [UpdateGraphsInternal](https://arongranberg.com/astar/docs/astarpath/updategraphsinternal.html#UpdateGraphsInternal) (ob, delay) Update all graphs using the GraphUpdateObject after **delay** seconds. [UpgradeSerializedData](https://arongranberg.com/astar/docs/versionedmonobehaviour/upgradeserializedd.html#UpgradeSerializedData) (isUnityThread) [VisualizeOriginalGraphUpdateBounds](https://arongranberg.com/astar/docs/astarpath/visualizeoriginalgraphupdatebou.html#VisualizeOriginalGraphUpdateBounds) (bounds) asyncScanTask If an async scan is running, this will be set to the coroutine. Private ##### IEnumerator<[Progress](https://arongranberg.com/astar/docs/progress.html) \> asyncScanTask If an async scan is running, this will be set to the coroutine. This primarily used to be able to force the async scan to complete immediately, if the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component should happen to be destroyed while an async scan is running. debugPathData The path to debug using gizmos. Internal ##### [PathHandler](https://arongranberg.com/astar/docs/pathhandler.html) debugPathData The path to debug using gizmos. This is the path handler used to calculate the last path. It is used in the editor to draw debug information using gizmos. debugPathID The path ID to debug using gizmos. Internal ##### ushort debugPathID The path ID to debug using gizmos. graphDataLock Global read-write lock for graph data. Private ##### [RWLock](https://arongranberg.com/astar/docs/rwlock.html) graphDataLock = new [RWLock](https://arongranberg.com/astar/docs/rwlock.html) () Global read-write lock for graph data. Graph data is always consistent from the main-thread's perspective, but if you are using jobs to read from graph data, you may need this. A write lock is held automatically... * During graph updates. During async graph updates, the lock is only held once per frame while the graph update is actually running, not for the whole duration. * During work items. Async work items work similarly to graph updates, the lock is only held once per frame while the work item is actually running. * When [GraphModifier](https://arongranberg.com/astar/docs/graphmodifier.html) events run. * When graph related callbacks, such as [OnGraphsUpdated](https://arongranberg.com/astar/docs/astarpath.html#OnGraphsUpdated) , run. * During the last step of a graph's scanning process, when the new graph data is being made visible to the rest of the game. See [ScanningStage](https://arongranberg.com/astar/docs/pathfinding.html#ScanningStage) . To use e.g. AstarPath.active.GetNearest from an ECS job, you'll need to acquire a read lock first, and make sure the lock is only released when the job is finished. `var readLock = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[LockGraphDataForReading](https://arongranberg.com/astar/docs/astarpath/lockgraphdataforreading.html#LockGraphDataForReading) (); var handle = new MyJob { // ... }.Schedule(readLock.dependency); readLock.UnlockAfter(handle); ` See [LockGraphDataForReading](https://arongranberg.com/astar/docs/astarpath/lockgraphdataforreading.html#LockGraphDataForReading) graphUpdates Processes graph updates. Private Readonly ##### [GraphUpdateProcessor](https://arongranberg.com/astar/docs/graphupdateprocessor.html) graphUpdates Processes graph updates. graphUpdatesWorkItemAdded Makes sure QueueGraphUpdates will not queue multiple graph update orders. Private ##### bool graphUpdatesWorkItemAdded = false Makes sure QueueGraphUpdates will not queue multiple graph update orders. hasScannedGraphAtStartup Private ##### bool hasScannedGraphAtStartup = false hierarchicalGraph Holds a hierarchical graph to speed up some queries like if there is a path between two nodes. Internal Readonly ##### [HierarchicalGraph](https://arongranberg.com/astar/docs/hierarchicalgraph.html) hierarchicalGraph Holds a hierarchical graph to speed up some queries like if there is a path between two nodes. inGameDebugPath Debug string from the last completed path. Private ##### string inGameDebugPath Debug string from the last completed path. Will be updated if [logPathResults](https://arongranberg.com/astar/docs/astarpath.html#logPathResults) == PathLog.InGame lastGraphUpdate Time the last graph update was done. Private ##### float lastGraphUpdate = float.NegativeInfinity Time the last graph update was done. Used to group together frequent graph updates to batches nextFreePathID The next unused Path ID. Private ##### ushort nextFreePathID = 1 The next unused Path ID. Incremented for every call to GetNextPathID nodeStorage Holds global node data that cannot be stored in individual graphs. Internal ##### [GlobalNodeStorage](https://arongranberg.com/astar/docs/globalnodestorage.html) nodeStorage Holds global node data that cannot be stored in individual graphs. pathProcessor Holds all paths waiting to be calculated and calculates them. Internal Readonly ##### [PathProcessor](https://arongranberg.com/astar/docs/pathprocessor.html) pathProcessor Holds all paths waiting to be calculated and calculates them. pathReturnQueue Holds all completed paths waiting to be returned to where they were requested. Internal Readonly ##### [PathReturnQueue](https://arongranberg.com/astar/docs/pathreturnqueue.html) pathReturnQueue Holds all completed paths waiting to be returned to where they were requested. tagNames Stored tag names. Protected ##### string\[\] tagNames = null Stored tag names. See [AstarPath.FindTagNames](https://arongranberg.com/astar/docs/astarpath/findtagnames.html#FindTagNames) [AstarPath.GetTagNames](https://arongranberg.com/astar/docs/astarpath/gettagnames.html#GetTagNames) waitForPathDepth Private Static ##### int waitForPathDepth = 0 workItemLock Held if any work items are currently queued. Private ##### [PathProcessor.GraphUpdateLock](https://arongranberg.com/astar/docs/graphupdatelock.html) workItemLock Held if any work items are currently queued. workItems Processes work items. Private Readonly ##### [WorkItemProcessor](https://arongranberg.com/astar/docs/workitemprocessor.html) workItems Processes work items. Deprecated Members ------------------ prioritizeGraphs Prioritize graphs. Public ##### bool prioritizeGraphs = false Prioritize graphs. Graphs will be prioritized based on their order in the inspector. The first graph which has a node closer than [prioritizeGraphsLimit](https://arongranberg.com/astar/docs/astarpath.html#prioritizeGraphsLimit) will be chosen instead of searching all graphs. Deprecated This setting has been removed. It was always a bit of a hack. Use TraversalConstraint.graphMask if you want to choose which graphs are searched. prioritizeGraphsLimit Distance limit for [prioritizeGraphs](https://arongranberg.com/astar/docs/astarpath.html#prioritizeGraphs) . Public ##### float prioritizeGraphsLimit = 1F Distance limit for [prioritizeGraphs](https://arongranberg.com/astar/docs/astarpath.html#prioritizeGraphs) . See [prioritizeGraphs](https://arongranberg.com/astar/docs/astarpath.html#prioritizeGraphs) Deprecated This setting has been removed. It was always a bit of a hack. Use TraversalConstraint.graphMask if you want to choose which graphs are searched. --- # Classes - A* Pathfinding Project Classes ======= * [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) * [Collections](https://arongranberg.com/astar/docs/collections.html) * [AABBTree](https://arongranberg.com/astar/docs/aabbtree.html) Axis Aligned Bounding Box Tree. * [AABBComparer](https://arongranberg.com/astar/docs/aabbcomparer.html) * [Key](https://arongranberg.com/astar/docs/key.html) A key to a leaf node in the tree. * [Node](https://arongranberg.com/astar/docs/node.html) * [BBTree](https://arongranberg.com/astar/docs/bbtree.html) Axis Aligned Bounding Box Tree. * [BBTreeBox](https://arongranberg.com/astar/docs/bbtreebox.html) * [CloseNode](https://arongranberg.com/astar/docs/closenode.html) * [NearbyNodesIterator](https://arongranberg.com/astar/docs/nearbynodesiterator.html) * [BoxWithDist](https://arongranberg.com/astar/docs/boxwithdist.html) * [ProjectionParams](https://arongranberg.com/astar/docs/projectionparams.html) * [CircularBuffer](https://arongranberg.com/astar/docs/circularbuffer.html) Implements an efficient circular buffer that can be appended to in both directions. * [GridLookup](https://arongranberg.com/astar/docs/gridlookup.html) Holds a lookup datastructure to quickly find objects inside rectangles. * [Item](https://arongranberg.com/astar/docs/item.html) * [Root](https://arongranberg.com/astar/docs/root.html) * [HierarchicalBitset](https://arongranberg.com/astar/docs/hierarchicalbitset.html) Thread-safe hierarchical bitset. * [Iterator](https://arongranberg.com/astar/docs/iterator.html) * [NativeCircularBuffer](https://arongranberg.com/astar/docs/nativecircularbuffer.html) Implements an efficient circular buffer that can be appended to in both directions. * [SlabAllocator](https://arongranberg.com/astar/docs/slaballocator.html) A tiny slab allocator. * [AllocatorData](https://arongranberg.com/astar/docs/allocatordata.html) * [Header](https://arongranberg.com/astar/docs/header.html) * [List](https://arongranberg.com/astar/docs/list.html) * [NextBlock](https://arongranberg.com/astar/docs/nextblock.html) * [SlabListExtensions](https://arongranberg.com/astar/docs/slablistextensions.html) * [SpanExtensions](https://arongranberg.com/astar/docs/spanextensions.html) * [UnsafeSpan](https://arongranberg.com/astar/docs/unsafespan.html) Replacement for System.Span which is compatible with earlier versions of C#. * [ECS](https://arongranberg.com/astar/docs/ecs2.html) * [RVO](https://arongranberg.com/astar/docs/rvo.html) * [AgentIndex](https://arongranberg.com/astar/docs/agentindex.html) Index of an [RVO](https://arongranberg.com/astar/docs/rvo.html) agent in the local avoidance simulation. * [RVOAgent](https://arongranberg.com/astar/docs/rvoagent.html) Agent data for the local avoidance system. * [RVOSystem](https://arongranberg.com/astar/docs/rvosystem.html) Simulates local avoidance in an [ECS](https://arongranberg.com/astar/docs/ecs2.html) context. * [JobCopyFromEntitiesToRVOSimulator](https://arongranberg.com/astar/docs/jobcopyfromentitiestorvosimulator.html) * [JobCopyFromRVOSimulatorToEntities](https://arongranberg.com/astar/docs/jobcopyfromrvosimulatortoentities.html) * [AgentCylinderShape](https://arongranberg.com/astar/docs/agentcylindershape.html) An agent's shape represented as a cylinder. * [AgentMovementPlane](https://arongranberg.com/astar/docs/agentmovementplane.html) Holds an agent's movement plane. * [AgentMovementPlaneSource](https://arongranberg.com/astar/docs/agentmovementplanesource.html) The movement plane source for an agent. * [AgentOffMeshLinkLocalAvoidanceDisabled](https://arongranberg.com/astar/docs/agentoffmeshlinklocalavoidancedisabled.html) Component which is enabled when the agent is traversing an off-mesh link, and the local avoidance logic should be disabled. * [AgentOffMeshLinkMovementDisabled](https://arongranberg.com/astar/docs/agentoffmeshlinkmovementdisabled.html) Component which is enabled when the agent is traversing an off-mesh link, and the built-in movement logic should be disabled. * [AgentOffMeshLinkTraversal](https://arongranberg.com/astar/docs/agentoffmeshlinktraversal.html) Holds unmanaged information about an off-mesh link that the agent is currently traversing. * [AgentOffMeshLinkTraversalContext](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext.html) Context with helpers for traversing an off-mesh link. * [AbortOffMeshLinkTraversal](https://arongranberg.com/astar/docs/abortoffmeshlinktraversal.html) Thrown when the off-mesh link traversal should be aborted. * [AgentShouldRecalculatePath](https://arongranberg.com/astar/docs/agentshouldrecalculatepath.html) Tag component which, when enabled, indicates that the agent should recalculate its path immediately. * [AIGizmosSystem](https://arongranberg.com/astar/docs/aigizmossystem.html) Draws gizmos and debug information for [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) agents. * [DrawerCallback](https://arongranberg.com/astar/docs/drawercallback.html) * [AIMovementSystemGroup](https://arongranberg.com/astar/docs/aimovementsystemgroup.html) * [TimeScaledRateManager](https://arongranberg.com/astar/docs/timescaledratemanager.html) Rate manager which runs a system group multiple times if the delta time is higher than desired, but always executes the group at least once per frame. * [AIMoveSystem](https://arongranberg.com/astar/docs/aimovesystem.html) * [AutoRepathPolicy](https://arongranberg.com/astar/docs/autorepathpolicy2.html) Policy for how often to recalculate an agent's path. * [ComponentRef](https://arongranberg.com/astar/docs/componentref.html) Wrapper for a pointer. * [DestinationEntity](https://arongranberg.com/astar/docs/destinationentity.html) Holds an agent's destination as an entity. * [DestinationEntitySystem](https://arongranberg.com/astar/docs/destinationentitysystem.html) System that updates the destination of agents with a [DestinationEntity](https://arongranberg.com/astar/docs/destinationentity.html) component. * [UpdateDestinationJob](https://arongranberg.com/astar/docs/updatedestinationjob.html) * [DestinationMoveInCircleSystem](https://arongranberg.com/astar/docs/destinationmoveincirclesystem.html) System that updates the destination of agents with a [DestinationMoveInCircle](https://arongranberg.com/astar/docs/destinationmoveincircle.html) component. * [UpdateDestinationJob](https://arongranberg.com/astar/docs/updatedestinationjob2.html) * [DestinationPoint](https://arongranberg.com/astar/docs/destinationpoint.html) Holds an agent's destination point. * [DrawGizmosJobUtils](https://arongranberg.com/astar/docs/drawgizmosjobutils.html) * [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) Utility for efficient random access to entity component data from the main thread. * [EntityAccessHelper](https://arongranberg.com/astar/docs/entityaccesshelper.html) Helper for [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) . * [EntityStorageCache](https://arongranberg.com/astar/docs/entitystoragecache.html) Utility for efficient random access to entity storage data from the main thread. * [FallbackResolveMovementSystem](https://arongranberg.com/astar/docs/fallbackresolvemovementsystem.html) Copies [MovementControl](https://arongranberg.com/astar/docs/movementcontrol.html) to [ResolvedMovement](https://arongranberg.com/astar/docs/resolvedmovement.html) when no local avoidance is used. * [CopyJob](https://arongranberg.com/astar/docs/copyjob.html) * [CopyRotationJob](https://arongranberg.com/astar/docs/copyrotationjob.html) * [FollowerControlSystem](https://arongranberg.com/astar/docs/followercontrolsystem.html) * [FollowerEntityProxy](https://arongranberg.com/astar/docs/followerentityproxy.html) Proxy for a [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) using pure [ECS](https://arongranberg.com/astar/docs/ecs2.html) components. * [EntityDoesNotExistException](https://arongranberg.com/astar/docs/entitydoesnotexistexception.html) * [GravityState](https://arongranberg.com/astar/docs/gravitystate.html) Agent state related to gravity. * [InitManagedStateSystem](https://arongranberg.com/astar/docs/initmanagedstatesystem.html) Creates a [ManagedState](https://arongranberg.com/astar/docs/managedstate.html) component for every entity with a [ManagedSettings](https://arongranberg.com/astar/docs/managedsettings.html) component. * [JobAlignAgentWithMovementDirection](https://arongranberg.com/astar/docs/jobalignagentwithmovementdirection.html) Aligns the agent's rotation with its movement direction, if the local avoidance system is causing it to move differently than expected. * [JobApplyGravity](https://arongranberg.com/astar/docs/jobapplygravity.html) * [JobClearTemporaryData](https://arongranberg.com/astar/docs/jobcleartemporarydata.html) * [JobControl](https://arongranberg.com/astar/docs/jobcontrol.html) * [JobDrawFollowerGizmos](https://arongranberg.com/astar/docs/jobdrawfollowergizmos.html) * [JobDrawFollowerGizmosBase](https://arongranberg.com/astar/docs/jobdrawfollowergizmosbase.html) * [JobManagedMovementOverrideAfterControl](https://arongranberg.com/astar/docs/jobmanagedmovementoverrideaftercontrol.html) * [JobManagedMovementOverrideBeforeControl](https://arongranberg.com/astar/docs/jobmanagedmovementoverridebeforecontrol.html) * [JobManagedMovementOverrideBeforeMovement](https://arongranberg.com/astar/docs/jobmanagedmovementoverridebeforemovement.html) * [JobManagedOffMeshLinkTransition](https://arongranberg.com/astar/docs/jobmanagedoffmeshlinktransition.html) * [JobManagedOffMeshLinkTransitionCleanup](https://arongranberg.com/astar/docs/jobmanagedoffmeshlinktransitioncleanup.html) * [JobMoveAgent](https://arongranberg.com/astar/docs/jobmoveagent.html) * [JobPrepareAgentRaycasts](https://arongranberg.com/astar/docs/jobprepareagentraycasts.html) * [JobRepairPath](https://arongranberg.com/astar/docs/jobrepairpath.html) Repairs the path of agents. * [Scheduler](https://arongranberg.com/astar/docs/scheduler.html) * [JobRepairPathHelpers](https://arongranberg.com/astar/docs/jobrepairpathhelpers.html) * [PathTracerInfo](https://arongranberg.com/astar/docs/pathtracerinfo.html) * [JobStartOffMeshLinkTransition](https://arongranberg.com/astar/docs/jobstartoffmeshlinktransition.html) * [JobSyncEntitiesToTransforms](https://arongranberg.com/astar/docs/jobsyncentitiestotransforms.html) * [JobUpdateMovementStatistics](https://arongranberg.com/astar/docs/jobupdatemovementstatistics.html) * [LateSyncSystem](https://arongranberg.com/astar/docs/latesyncsystem.html) System that runs after all movement systems and repairs the agent's path and syncs its orientation to the associated Transform component, if one exists. * [ManagedAgentOffMeshLinkTraversal](https://arongranberg.com/astar/docs/managedagentoffmeshlinktraversal.html) Holds managed information about an off-mesh link that the agent is currently traversing. * [ManagedEntityAccess](https://arongranberg.com/astar/docs/managedentityaccess.html) Utility for efficient random access to managed entity component data from the main thread. * [ManagedMovementOverride](https://arongranberg.com/astar/docs/managedmovementoverride.html) Component that stores a delegate that can be used to override movement control and movement settings for a specific entity. * [ManagedMovementOverrideAfterControl](https://arongranberg.com/astar/docs/managedmovementoverrideaftercontrol.html) * [ManagedMovementOverrideBeforeControl](https://arongranberg.com/astar/docs/managedmovementoverridebeforecontrol.html) * [ManagedMovementOverrideBeforeMovement](https://arongranberg.com/astar/docs/managedmovementoverridebeforemovement.html) * [ManagedMovementOverrides](https://arongranberg.com/astar/docs/managedmovementoverrides.html) Helper for adding and removing hooks to the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component. * [ManagedSettings](https://arongranberg.com/astar/docs/managedsettings.html) Settings for agent movement that require managed types. * [ManagedState](https://arongranberg.com/astar/docs/managedstate.html) Runtime state for agent movement that requires managed types. * [MovementControl](https://arongranberg.com/astar/docs/movementcontrol.html) Desired movement for an agent. * [MovementPlaneFromGraphSystem](https://arongranberg.com/astar/docs/movementplanefromgraphsystem.html) * [JobMovementPlaneFromGraph](https://arongranberg.com/astar/docs/jobmovementplanefromgraph.html) * [JobMovementPlaneFromNavmeshNormal](https://arongranberg.com/astar/docs/jobmovementplanefromnavmeshnormal.html) * [MovementSettings](https://arongranberg.com/astar/docs/movementsettings.html) * [MovementState](https://arongranberg.com/astar/docs/movementstate.html) * [MovementStatistics](https://arongranberg.com/astar/docs/movementstatistics.html) * [MovementStatisticsSystem](https://arongranberg.com/astar/docs/movementstatisticssystem.html) System that updates the destination of agents with a [DestinationEntity](https://arongranberg.com/astar/docs/destinationentity.html) component. * [MovementTarget](https://arongranberg.com/astar/docs/movementtarget.html) * [OrientationYAxisForward](https://arongranberg.com/astar/docs/orientationyaxisforward.html) Tag component to indicate that the agent's forward direction is along the Y axis. * [PhysicsSceneRef](https://arongranberg.com/astar/docs/physicssceneref.html) The physics scene to use for raycasting. * [PollPendingPathsSystem](https://arongranberg.com/astar/docs/pollpendingpathssystem.html) Checks if paths have been calculated, and updates the agent's paths if they have. * [ReadyToTraverseOffMeshLink](https://arongranberg.com/astar/docs/readytotraverseoffmeshlink.html) Enabled if the agnet is ready to start traversing an off-mesh link. * [RepairPathSystem](https://arongranberg.com/astar/docs/repairpathsystem.html) * [ResolvedMovement](https://arongranberg.com/astar/docs/resolvedmovement.html) Holds the final movement data for an entity. * [SchedulePathSearchSystem](https://arongranberg.com/astar/docs/schedulepathsearchsystem.html) * [JobCheckStaleness](https://arongranberg.com/astar/docs/jobcheckstaleness.html) * [JobRecalculatePaths](https://arongranberg.com/astar/docs/jobrecalculatepaths.html) * [JobShouldRecalculatePaths](https://arongranberg.com/astar/docs/jobshouldrecalculatepaths.html) * [SearchState](https://arongranberg.com/astar/docs/searchstate.html) * [SimulateMovement](https://arongranberg.com/astar/docs/simulatemovement.html) Tag component to enable movement for an entity. * [SimulateMovementControl](https://arongranberg.com/astar/docs/simulatemovementcontrol.html) Tag component to allow the agent to calculate how it wants to move. * [SimulateMovementFinalize](https://arongranberg.com/astar/docs/simulatemovementfinalize.html) Tag component to allow the agent to move according to its desired movement parameters. * [SimulateMovementRepair](https://arongranberg.com/astar/docs/simulatemovementrepair.html) Tag component to allow the agent to repair its path and recalculate various statistics. * [SyncDestinationTransformSystem](https://arongranberg.com/astar/docs/syncdestinationtransformsystem.html) * [SyncPositionWithTransform](https://arongranberg.com/astar/docs/syncpositionwithtransform.html) Tag component to enable syncing between an agent's Transform and the agent entity's position. * [SyncRotationWithTransform](https://arongranberg.com/astar/docs/syncrotationwithtransform.html) Tag component to enable syncing between an agent's Transform and the agent entity's rotation. * [SyncTransformsToEntitiesSystem](https://arongranberg.com/astar/docs/synctransformstoentitiessystem.html) * [SyncTransformsToEntitiesJob](https://arongranberg.com/astar/docs/synctransformstoentitiesjob.html) * [TraverseOffMeshLinkSystem](https://arongranberg.com/astar/docs/traverseoffmeshlinksystem.html) * [Graphs](https://arongranberg.com/astar/docs/graphs2.html) * [Grid](https://arongranberg.com/astar/docs/grid.html) * [Jobs](https://arongranberg.com/astar/docs/jobs.html) * [JobAllocateNodes](https://arongranberg.com/astar/docs/joballocatenodes2.html) Allocates and deallocates nodes in a grid graph. * [JobCalculateGridConnections](https://arongranberg.com/astar/docs/jobcalculategridconnections.html) Calculates the grid connections for all nodes. * [JobCheckCollisions](https://arongranberg.com/astar/docs/jobcheckcollisions.html) Checks if nodes are obstructed by obstacles or not. * [JobColliderHitsToBooleans](https://arongranberg.com/astar/docs/jobcolliderhitstobooleans.html) Fills the output with true or false depending on if the collider hit was a hit. * [JobCopyBuffers](https://arongranberg.com/astar/docs/jobcopybuffers.html) Copies 3D arrays with grid data from one shape to another. * [JobErosion](https://arongranberg.com/astar/docs/joberosion.html) Calculates erosion. * [JobFilterDiagonalConnections](https://arongranberg.com/astar/docs/jobfilterdiagonalconnections.html) Filters out diagonal connections that are not allowed in layered grid graphs. * [JobMergeRaycastCollisionHits](https://arongranberg.com/astar/docs/jobmergeraycastcollisionhits.html) Calculates if either of the two input hits actually hit something. * [JobNodeGridLayout](https://arongranberg.com/astar/docs/jobnodegridlayout.html) Calculates the default node positions for a grid graph. * [JobNodeWalkability](https://arongranberg.com/astar/docs/jobnodewalkability.html) Calculates for each grid node if it should be walkable or not. * [JobPrepareCapsuleCommands](https://arongranberg.com/astar/docs/jobpreparecapsulecommands.html) Prepares a set of capsule commands for collision checking in a grid graph. * [JobPrepareGridRaycast](https://arongranberg.com/astar/docs/jobpreparegridraycast.html) Prepares a set of raycast commands for a grid graph. * [JobPrepareGridRaycastThick](https://arongranberg.com/astar/docs/jobpreparegridraycastthick.html) Prepares a set of thick raycast commands for a grid graph. * [JobPrepareRaycasts](https://arongranberg.com/astar/docs/jobprepareraycasts.html) Prepares a set of raycast commands for a grid graph. * [JobPrepareSphereCommands](https://arongranberg.com/astar/docs/jobpreparespherecommands.html) Prepares a set of sphere commands for collision checking in a grid graph. * [JobReadNodeData](https://arongranberg.com/astar/docs/jobreadnodedata.html) Reads node data from managed [GridNodeBase](https://arongranberg.com/astar/docs/gridnodebase.html) objects into unmanaged arrays. * [Reader](https://arongranberg.com/astar/docs/reader.html) * [JobRelocateNodes](https://arongranberg.com/astar/docs/jobrelocatenodes.html) Moves all nodes to new positions. * [JobWriteNodeData](https://arongranberg.com/astar/docs/jobwritenodedata.html) Writes node data from unmanaged arrays into managed [GridNodeBase](https://arongranberg.com/astar/docs/gridnodebase.html) objects. * [Rules](https://arongranberg.com/astar/docs/rules.html) * [CustomGridGraphRuleEditorAttribute](https://arongranberg.com/astar/docs/customgridgraphruleeditorattribute.html) * [GridGraphRule](https://arongranberg.com/astar/docs/gridgraphrule.html) Custom rule for a grid graph. * [GridGraphRules](https://arongranberg.com/astar/docs/gridgraphrules.html) Container for all rules in a grid graph. * [Context](https://arongranberg.com/astar/docs/context.html) [Context](https://arongranberg.com/astar/docs/context.html) for when scanning or updating a graph. * [IGridGraphRuleEditor](https://arongranberg.com/astar/docs/igridgraphruleeditor.html) Common interface for all grid graph rule editors. * [RuleAnglePenalty](https://arongranberg.com/astar/docs/ruleanglepenalty.html) Applies penalty based on the slope of the surface below the node. * [JobPenaltyAngle](https://arongranberg.com/astar/docs/jobpenaltyangle.html) * [RuleElevationPenalty](https://arongranberg.com/astar/docs/ruleelevationpenalty.html) Applies penalty based on the elevation of the node. * [JobElevationPenalty](https://arongranberg.com/astar/docs/jobelevationpenalty.html) * [RulePerLayerModifications](https://arongranberg.com/astar/docs/ruleperlayermodifications.html) Modifies nodes based on the layer of the surface under the node. * [PerLayerRule](https://arongranberg.com/astar/docs/perlayerrule.html) * [RuleTexture](https://arongranberg.com/astar/docs/ruletexture.html) Modifies nodes based on the contents of a texture. * [JobTexturePenalty](https://arongranberg.com/astar/docs/jobtexturepenalty.html) * [JobTexturePosition](https://arongranberg.com/astar/docs/jobtextureposition.html) * [FlatGridAdjacencyMapper](https://arongranberg.com/astar/docs/flatgridadjacencymapper.html) * [GraphCollision](https://arongranberg.com/astar/docs/graphcollision.html) Handles collision checking for graphs. * [GridAdjacencyMapper](https://arongranberg.com/astar/docs/gridadjacencymapper.html) * [GridGraphNodeData](https://arongranberg.com/astar/docs/gridgraphnodedata.html) * [LightReader](https://arongranberg.com/astar/docs/lightreader.html) * [GridGraphScanData](https://arongranberg.com/astar/docs/gridgraphscandata.html) * [GridIterationUtilities](https://arongranberg.com/astar/docs/griditerationutilities.html) Helpers for iterating over grid graph data. * [ICellAction](https://arongranberg.com/astar/docs/icellaction.html) Callback struct for [ForEachCellIn3DArray](https://arongranberg.com/astar/docs/griditerationutilities/foreachcellin3darr.html#ForEachCellIn3DArray) . * [IConnectionFilter](https://arongranberg.com/astar/docs/iconnectionfilter.html) Helper interface for modifying node connections. * [INodeModifier](https://arongranberg.com/astar/docs/inodemodifier.html) Helper interface for modifying nodes. * [ISliceAction](https://arongranberg.com/astar/docs/isliceaction.html) Callback struct for [ForEachCellIn3DSlice](https://arongranberg.com/astar/docs/griditerationutilities/foreachcellin3dsli.html#ForEachCellIn3DSlice) . * [ISliceActionWithCoords](https://arongranberg.com/astar/docs/isliceactionwithcoords.html) Callback struct for [ForEachCellIn3DSlice](https://arongranberg.com/astar/docs/griditerationutilities/foreachcellin3dsli.html#ForEachCellIn3DSlice) . * [LayeredGridAdjacencyMapper](https://arongranberg.com/astar/docs/layeredgridadjacencymapper.html) * [Navmesh](https://arongranberg.com/astar/docs/navmesh.html) * [Jobs](https://arongranberg.com/astar/docs/jobs2.html) * [JobBuildNodes](https://arongranberg.com/astar/docs/jobbuildnodes.html) Builds nodes and tiles and prepares them for pathfinding. * [BuildNodeTilesOutput](https://arongranberg.com/astar/docs/buildnodetilesoutput.html) * [JobBuildTileMeshFromVertices](https://arongranberg.com/astar/docs/jobbuildtilemeshfromvertices.html) Builds tiles from raw mesh vertices and indices. * [JobTransformTileCoordinates](https://arongranberg.com/astar/docs/jobtransformtilecoordinates.html) * [JobBuildTileMeshFromVoxels](https://arongranberg.com/astar/docs/jobbuildtilemeshfromvoxels.html) Builds tiles from a polygon soup using voxelization. * [JobCalculateTriangleConnections](https://arongranberg.com/astar/docs/jobcalculatetriangleconnections.html) Calculates node connections between triangles within each tile. * [TileNodeConnectionsUnsafe](https://arongranberg.com/astar/docs/tilenodeconnectionsunsafe.html) * [JobConnectTiles](https://arongranberg.com/astar/docs/jobconnecttiles.html) Connects adjacent tiles together. * [JobConnectTilesSingle](https://arongranberg.com/astar/docs/jobconnecttilessingle.html) Connects two adjacent tiles together. * [JobConvertAreasToTags](https://arongranberg.com/astar/docs/jobconvertareastotags.html) Convert recast region IDs to the tags that should be applied to the nodes. * [JobCreateTiles](https://arongranberg.com/astar/docs/jobcreatetiles.html) Builds tiles optimized for pathfinding, from a list of [TileMesh.TileMeshUnsafe](https://arongranberg.com/astar/docs/tilemeshunsafe.html) . * [JobTransformTileCoordinates](https://arongranberg.com/astar/docs/jobtransformtilecoordinates2.html) Transforms vertices from voxel coordinates to tile coordinates. * [JobWriteNodeConnections](https://arongranberg.com/astar/docs/jobwritenodeconnections.html) Writes connections to each node in each tile. * [TileBuilderBurst](https://arongranberg.com/astar/docs/tilebuilderburst.html) Scratch space for building navmesh tiles using voxelization. * [Voxelization](https://arongranberg.com/astar/docs/voxelization.html) * [Burst](https://arongranberg.com/astar/docs/burst.html) * [CellMinMax](https://arongranberg.com/astar/docs/cellminmax.html) * [CompactVoxelCell](https://arongranberg.com/astar/docs/compactvoxelcell.html) [CompactVoxelCell](https://arongranberg.com/astar/docs/compactvoxelcell.html) used for recast graphs. * [CompactVoxelField](https://arongranberg.com/astar/docs/compactvoxelfield.html) Stores a compact voxel field. * [CompactVoxelSpan](https://arongranberg.com/astar/docs/compactvoxelspan.html) [CompactVoxelSpan](https://arongranberg.com/astar/docs/compactvoxelspan.html) used for recast graphs. * [JobBuildCompactField](https://arongranberg.com/astar/docs/jobbuildcompactfield.html) * [JobBuildConnections](https://arongranberg.com/astar/docs/jobbuildconnections.html) * [JobBuildContours](https://arongranberg.com/astar/docs/jobbuildcontours.html) * [JobBuildDistanceField](https://arongranberg.com/astar/docs/jobbuilddistancefield.html) * [JobBuildMesh](https://arongranberg.com/astar/docs/jobbuildmesh.html) Builds a polygon mesh from a contour set. * [JobBuildRegions](https://arongranberg.com/astar/docs/jobbuildregions.html) * [RelevantGraphSurfaceInfo](https://arongranberg.com/astar/docs/relevantgraphsurfaceinfo.html) * [JobErodeWalkableArea](https://arongranberg.com/astar/docs/joberodewalkablearea.html) * [JobFilterLedges](https://arongranberg.com/astar/docs/jobfilterledges.html) * [JobFilterLowHeightSpans](https://arongranberg.com/astar/docs/jobfilterlowheightspans.html) * [JobVoxelize](https://arongranberg.com/astar/docs/jobvoxelize.html) * [LinkedVoxelField](https://arongranberg.com/astar/docs/linkedvoxelfield.html) * [LinkedVoxelSpan](https://arongranberg.com/astar/docs/linkedvoxelspan.html) * [RasterizationMesh](https://arongranberg.com/astar/docs/rasterizationmesh.html) * [VoxelContour](https://arongranberg.com/astar/docs/voxelcontour.html) [VoxelContour](https://arongranberg.com/astar/docs/voxelcontour.html) used for recast graphs. * [VoxelMesh](https://arongranberg.com/astar/docs/voxelmesh.html) [VoxelMesh](https://arongranberg.com/astar/docs/voxelmesh.html) used for recast graphs. * [VoxelUtilityBurst](https://arongranberg.com/astar/docs/voxelutilityburst.html) * [Int3PolygonClipper](https://arongranberg.com/astar/docs/int3polygonclipper.html) Utility for clipping polygons. * [VoxelPolygonClipper](https://arongranberg.com/astar/docs/voxelpolygonclipper.html) Utility for clipping polygons. * [CircleGeometryUtilities](https://arongranberg.com/astar/docs/circlegeometryutilities.html) * [ColliderMeshBuilder2D](https://arongranberg.com/astar/docs/collidermeshbuilder2d.html) * [ShapeMesh](https://arongranberg.com/astar/docs/shapemesh.html) * [NavmeshTile](https://arongranberg.com/astar/docs/navmeshtile.html) A single tile in a recast or navmesh graph. * [NavmeshUpdates](https://arongranberg.com/astar/docs/navmeshupdates.html) Helper for navmesh cut objects. * [NavmeshUpdateSettings](https://arongranberg.com/astar/docs/navmeshupdatesettings.html) Stores navmesh cutting related data for a single graph. * [RecastBuilder](https://arongranberg.com/astar/docs/recastbuilder.html) Helper methods for scanning a recast graph. * [RecastMeshGatherer](https://arongranberg.com/astar/docs/recastmeshgatherer.html) * [GatheredMesh](https://arongranberg.com/astar/docs/gatheredmesh.html) Holds info about a mesh to be rasterized. * [JobGenerateHeightmapChunk](https://arongranberg.com/astar/docs/jobgenerateheightmapchunk.html) Generates a terrain chunk mesh. * [TerrainChunk](https://arongranberg.com/astar/docs/terrainchunk.html) * [Markers](https://arongranberg.com/astar/docs/markers.html) * [MeshCacheItem](https://arongranberg.com/astar/docs/meshcacheitem.html) * [MeshCollection](https://arongranberg.com/astar/docs/meshcollection.html) * [TreeInfo](https://arongranberg.com/astar/docs/treeinfo.html) * [RelevantGraphSurface](https://arongranberg.com/astar/docs/relevantgraphsurface.html) Pruning of recast navmesh regions. * [TileBuilder](https://arongranberg.com/astar/docs/tilebuilder.html) Settings for building tile meshes in a recast graph. * [BucketMapping](https://arongranberg.com/astar/docs/bucketmapping.html) A mapping from tiles to the meshes that each tile touches. * [TileBuilderOutput](https://arongranberg.com/astar/docs/tilebuilderoutput.html) * [TileCutter](https://arongranberg.com/astar/docs/tilecutter.html) * [JobCutTiles](https://arongranberg.com/astar/docs/jobcuttiles.html) * [TileCutterOutput](https://arongranberg.com/astar/docs/tilecutteroutput.html) * [TileHandler](https://arongranberg.com/astar/docs/tilehandler.html) Utility class for updating tiles of navmesh/recast graphs. * [ContourMeta](https://arongranberg.com/astar/docs/contourmeta.html) * [CutCollection](https://arongranberg.com/astar/docs/cutcollection.html) * [CutFunctionKey](https://arongranberg.com/astar/docs/cutfunctionkey.html) * [Point64Wrapper](https://arongranberg.com/astar/docs/point64wrapper.html) * [TileCuts](https://arongranberg.com/astar/docs/tilecuts.html) * [TileHandlerCache](https://arongranberg.com/astar/docs/tilehandlercache.html) * [TileLayout](https://arongranberg.com/astar/docs/tilelayout.html) Represents the position and size of a tile grid for a recast/navmesh graph. * [TileMesh](https://arongranberg.com/astar/docs/tilemesh.html) A tile in a navmesh graph. * [TileMeshUnsafe](https://arongranberg.com/astar/docs/tilemeshunsafe.html) Unsafe version of [TileMesh](https://arongranberg.com/astar/docs/tilemesh.html) . * [TileMeshes](https://arongranberg.com/astar/docs/tilemeshes.html) Represents a rectangular group of tiles of a recast graph. * [TileMeshesUnsafe](https://arongranberg.com/astar/docs/tilemeshesunsafe.html) Unsafe representation of a [TileMeshes](https://arongranberg.com/astar/docs/tilemeshes.html) struct. * [Util](https://arongranberg.com/astar/docs/util.html) * [EuclideanEmbedding](https://arongranberg.com/astar/docs/euclideanembedding.html) Implements heuristic optimizations. * [EuclideanEmbeddingSearchPath](https://arongranberg.com/astar/docs/euclideanembeddingsearchpath.html) * [Jobs](https://arongranberg.com/astar/docs/jobs3.html) * [DisableUninitializedReadCheckAttribute](https://arongranberg.com/astar/docs/disableuninitializedreadcheckattribute.html) Disable the check that prevents jobs from including uninitialized native arrays open for reading. * [DisposeArena](https://arongranberg.com/astar/docs/disposearena.html) Convenient collection of items that can be disposed together. * [IArenaDisposable](https://arongranberg.com/astar/docs/iarenadisposable.html) * [IJobExtensions](https://arongranberg.com/astar/docs/ijobextensions.html) Extension methods for IJob and related interfaces. * [ManagedActionJob](https://arongranberg.com/astar/docs/managedactionjob.html) * [ManagedJob](https://arongranberg.com/astar/docs/managedjob.html) * [IJobParallelForBatched](https://arongranberg.com/astar/docs/ijobparallelforbatched.html) * [IJobTimeSliced](https://arongranberg.com/astar/docs/ijobtimesliced.html) * [IndexActionJob](https://arongranberg.com/astar/docs/indexactionjob.html) * [JobAND](https://arongranberg.com/astar/docs/joband.html) result\[i\] &= data\[i\] * [JobClampHitToRay](https://arongranberg.com/astar/docs/jobclamphittoray.html) Clamps spherecast hit points to the ray, based on the origin and direction. * [JobCopy](https://arongranberg.com/astar/docs/jobcopy.html) to\[i\] = from\[i\] * [JobCopyHits](https://arongranberg.com/astar/docs/jobcopyhits.html) Copies hit points and normals. * [JobCopyRectangle](https://arongranberg.com/astar/docs/jobcopyrectangle.html) Treats input as a 3-dimensional array and copies it into the output at the specified position. * [JobDependencyAnalyzer](https://arongranberg.com/astar/docs/jobdependencyanalyzer.html) * [ReflectionData](https://arongranberg.com/astar/docs/reflectiondata.html) * [JobDependencyAnalyzerAssociated](https://arongranberg.com/astar/docs/jobdependencyanalyzerassociated.html) * [JobDependencyTracker](https://arongranberg.com/astar/docs/jobdependencytracker.html) Automatic dependency tracking for the Unity Job System. * [JobInstance](https://arongranberg.com/astar/docs/jobinstance.html) * [JobOverlapCapsuleCommandDummy](https://arongranberg.com/astar/docs/joboverlapcapsulecommanddummy.html) * [JobOverlapSphereCommandDummy](https://arongranberg.com/astar/docs/joboverlapspherecommanddummy.html) * [JobRaycastCommandDummy](https://arongranberg.com/astar/docs/jobraycastcommanddummy.html) * [JobSpherecastCommandDummy](https://arongranberg.com/astar/docs/jobspherecastcommanddummy.html) * [NativeArraySlot](https://arongranberg.com/astar/docs/nativearrayslot.html) * [JobHandleWithMainThreadWork](https://arongranberg.com/astar/docs/jobhandlewithmainthreadwork.html) * [JobMaxHitCount](https://arongranberg.com/astar/docs/jobmaxhitcount.html) * [JobMemSet](https://arongranberg.com/astar/docs/jobmemset.html) result\[i\] = value * [JobParallelForBatchedExtensions](https://arongranberg.com/astar/docs/jobparallelforbatchedextensions.html) * [ParallelForBatchJobStruct](https://arongranberg.com/astar/docs/parallelforbatchjobstruct.html) * [JobRaycastAll](https://arongranberg.com/astar/docs/jobraycastall.html) * [JobCombineResults](https://arongranberg.com/astar/docs/jobcombineresults.html) * [JobCreateCommands](https://arongranberg.com/astar/docs/jobcreatecommands.html) * [JobRotate3DArray](https://arongranberg.com/astar/docs/jobrotate3darray.html) * [NativeArrayExtensions](https://arongranberg.com/astar/docs/nativearrayextensions.html) Helpers for scheduling simple NativeArray jobs. * [Slice3D](https://arongranberg.com/astar/docs/slice3d.html) Slice of a 3D array. * [SliceActionJob](https://arongranberg.com/astar/docs/sliceactionjob.html) * [TimeSlice](https://arongranberg.com/astar/docs/timeslice.html) * [Legacy](https://arongranberg.com/astar/docs/legacy.html) * [LegacyEditorHelper](https://arongranberg.com/astar/docs/legacyeditorhelper.html) * [PID](https://arongranberg.com/astar/docs/pid.html) * [AnglePIDController](https://arongranberg.com/astar/docs/anglepidcontroller.html) Implements a [PID](https://arongranberg.com/astar/docs/pid.html) controller for the angular velocity of an agent following a curve. * [AnglePIDControlOutput2D](https://arongranberg.com/astar/docs/anglepidcontroloutput2d.html) * [PIDMovement](https://arongranberg.com/astar/docs/pidmovement.html) Core control loop for the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) movement script. * [ControlParams](https://arongranberg.com/astar/docs/controlparams.html) * [EdgeBuffers](https://arongranberg.com/astar/docs/edgebuffers.html) * [PersistentState](https://arongranberg.com/astar/docs/persistentstate.html) * [Pooling](https://arongranberg.com/astar/docs/pooling2.html) * [ArrayPool](https://arongranberg.com/astar/docs/arraypool.html) Lightweight Array Pool. * [IAstarPooledObject](https://arongranberg.com/astar/docs/iastarpooledobject.html) * [ListExtensions](https://arongranberg.com/astar/docs/listextensions.html) Extension methods for List * [ListPool](https://arongranberg.com/astar/docs/listpool.html) Lightweight List Pool. * [ObjectPool](https://arongranberg.com/astar/docs/objectpool.html) Lightweight object Pool for [IAstarPooledObject](https://arongranberg.com/astar/docs/iastarpooledobject.html) . * [ObjectPoolSimple](https://arongranberg.com/astar/docs/objectpoolsimple.html) Lightweight object Pool. * [PathPool](https://arongranberg.com/astar/docs/pathpool.html) Pools path objects to reduce load on the garbage collector. * [StackPool](https://arongranberg.com/astar/docs/stackpool.html) Lightweight Stack Pool. * [RVO](https://arongranberg.com/astar/docs/rvo2.html) Local avoidance related classes. * [ArbitraryMovementPlane](https://arongranberg.com/astar/docs/arbitrarymovementplane.html) * [IAgent](https://arongranberg.com/astar/docs/iagent.html) Exposes properties of an Agent class. * [IMovementPlaneWrapper](https://arongranberg.com/astar/docs/imovementplanewrapper.html) * [JobDestinationReached](https://arongranberg.com/astar/docs/jobdestinationreached.html) Calculates if the agent has reached the end of its path and if its blocked from further progress towards it. * [TempAgentData](https://arongranberg.com/astar/docs/tempagentdata.html) * [JobHardCollisions](https://arongranberg.com/astar/docs/jobhardcollisions.html) * [JobHorizonAvoidancePhase1](https://arongranberg.com/astar/docs/jobhorizonavoidancephase1.html) Inspired by StarCraft 2's avoidance of locked units. * [JobHorizonAvoidancePhase2](https://arongranberg.com/astar/docs/jobhorizonavoidancephase2.html) Inspired by StarCraft 2's avoidance of locked units. * [JobRVO](https://arongranberg.com/astar/docs/jobrvo.html) * [LinearProgram2Output](https://arongranberg.com/astar/docs/linearprogram2output.html) * [ORCALine](https://arongranberg.com/astar/docs/orcaline.html) A half-plane defined as the line splitting plane. * [SortByKey](https://arongranberg.com/astar/docs/sortbykey.html) * [JobRVOCalculateNeighbours](https://arongranberg.com/astar/docs/jobrvocalculateneighbours.html) * [JobRVOPreprocess](https://arongranberg.com/astar/docs/jobrvopreprocess.html) * [ObstacleVertexGroup](https://arongranberg.com/astar/docs/obstaclevertexgroup.html) * [RVOController](https://arongranberg.com/astar/docs/rvocontroller.html) [RVO](https://arongranberg.com/astar/docs/rvo2.html) Character Controller. * [RVOControllerEditor](https://arongranberg.com/astar/docs/rvocontrollereditor.html) * [RVODestinationCrowdedBehavior](https://arongranberg.com/astar/docs/rvodestinationcrowdedbehavior.html) Controls if the agent slows down to a stop if the area around the destination is crowded. * [JobDensityCheck](https://arongranberg.com/astar/docs/jobdensitycheck.html) * [QueryData](https://arongranberg.com/astar/docs/querydata.html) * [RVONavmesh](https://arongranberg.com/astar/docs/rvonavmesh.html) Adds a navmesh as [RVO](https://arongranberg.com/astar/docs/rvo2.html) obstacles. * [RVOObstacle](https://arongranberg.com/astar/docs/rvoobstacle.html) Base class for simple [RVO](https://arongranberg.com/astar/docs/rvo2.html) colliders. * [RVOObstacleCache](https://arongranberg.com/astar/docs/rvoobstaclecache.html) * [ObstacleSegment](https://arongranberg.com/astar/docs/obstaclesegment.html) * [RVOQuadtreeBurst](https://arongranberg.com/astar/docs/rvoquadtreeburst.html) Quadtree for quick nearest neighbour search of rvo agents. * [DebugDrawJob](https://arongranberg.com/astar/docs/debugdrawjob.html) * [JobBuild](https://arongranberg.com/astar/docs/jobbuild.html) * [QuadtreeQuery](https://arongranberg.com/astar/docs/quadtreequery.html) * [RVOSimulator](https://arongranberg.com/astar/docs/rvosimulator.html) Unity front end for an [RVO](https://arongranberg.com/astar/docs/rvo2.html) simulator. * [RVOSquareObstacle](https://arongranberg.com/astar/docs/rvosquareobstacle.html) Square Obstacle for [RVO](https://arongranberg.com/astar/docs/rvo2.html) Simulation. * [SimulatorBurst](https://arongranberg.com/astar/docs/simulatorburst.html) Local Avoidance Simulator. * [Agent](https://arongranberg.com/astar/docs/agent.html) * [AgentData](https://arongranberg.com/astar/docs/agentdata.html) Holds internal agent data for the local avoidance simulation. * [AgentNeighbourLookup](https://arongranberg.com/astar/docs/agentneighbourlookup.html) * [AgentOutputData](https://arongranberg.com/astar/docs/agentoutputdata.html) * [HorizonAgentData](https://arongranberg.com/astar/docs/horizonagentdata.html) * [ObstacleData](https://arongranberg.com/astar/docs/obstacledata.html) Holds internal obstacle data for the local avoidance simulation. * [TemporaryAgentData](https://arongranberg.com/astar/docs/temporaryagentdata.html) * [UnmanagedObstacle](https://arongranberg.com/astar/docs/unmanagedobstacle.html) Represents a set of obstacles. * [XYMovementPlane](https://arongranberg.com/astar/docs/xymovementplane.html) * [XZMovementPlane](https://arongranberg.com/astar/docs/xzmovementplane.html) * [Serialization](https://arongranberg.com/astar/docs/serialization.html) * [AstarSerializer](https://arongranberg.com/astar/docs/astarserializer.html) Handles low level serialization and deserialization of graph settings and data. * [GraphMeta](https://arongranberg.com/astar/docs/graphmeta.html) Metadata for all graphs included in serialization. * [GraphSerializationContext](https://arongranberg.com/astar/docs/graphserializationcontext.html) Holds information passed to custom graph serializers. * [JsonDynamicTypeAliasAttribute](https://arongranberg.com/astar/docs/jsondynamictypealiasattribute.html) * [JsonDynamicTypeAttribute](https://arongranberg.com/astar/docs/jsondynamictypeattribute.html) Indicates that the full type of the instance will always be serialized. * [JsonMemberAttribute](https://arongranberg.com/astar/docs/jsonmemberattribute.html) * [JsonOptInAttribute](https://arongranberg.com/astar/docs/jsonoptinattribute.html) * [Migrations](https://arongranberg.com/astar/docs/migrations.html) Helper struct for handling serialization backwards compatibility. * [SerializableAnimationCurve](https://arongranberg.com/astar/docs/serializableanimationcurve.html) * [SerializeSettings](https://arongranberg.com/astar/docs/serializesettings.html) Holds settings for how graphs should be serialized. * [TinyJsonDeserializer](https://arongranberg.com/astar/docs/tinyjsondeserializer.html) A very tiny json deserializer. * [TinyJsonSerializer](https://arongranberg.com/astar/docs/tinyjsonserializer.html) A very tiny json serializer. * [Sync](https://arongranberg.com/astar/docs/sync.html) Synchronization primitives. * [BlockableChannel](https://arongranberg.com/astar/docs/blockablechannel.html) Multi-producer-multi-consumer (MPMC) channel. * [Receiver](https://arongranberg.com/astar/docs/receiver.html) Allows receiving items from a channel. * [IProgress](https://arongranberg.com/astar/docs/iprogress.html) * [Promise](https://arongranberg.com/astar/docs/promise.html) A promise that T is being calculated asynchronously. * [RWLock](https://arongranberg.com/astar/docs/rwlock.html) A simple read/write lock for use with the Unity Job System. * [CombinedReadLockAsync](https://arongranberg.com/astar/docs/combinedreadlockasync.html) * [LockSync](https://arongranberg.com/astar/docs/locksync.html) * [ReadLockAsync](https://arongranberg.com/astar/docs/readlockasync.html) * [WriteLockAsync](https://arongranberg.com/astar/docs/writelockasync.html) * [SpinLock](https://arongranberg.com/astar/docs/spinlock.html) Spin lock which can be used in Burst. * [Util](https://arongranberg.com/astar/docs/util2.html) * [AssemblySearcher](https://arongranberg.com/astar/docs/assemblysearcher.html) * [BatchedEvents](https://arongranberg.com/astar/docs/batchedevents.html) Helper for batching updates to many objects efficiently. * [Archetype](https://arongranberg.com/astar/docs/archetype.html) * [Checksum](https://arongranberg.com/astar/docs/checksum.html) Calculates checksums of byte arrays. * [DependencyCheck](https://arongranberg.com/astar/docs/dependencycheck.html) * [Dependency](https://arongranberg.com/astar/docs/dependency.html) * [EditorGUILayoutHelper](https://arongranberg.com/astar/docs/editorguilayouthelper.html) Some editor gui helper methods. * [GraphGizmoHelper](https://arongranberg.com/astar/docs/graphgizmohelper.html) * [GraphSnapshot](https://arongranberg.com/astar/docs/graphsnapshot.html) A snapshot of parts of graphs. * [GraphTransform](https://arongranberg.com/astar/docs/graphtransform.html) Defines a transformation from graph space to world space. * [Guid](https://arongranberg.com/astar/docs/guid.html) Simple implementation of a GUID. * [IEntityIndex](https://arongranberg.com/astar/docs/ientityindex.html) Used by [Pathfinding.Util.BatchedEvents](https://arongranberg.com/astar/docs/batchedevents.html) . * [IGraphSnapshot](https://arongranberg.com/astar/docs/igraphsnapshot.html) * [IMovementPlane](https://arongranberg.com/astar/docs/imovementplane.html) Transforms to and from world space to a 2D movement plane. * [IRuntimeBaker](https://arongranberg.com/astar/docs/iruntimebaker.html) * [ITransform](https://arongranberg.com/astar/docs/itransform.html) Generic 3D coordinate transformation. * [MathExtensions](https://arongranberg.com/astar/docs/mathextensions.html) * [Memory](https://arongranberg.com/astar/docs/memory.html) Various utilities for handling arrays and memory. * [MeshUtility](https://arongranberg.com/astar/docs/meshutility.html) Helper class for working with meshes efficiently. * [JobMergeNearbyVertices](https://arongranberg.com/astar/docs/jobmergenearbyvertices.html) Removes duplicate vertices from the array and updates the triangle array. * [CoordinateSorter](https://arongranberg.com/astar/docs/coordinatesorter.html) * [JobRemoveDegenerateTriangles](https://arongranberg.com/astar/docs/jobremovedegeneratetriangles.html) * [MovementUtilities](https://arongranberg.com/astar/docs/movementutilities.html) * [MutableGraphTransform](https://arongranberg.com/astar/docs/mutablegraphtransform.html) Like [Pathfinding.Util.GraphTransform](https://arongranberg.com/astar/docs/graphtransform.html) , but mutable. * [NativeMovementPlane](https://arongranberg.com/astar/docs/nativemovementplane.html) A variant of [SimpleMovementPlane](https://arongranberg.com/astar/docs/simplemovementplane.html) that can be passed to burst functions. * [NodeHasher](https://arongranberg.com/astar/docs/nodehasher.html) Combines hashes into a single hash value. * [PathInterpolator](https://arongranberg.com/astar/docs/pathinterpolator.html) Interpolates along a sequence of points. * [Cursor](https://arongranberg.com/astar/docs/cursor.html) Represents a single point on the polyline represented by the [PathInterpolator](https://arongranberg.com/astar/docs/pathinterpolator.html) . * [PathPartWithLinkInfo](https://arongranberg.com/astar/docs/pathpartwithlinkinfo.html) Represents a part of a path, with optional link information. * [PreserveAttribute](https://arongranberg.com/astar/docs/preserveattribute.html) Prevents code stripping. * [SimpleMovementPlane](https://arongranberg.com/astar/docs/simplemovementplane.html) Represents the orientation of a plane. * [ToPlaneMatrix](https://arongranberg.com/astar/docs/toplanematrix.html) A matrix wrapper which can be used to project points from world space to a movement plane. * [ToWorldMatrix](https://arongranberg.com/astar/docs/toworldmatrix.html) A matrix wrapper which can be used to project points from a movement plane to world space. * [UnityCompatibility](https://arongranberg.com/astar/docs/unitycompatibility.html) Compatibility class for Unity APIs that are not available in all Unity versions. * [WindowsStore](https://arongranberg.com/astar/docs/windowsstore.html) * [WindowsStoreCompatibility](https://arongranberg.com/astar/docs/windowsstorecompatibility.html) * [ABPath](https://arongranberg.com/astar/docs/abpath.html) Basic path, finds the shortest path from A to B. * [ABPathEndingCondition](https://arongranberg.com/astar/docs/abpathendingcondition.html) Ending condition which emulates the default one for the [ABPath](https://arongranberg.com/astar/docs/abpath.html) . * [AdvancedSmooth](https://arongranberg.com/astar/docs/advancedsmooth.html) Smoothing by dividing path into turns and straight segments. * [ConstantTurn](https://arongranberg.com/astar/docs/constantturn.html) Constant turning speed. * [MaxTurn](https://arongranberg.com/astar/docs/maxturn.html) Type of turn. * [Turn](https://arongranberg.com/astar/docs/turn.html) Represents a turn in a path. * [TurnConstructor](https://arongranberg.com/astar/docs/turnconstructor.html) Abstract turn constructor. * [AIBase](https://arongranberg.com/astar/docs/aibase.html) Base class for [AIPath](https://arongranberg.com/astar/docs/aipath.html) and [RichAI](https://arongranberg.com/astar/docs/richai.html) . * [AIDestinationSetter](https://arongranberg.com/astar/docs/aidestinationsetter.html) Sets the destination of an AI to the position of a specified object. * [AIDestinationSetterBaker](https://arongranberg.com/astar/docs/aidestinationsetterbaker.html) * [AIDestinationSetterEditor](https://arongranberg.com/astar/docs/aidestinationsettereditor.html) * [AILerp](https://arongranberg.com/astar/docs/ailerp.html) Linearly interpolating movement script. * [AILerpEditor](https://arongranberg.com/astar/docs/ailerpeditor.html) * [AIPath](https://arongranberg.com/astar/docs/aipath.html) AI for following paths. * [AIPathAlignedToSurface](https://arongranberg.com/astar/docs/aipathalignedtosurface.html) Movement script for curved worlds. * [AlternativePath](https://arongranberg.com/astar/docs/alternativepath.html) Applies penalty to the paths it processes telling other units to avoid choosing the same path. * [AnimationLink](https://arongranberg.com/astar/docs/animationlink.html) * [LinkClip](https://arongranberg.com/astar/docs/linkclip.html) * [AnimationLinkEditor](https://arongranberg.com/astar/docs/animationlinkeditor.html) * [AstarColor](https://arongranberg.com/astar/docs/astarcolor.html) Stores editor colors. * [AstarData](https://arongranberg.com/astar/docs/astardata.html) Stores the navigation graphs for the A\* [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) System. * [AstarDebugger](https://arongranberg.com/astar/docs/astardebugger.html) Debugger for the A\* [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) Project. * [GraphPoint](https://arongranberg.com/astar/docs/graphpoint.html) * [PathTypeDebug](https://arongranberg.com/astar/docs/pathtypedebug.html) * [AstarMath](https://arongranberg.com/astar/docs/astarmath.html) Utility functions for working with numbers and strings. * [AstarPathEditor](https://arongranberg.com/astar/docs/astarpatheditor.html) * [AstarSplines](https://arongranberg.com/astar/docs/astarsplines.html) Contains various spline functions. * [AstarUpdateChecker](https://arongranberg.com/astar/docs/astarupdatechecker.html) Handles update checking for the A\* [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) Project. * [AstarUpdateWindow](https://arongranberg.com/astar/docs/astarupdatewindow.html) * [AstarWorkItem](https://arongranberg.com/astar/docs/astarworkitem.html) An item of work that can be executed when graphs are safe to update. * [AutoRepathPolicy](https://arongranberg.com/astar/docs/autorepathpolicy.html) Policy for how often to recalculate an agent's path. * [BaseAIEditor](https://arongranberg.com/astar/docs/baseaieditor.html) * [BinaryHeap](https://arongranberg.com/astar/docs/binaryheap.html) Binary heap implementation. * [HeapNode](https://arongranberg.com/astar/docs/heapnode.html) Item in the heap. * [BlockManager](https://arongranberg.com/astar/docs/blockmanager.html) Manager for blocker scripts such as [SingleNodeBlocker](https://arongranberg.com/astar/docs/singlenodeblocker.html) . * [TraversalProvider](https://arongranberg.com/astar/docs/traversalprovider.html) Blocks nodes according to a [BlockManager](https://arongranberg.com/astar/docs/blockmanager.html) . * [Connection](https://arongranberg.com/astar/docs/connection.html) Represents a connection to another node. * [ConstantPath](https://arongranberg.com/astar/docs/constantpath.html) Finds all nodes within a specified distance from the start. * [CustomGraphEditorAttribute](https://arongranberg.com/astar/docs/customgrapheditorattribute.html) Added to editors of custom graph types. * [DefaultITraversalProvider](https://arongranberg.com/astar/docs/defaultitraversalprovider.html) Convenience class to access the default implementation of the [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) . * [DistanceMetric](https://arongranberg.com/astar/docs/distancemetric.html) Determines how to measure distances to the navmesh. * [DynamicGridObstacle](https://arongranberg.com/astar/docs/dynamicgridobstacle.html) Updates graphs around the object as it moves. * [DynamicObstacle](https://arongranberg.com/astar/docs/dynamicobstacle.html) Updates graphs around the object as it moves. * [EditorBase](https://arongranberg.com/astar/docs/editorbase.html) Helper for creating editors. * [EditorGUILayoutx](https://arongranberg.com/astar/docs/editorguilayoutx.html) Handles fading effects and also some custom GUI functions such as LayerMaskField. * [EditorResourceHelper](https://arongranberg.com/astar/docs/editorresourcehelper.html) Internal utility class for looking up editor resources. * [EndingConditionDistance](https://arongranberg.com/astar/docs/endingconditiondistance.html) Target is found when the path is longer than a specified value. * [EndingConditionProximity](https://arongranberg.com/astar/docs/endingconditionproximity.html) Ending condition which stops a fixed distance from the target point. * [EnumFlagAttribute](https://arongranberg.com/astar/docs/enumflagattribute.html) * [EnumFlagDrawer](https://arongranberg.com/astar/docs/enumflagdrawer.html) * [FadeArea](https://arongranberg.com/astar/docs/fadearea.html) Editor helper for hiding and showing a group of GUI elements. * [FakeTransform](https://arongranberg.com/astar/docs/faketransform.html) * [FleePath](https://arongranberg.com/astar/docs/fleepath.html) Returns a path heading away from a specified point to avoid. * [FloodPath](https://arongranberg.com/astar/docs/floodpath.html) Calculates paths from everywhere to a single point. * [FloodPathTracer](https://arongranberg.com/astar/docs/floodpathtracer.html) Traces a path created with the [Pathfinding.FloodPath](https://arongranberg.com/astar/docs/floodpath.html) . * [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) Movement script that uses ECS. * [FollowerEntityEditor](https://arongranberg.com/astar/docs/followerentityeditor.html) * [Funnel](https://arongranberg.com/astar/docs/funnel.html) Implements the funnel algorithm as well as various related methods. * [FunnelPortals](https://arongranberg.com/astar/docs/funnelportals.html) [Funnel](https://arongranberg.com/astar/docs/funnel.html) in which the path to the target will be. * [FunnelState](https://arongranberg.com/astar/docs/funnelstate.html) * [PathPart](https://arongranberg.com/astar/docs/pathpart.html) Part of a path. * [FunnelModifier](https://arongranberg.com/astar/docs/funnelmodifier.html) Simplifies paths on navmesh graphs using the funnel algorithm. * [FunnelModifierEditor](https://arongranberg.com/astar/docs/funnelmodifiereditor.html) * [GlobalNodeStorage](https://arongranberg.com/astar/docs/globalnodestorage.html) * [DebugPathNode](https://arongranberg.com/astar/docs/debugpathnode.html) * [IndexedStack](https://arongranberg.com/astar/docs/indexedstack.html) * [JobAllocateNodes](https://arongranberg.com/astar/docs/joballocatenodes.html) * [PathfindingThreadData](https://arongranberg.com/astar/docs/pathfindingthreaddata.html) * [GraphEditor](https://arongranberg.com/astar/docs/grapheditor.html) * [GraphEditorBase](https://arongranberg.com/astar/docs/grapheditorbase.html) Base class for all graph editors. * [GraphHitInfo](https://arongranberg.com/astar/docs/graphhitinfo.html) Info about what a raycast, linecast or nearest border query hit. * [GraphMask](https://arongranberg.com/astar/docs/graphmask.html) A combination of graphs. * [GraphMaskDrawer](https://arongranberg.com/astar/docs/graphmaskdrawer.html) * [GraphModifier](https://arongranberg.com/astar/docs/graphmodifier.html) [GraphModifier](https://arongranberg.com/astar/docs/graphmodifier.html) is used for modifying graphs or processing graph data based on events. * [GraphNode](https://arongranberg.com/astar/docs/graphnode.html) Base class for all nodes. * [GraphUpdateObject](https://arongranberg.com/astar/docs/graphupdateobject.html) Represents a collection of settings used to update nodes in a specific region of a graph. * [GraphUpdateData](https://arongranberg.com/astar/docs/graphupdatedata.html) Provides burst-readable data to a graph update job. * [JobGraphUpdate](https://arongranberg.com/astar/docs/jobgraphupdate.html) Job for applying a graph update object. * [GraphUpdateProcessor](https://arongranberg.com/astar/docs/graphupdateprocessor.html) * [GraphUpdateScene](https://arongranberg.com/astar/docs/graphupdatescene.html) Helper class for easily updating graphs. * [GraphUpdateSceneEditor](https://arongranberg.com/astar/docs/graphupdatesceneeditor.html) Editor for [GraphUpdateScene](https://arongranberg.com/astar/docs/graphupdatescene.html) . * [GraphUpdateShape](https://arongranberg.com/astar/docs/graphupdateshape.html) Defines a shape for a [Pathfinding.GraphUpdateObject](https://arongranberg.com/astar/docs/graphupdateobject.html) . * [BurstShape](https://arongranberg.com/astar/docs/burstshape.html) Shape optimized for burst. * [GraphUpdateUtilities](https://arongranberg.com/astar/docs/graphupdateutilities.html) Contains useful functions for updating graphs. * [GraphUtilities](https://arongranberg.com/astar/docs/graphutilities.html) Contains utility methods for getting useful information out of graph. * [GridGraph](https://arongranberg.com/astar/docs/gridgraph.html) Generates a grid of nodes. * [CombinedGridGraphUpdatePromise](https://arongranberg.com/astar/docs/combinedgridgraphupdatepromise.html) * [GridGraphMovePromise](https://arongranberg.com/astar/docs/gridgraphmovepromise.html) * [GridGraphSnapshot](https://arongranberg.com/astar/docs/gridgraphsnapshot.html) * [GridGraphUpdatePromise](https://arongranberg.com/astar/docs/gridgraphupdatepromise.html) * [NodesHolder](https://arongranberg.com/astar/docs/nodesholder.html) Reference to a nodes array to allow multiple serial updates to have a common reference to the nodes. * [TextureData](https://arongranberg.com/astar/docs/texturedata.html) Used for using a texture as a source for a grid graph. * [GridGraphEditor](https://arongranberg.com/astar/docs/gridgrapheditor.html) * [GridHitInfo](https://arongranberg.com/astar/docs/gridhitinfo.html) Information about a linecast hit on a grid graph. * [GridNode](https://arongranberg.com/astar/docs/gridnode.html) Node used for the [GridGraph](https://arongranberg.com/astar/docs/gridgraph.html) . * [GridNodeBase](https://arongranberg.com/astar/docs/gridnodebase.html) Base class for [GridNode](https://arongranberg.com/astar/docs/gridnode.html) and [LevelGridNode](https://arongranberg.com/astar/docs/levelgridnode.html) . * [GridStringPulling](https://arongranberg.com/astar/docs/gridstringpulling.html) Simplifies a path on a grid graph using a string pulling algorithm. * [TriangleBounds](https://arongranberg.com/astar/docs/trianglebounds.html) * [GUIUtilityx](https://arongranberg.com/astar/docs/guiutilityx.html) Simple GUI utility functions. * [HeuristicObjective](https://arongranberg.com/astar/docs/heuristicobjective.html) Calculates an estimated cost from the specified point to the target. * [HierarchicalGraph](https://arongranberg.com/astar/docs/hierarchicalgraph.html) Holds a hierarchical graph to speed up certain pathfinding queries. * [HierarhicalNodeData](https://arongranberg.com/astar/docs/hierarhicalnodedata.html) Burst-accessible data about the hierarhical nodes. * [JobRecalculateComponents](https://arongranberg.com/astar/docs/jobrecalculatecomponents.html) * [Context](https://arongranberg.com/astar/docs/context2.html) * [IAstarAI](https://arongranberg.com/astar/docs/iastarai.html) Common interface for all movement scripts in the A\* [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) Project. * [IGraphInternals](https://arongranberg.com/astar/docs/igraphinternals.html) Exposes internal methods for graphs. * [IGraphUpdateContext](https://arongranberg.com/astar/docs/igraphupdatecontext.html) Helper functions for graph updates. * [IGraphUpdatePromise](https://arongranberg.com/astar/docs/igraphupdatepromise.html) Promise representing a graph update. * [INavmeshHolder](https://arongranberg.com/astar/docs/inavmeshholder.html) Interface for something that holds a triangle based navmesh. * [Int3](https://arongranberg.com/astar/docs/int3.html) Holds a coordinate in (integer) millimeters. * [IntBounds](https://arongranberg.com/astar/docs/intbounds.html) Integer bounding box. * [IntRect](https://arongranberg.com/astar/docs/intrect.html) Integer Rectangle. * [IOffMeshLinkHandler](https://arongranberg.com/astar/docs/ioffmeshlinkhandler.html) Interface for handling off-mesh links. * [IOffMeshLinkStateMachine](https://arongranberg.com/astar/docs/ioffmeshlinkstatemachine.html) * [IPathInternals](https://arongranberg.com/astar/docs/ipathinternals.html) Used for hiding internal methods of the [Path](https://arongranberg.com/astar/docs/path.html) class. * [IPathModifier](https://arongranberg.com/astar/docs/ipathmodifier.html) Base for all path modifiers. * [IRaycastableGraph](https://arongranberg.com/astar/docs/iraycastablegraph.html) Graph which supports the Linecast method. * [ITransformedGraph](https://arongranberg.com/astar/docs/itransformedgraph.html) Graph which has a well defined transformation from graph space to world space. * [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) Provides additional traversal information to a path request. * [IUpdatableGraph](https://arongranberg.com/astar/docs/iupdatablegraph.html) [Graphs](https://arongranberg.com/astar/docs/graphs2.html) which can be updated during runtime. * [IVersionedMonoBehaviourInternal](https://arongranberg.com/astar/docs/iversionedmonobehaviourinternal.html) Exposes internal methods from [Pathfinding.VersionedMonoBehaviour](https://arongranberg.com/astar/docs/versionedmonobehaviour.html) . * [IWorkItemContext](https://arongranberg.com/astar/docs/iworkitemcontext.html) Interface to expose a subset of the [WorkItemProcessor](https://arongranberg.com/astar/docs/workitemprocessor.html) functionality. * [LayerGridGraph](https://arongranberg.com/astar/docs/layergridgraph.html) Grid Graph, supports layered worlds. * [LayerGridGraphEditor](https://arongranberg.com/astar/docs/layergridgrapheditor.html) * [LevelGridNode](https://arongranberg.com/astar/docs/levelgridnode.html) Describes a single node for the [LayerGridGraph](https://arongranberg.com/astar/docs/layergridgraph.html) . * [LinkGraph](https://arongranberg.com/astar/docs/linkgraph.html) Graph for off-mesh links. * [LinkGraphUpdatePromise](https://arongranberg.com/astar/docs/linkgraphupdatepromise.html) * [LinkNode](https://arongranberg.com/astar/docs/linknode.html) * [LocalSpaceGraph](https://arongranberg.com/astar/docs/localspacegraph.html) Helper for [Pathfinding.Examples.LocalSpaceRichAI](https://arongranberg.com/astar/docs/localspacerichai.html) . * [MeshNode](https://arongranberg.com/astar/docs/meshnode.html) * [MonoModifier](https://arongranberg.com/astar/docs/monomodifier.html) Base class for path modifiers which can be attached to GameObjects. * [MoveInCircle](https://arongranberg.com/astar/docs/moveincircle.html) Moves an agent in a circle around a point. * [DestinationMoveInCircle](https://arongranberg.com/astar/docs/destinationmoveincircle.html) [ECS](https://arongranberg.com/astar/docs/ecs2.html) component corresponding to [MoveInCircle](https://arongranberg.com/astar/docs/moveincircle.html) . * [MoveInCircleBaker](https://arongranberg.com/astar/docs/moveincirclebaker.html) * [MultiTargetPath](https://arongranberg.com/astar/docs/multitargetpath.html) A path which searches from one point to a number of different targets in one search or from a number of different start points to a single target. * [NavGraph](https://arongranberg.com/astar/docs/navgraph.html) Base class for all graphs. * [NavmeshAdd](https://arongranberg.com/astar/docs/navmeshadd.html) Adds new geometry to a recast graph. * [NavmeshAddEditor](https://arongranberg.com/astar/docs/navmeshaddeditor.html) * [NavmeshBase](https://arongranberg.com/astar/docs/navmeshbase.html) Base class for [RecastGraph](https://arongranberg.com/astar/docs/recastgraph.html) and [NavMeshGraph](https://arongranberg.com/astar/docs/navmeshgraph.html) . * [NavmeshClamp](https://arongranberg.com/astar/docs/navmeshclamp.html) Attach to any GameObject and the object will be clamped to the navmesh. * [NavmeshClipper](https://arongranberg.com/astar/docs/navmeshclipper.html) Base class for the [NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) and [NavmeshAdd](https://arongranberg.com/astar/docs/navmeshadd.html) components. * [NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) Navmesh cutting is used for fast recast/navmesh graph updates. * [Contour](https://arongranberg.com/astar/docs/contour.html) * [ContourBurst](https://arongranberg.com/astar/docs/contourburst.html) * [NavmeshCutEditor](https://arongranberg.com/astar/docs/navmeshcuteditor.html) * [NavmeshCutJobs](https://arongranberg.com/astar/docs/navmeshcutjobs.html) * [AngleComparator](https://arongranberg.com/astar/docs/anglecomparator.html) * [JobCalculateContour](https://arongranberg.com/astar/docs/jobcalculatecontour.html) * [NavmeshEdges](https://arongranberg.com/astar/docs/navmeshedges.html) * [JobCalculateObstacles](https://arongranberg.com/astar/docs/jobcalculateobstacles.html) * [JobResizeObstacles](https://arongranberg.com/astar/docs/jobresizeobstacles.html) * [NavmeshBorderData](https://arongranberg.com/astar/docs/navmeshborderdata.html) Burst-accessible data about borders in the navmesh. * [NavMeshGraph](https://arongranberg.com/astar/docs/navmeshgraph.html) Generates graphs based on navmeshes. * [NavMeshGraphScanPromise](https://arongranberg.com/astar/docs/navmeshgraphscanpromise.html) * [NavMeshGraphUpdatePromise](https://arongranberg.com/astar/docs/navmeshgraphupdatepromise.html) * [NavMeshGraphEditor](https://arongranberg.com/astar/docs/navmeshgrapheditor.html) * [NavmeshPrefab](https://arongranberg.com/astar/docs/navmeshprefab.html) Stores a set of navmesh tiles which can be placed on a recast graph. * [SerializedOutput](https://arongranberg.com/astar/docs/serializedoutput.html) * [SerializeJob](https://arongranberg.com/astar/docs/serializejob.html) * [NavmeshPrefabEditor](https://arongranberg.com/astar/docs/navmeshprefabeditor.html) Editor for the [NavmeshPrefab](https://arongranberg.com/astar/docs/navmeshprefab.html) component. * [NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) Constraint for the [AstarPath.GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html) method. * [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) Nearest node constraint. * [NNConstraintGraphUpdateObjectProxy](https://arongranberg.com/astar/docs/nnconstraintgraphupdateobjectproxy.html) Helper proxy for handling compatibility with the old [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) API. * [NNConstraintPathProxy](https://arongranberg.com/astar/docs/nnconstraintpathproxy.html) Helper proxy for handling compatibility with the old [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) API. * [NNInfo](https://arongranberg.com/astar/docs/nninfo.html) Result of a nearest node query. * [NodeLink](https://arongranberg.com/astar/docs/nodelink.html) Connects two nodes with a direct connection. * [NodeLink2](https://arongranberg.com/astar/docs/nodelink2.html) Connects two nodes using an off-mesh link. * [NodeLink2Editor](https://arongranberg.com/astar/docs/nodelink2editor.html) * [NodeLink3](https://arongranberg.com/astar/docs/nodelink3.html) Connects two TriangleMeshNodes (recast/navmesh graphs) as if they had shared an edge. * [NodeLink3Node](https://arongranberg.com/astar/docs/nodelink3node.html) * [OffMeshLinks](https://arongranberg.com/astar/docs/offmeshlinks.html) Manager for off-mesh links. * [Anchor](https://arongranberg.com/astar/docs/anchor.html) The start or end point of an off-mesh link. * [OffMeshLinkCombined](https://arongranberg.com/astar/docs/offmeshlinkcombined.html) * [OffMeshLinkConcrete](https://arongranberg.com/astar/docs/offmeshlinkconcrete.html) * [OffMeshLinkSource](https://arongranberg.com/astar/docs/offmeshlinksource.html) * [OffMeshLinkTracer](https://arongranberg.com/astar/docs/offmeshlinktracer.html) Information about an off-mesh link. * [OptimizationHandler](https://arongranberg.com/astar/docs/optimizationhandler.html) Helper for enabling or disabling compiler directives. * [DefineDefinition](https://arongranberg.com/astar/docs/definedefinition.html) * [Path](https://arongranberg.com/astar/docs/path.html) Base class for all path types. * [SearchContext](https://arongranberg.com/astar/docs/searchcontext.html) Temporary data for a single path used during the pathfinding process. * [OpenCandidateParams](https://arongranberg.com/astar/docs/opencandidateparams.html) Parameters to OpenCandidateConnectionBurst. * [PathEndingCondition](https://arongranberg.com/astar/docs/pathendingcondition.html) Customized ending condition for a path. * [PathfindingEditorSettings](https://arongranberg.com/astar/docs/pathfindingeditorsettings.html) * [PathfindingTag](https://arongranberg.com/astar/docs/pathfindingtag.html) Represents a single pathfinding tag. * [PathfindingTagDrawer](https://arongranberg.com/astar/docs/pathfindingtagdrawer.html) * [PathHandler](https://arongranberg.com/astar/docs/pathhandler.html) Handles thread specific path data. * [PathModifier](https://arongranberg.com/astar/docs/pathmodifier.html) Base class for path modifiers which are not attached to GameObjects. * [PathNNConstraint](https://arongranberg.com/astar/docs/pathnnconstraint.html) A special [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) which can use different logic for the start node and end node in a path. * [PathNode](https://arongranberg.com/astar/docs/pathnode.html) Stores temporary node data for a single pathfinding request. * [PathProcessor](https://arongranberg.com/astar/docs/pathprocessor.html) * [GraphUpdateLock](https://arongranberg.com/astar/docs/graphupdatelock.html) Prevents pathfinding from running while held. * [PathRequestSettings](https://arongranberg.com/astar/docs/pathrequestsettings.html) Settings for how an agent searches for paths. * [PathReturnQueue](https://arongranberg.com/astar/docs/pathreturnqueue.html) * [PathTracer](https://arongranberg.com/astar/docs/pathtracer.html) Helper for following a path. * [QueueItem](https://arongranberg.com/astar/docs/queueitem.html) * [PathUtilities](https://arongranberg.com/astar/docs/pathutilities.html) Contains useful functions for working with paths and nodes. * [JobFormationPacked](https://arongranberg.com/astar/docs/jobformationpacked.html) * [DistanceComparer](https://arongranberg.com/astar/docs/distancecomparer.html) * [Patrol](https://arongranberg.com/astar/docs/patrol.html) Simple patrol behavior. * [PointGraph](https://arongranberg.com/astar/docs/pointgraph.html) Graph consisting of a set of points. * [PointGraphScanPromise](https://arongranberg.com/astar/docs/pointgraphscanpromise.html) * [PointGraphUpdatePromise](https://arongranberg.com/astar/docs/pointgraphupdatepromise.html) * [PointGraphEditor](https://arongranberg.com/astar/docs/pointgrapheditor.html) * [PointKDTree](https://arongranberg.com/astar/docs/pointkdtree.html) Represents a collection of GraphNodes. * [CompareX](https://arongranberg.com/astar/docs/comparex.html) * [CompareY](https://arongranberg.com/astar/docs/comparey.html) * [CompareZ](https://arongranberg.com/astar/docs/comparez.html) * [Node](https://arongranberg.com/astar/docs/node2.html) * [PointNode](https://arongranberg.com/astar/docs/pointnode.html) Node used for the [PointGraph](https://arongranberg.com/astar/docs/pointgraph.html) . * [Polygon](https://arongranberg.com/astar/docs/polygon.html) Utility functions for working with polygons, lines, and other vector math. * [BarycentricTriangleInterpolator](https://arongranberg.com/astar/docs/barycentrictriangleinterpolator.html) * [ProceduralGraphMover](https://arongranberg.com/astar/docs/proceduralgraphmover.html) Moves a grid or recast graph to follow a target. * [ProceduralGridMover](https://arongranberg.com/astar/docs/proceduralgridmover.html) This class has been renamed to [ProceduralGraphMover](https://arongranberg.com/astar/docs/proceduralgraphmover.html) . * [ProceduralGridMoverEditor](https://arongranberg.com/astar/docs/proceduralgridmovereditor.html) * [Progress](https://arongranberg.com/astar/docs/progress.html) [Progress](https://arongranberg.com/astar/docs/progress.html) info for e.g a progressbar. * [RadiusModifier](https://arongranberg.com/astar/docs/radiusmodifier.html) Radius path modifier for offsetting paths. * [RandomPath](https://arongranberg.com/astar/docs/randompath.html) Finds a path in a random direction from the start node. * [RaycastModifier](https://arongranberg.com/astar/docs/raycastmodifier.html) Simplifies a path using raycasting. * [RaycastModifierEditor](https://arongranberg.com/astar/docs/raycastmodifiereditor.html) * [RecastGraph](https://arongranberg.com/astar/docs/recastgraph.html) Automatically generates navmesh graphs based on world geometry. * [CollectionSettings](https://arongranberg.com/astar/docs/collectionsettings.html) Settings for which meshes/colliders and other objects to include in the graph. * [PerLayerModification](https://arongranberg.com/astar/docs/perlayermodification.html) Per layer modification settings. * [PerTerrainLayerModification](https://arongranberg.com/astar/docs/perterrainlayermodification.html) Per terrain layer modification settings. * [RecastGraphScanPromise](https://arongranberg.com/astar/docs/recastgraphscanpromise.html) * [RecastGraphUpdatePromise](https://arongranberg.com/astar/docs/recastgraphupdatepromise.html) * [RecastMovePromise](https://arongranberg.com/astar/docs/recastmovepromise.html) * [RecastGraphEditor](https://arongranberg.com/astar/docs/recastgrapheditor.html) Editor for the [RecastGraph](https://arongranberg.com/astar/docs/recastgraph.html) . * [RecastMeshObj](https://arongranberg.com/astar/docs/recastmeshobj.html) Explicit mesh object for recast graphs. * [RecastNavmeshModifier](https://arongranberg.com/astar/docs/recastnavmeshmodifier.html) Overrides navmesh generation settings for a single mesh or collider. * [RecastNavmeshModifierEditor](https://arongranberg.com/astar/docs/recastnavmeshmodifiereditor.html) * [RecastTileUpdate](https://arongranberg.com/astar/docs/recasttileupdate.html) Updates the recast tile(s) it is in at start, needs [RecastTileUpdateHandler](https://arongranberg.com/astar/docs/recasttileupdatehandler.html) . * [RecastTileUpdateHandler](https://arongranberg.com/astar/docs/recasttileupdatehandler.html) Helper for easier fast updates to recast graphs. * [RichAI](https://arongranberg.com/astar/docs/richai.html) Advanced AI for navmesh based graphs. * [RichFunnel](https://arongranberg.com/astar/docs/richfunnel.html) * [RichPath](https://arongranberg.com/astar/docs/richpath.html) * [RichPathPart](https://arongranberg.com/astar/docs/richpathpart.html) * [RichSpecial](https://arongranberg.com/astar/docs/richspecial.html) * [RuleAnglePenaltyEditor](https://arongranberg.com/astar/docs/ruleanglepenaltyeditor.html) Editor for the [RuleAnglePenalty](https://arongranberg.com/astar/docs/ruleanglepenalty.html) rule. * [RuleElevationPenaltyEditor](https://arongranberg.com/astar/docs/ruleelevationpenaltyeditor.html) Editor for the [RuleElevationPenalty](https://arongranberg.com/astar/docs/ruleelevationpenalty.html) rule. * [RulePerLayerModificationsEditor](https://arongranberg.com/astar/docs/ruleperlayermodificationseditor.html) Editor for the [RulePerLayerModifications](https://arongranberg.com/astar/docs/ruleperlayermodifications.html) rule. * [RuleTextureEditor](https://arongranberg.com/astar/docs/ruletextureeditor.html) Editor for the [RuleTexture](https://arongranberg.com/astar/docs/ruletexture.html) rule. * [RVONavmeshEditor](https://arongranberg.com/astar/docs/rvonavmesheditor.html) * [RVOSimulatorEditor](https://arongranberg.com/astar/docs/rvosimulatoreditor.html) * [RVOSquareObstacleEditor](https://arongranberg.com/astar/docs/rvosquareobstacleeditor.html) * [Seeker](https://arongranberg.com/astar/docs/seeker.html) Handles path calls for a single unit. * [SeekerEditor](https://arongranberg.com/astar/docs/seekereditor.html) * [SimpleSmoothModifier](https://arongranberg.com/astar/docs/simplesmoothmodifier.html) Modifier which smooths the path. * [SingleNodeBlocker](https://arongranberg.com/astar/docs/singlenodeblocker.html) Blocks single nodes in a graph. * [SmoothModifierEditor](https://arongranberg.com/astar/docs/smoothmodifiereditor.html) * [StartEndModifier](https://arongranberg.com/astar/docs/startendmodifier.html) Adjusts start and end points of a path. * [TargetMover](https://arongranberg.com/astar/docs/targetmover.html) Moves the target in example scenes. * [TemporaryNode](https://arongranberg.com/astar/docs/temporarynode.html) * [ThreadCountExtensions](https://arongranberg.com/astar/docs/threadcountextensions.html) * [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint.html) Specifies which nodes are traversable and which are not. * [TraversalCosts](https://arongranberg.com/astar/docs/traversalcosts.html) Defines the cost of traversing specific nodes when pathfinding. * [TriangleMeshNode](https://arongranberg.com/astar/docs/trianglemeshnode.html) Node represented by a triangle. * [UniqueComponentAttribute](https://arongranberg.com/astar/docs/uniquecomponentattribute.html) * [UnityReferenceHelper](https://arongranberg.com/astar/docs/unityreferencehelper.html) Helper class to keep track of references to GameObjects. * [Vector2IntExtensions](https://arongranberg.com/astar/docs/vector2intextensions.html) * [VectorMath](https://arongranberg.com/astar/docs/vectormath.html) Various vector math utility functions. * [VersionedMonoBehaviour](https://arongranberg.com/astar/docs/versionedmonobehaviour.html) Base class for all components in the package. * [WelcomeScreen](https://arongranberg.com/astar/docs/welcomescreen.html) * [WorkItemProcessor](https://arongranberg.com/astar/docs/workitemprocessor.html) * [BoundsVisualization](https://arongranberg.com/astar/docs/boundsvisualization.html) * [IndexedQueue](https://arongranberg.com/astar/docs/indexedqueue.html) Similar to Queue but allows random access. * [XPath](https://arongranberg.com/astar/docs/xpath.html) Extended [Path](https://arongranberg.com/astar/docs/path.html) . * [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) Core component for the A\* Pathfinding System. * [DebugLimitsCtx](https://arongranberg.com/astar/docs/debuglimitsctx.html) * [DestroyGraphPromise](https://arongranberg.com/astar/docs/destroygraphpromise.html) * [DummyGraphUpdateContext](https://arongranberg.com/astar/docs/dummygraphupdatecontext.html) --- # Changelog - A* Pathfinding Project Changelog ========= * 5.4.5 (2025-11-21) * Breaking changes * Some tree colliders that were previously included in recast graph scans may now be excluded, in accordance with the layer and tag filtering settings on the recast graph. See below for more details. This is a bug fix, but you may have been relying on the previous (incorrect) behavior. * Fixed having many FollowerEntity agents with local avoidance enabled in the exact same position, could cause significant performance issues in some rare cases. * Fixed recast graphs would not take the layers, tags nor collider isTrigger state of tree prefabs into account when scanning. This could result in tree collider being included in the scan even if they should be excluded. * Fixed [NavmeshBase.ReplaceTiles](https://arongranberg.com/astar/docs/navmeshbase/replacetiles.html#ReplaceTiles) not applying tags to the new tiles. * Fixed a small memory leak caused by prefabs sometimes being kept in memory longer than they should, in the Unity editor. * The navmesh graph will now show a "Fix" button if the input mesh is not readable. Clicking the button will try to enable read/write on the mesh import settings automatically. * Fixed an exception that could be thrown when scanning a navmesh graph twice in a row with a null source mesh. * Fixed example code not being updated for 5.4 changes in the [Multiple agent types](https://arongranberg.com/astar/docs/multipleagenttypes.html) tutorial. * Fixed a regression in 5.4 that [FollowerEntity.Move](https://arongranberg.com/astar/docs/followerentity/move.html#Move) would not move the Transform immediately, but only the agent's internal position. * Improved performance and reduced allocations when destroying navmesh/recast graphs. * Reduced allocations when loading graphs. * Add [NavmeshBase.ToTileMeshes](https://arongranberg.com/astar/docs/navmeshbase/totilemeshes.html#ToTileMeshes) method to export tiles of the graph to the portable [TileMeshes](https://arongranberg.com/astar/docs/tilemeshes.html) representation. * Improve performance of serializing and deserializing [TileMeshes](https://arongranberg.com/astar/docs/tilemeshes.html) . * Fixed calling [NavmeshBase.ClearTiles](https://arongranberg.com/astar/docs/navmeshbase/cleartiles.html#ClearTiles) and then [NavmeshBase.ReplaceTiles](https://arongranberg.com/astar/docs/navmeshbase/replacetiles.html#ReplaceTiles) could skip applying navmesh cuts. * Reduce memory usage of recast/navmesh graphs. * Fixed [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) sometimes instantly stopping after a nearby graph update caused the navmesh underneath it to be destroyed. * The FollowerEntity will now refresh the endpoints of any pending path every frame, to ensure it is as up-to-date as possible when the path is calculated. This is important primarily when you have lots of agents calculating paths at the same time, or the game is running at a low framerate. * 5.4.4 (2025-10-06) * Note * This stable release contains the features of all beta releases 5.4.0 through 5.4.3. * Breaking changes * This release contains several breaking changes, check [Upgrading to 5.4 from 5.x](https://arongranberg.com/astar/docs/upgrading.html#v5_4) for more info. * There's compatibility code in place to keep the old APIs working for almost all use cases, but for best performance and accuracy, you should update your code to use the new APIs. * New features and improvements * Added an [ECS example scene](https://arongranberg.com/astar/docs/example_ecs.html) . Your browser does not support the video tag. * Added how-to page about ECS: [Using high performance ECS](https://arongranberg.com/astar/docs/ecs.html) . * The [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) movement script can now be used in ECS subscenes, in which it will be baked into a pure entity. * The [AIDestinationSetter](https://arongranberg.com/astar/docs/aidestinationsetter.html) component now also works in ECS subscenes, being baked into a [DestinationEntity](https://arongranberg.com/astar/docs/destinationentity.html) component. * The [MoveInCircle](https://arongranberg.com/astar/docs/moveincircle.html) component now also works in ECS subscenes, being baked into a [DestinationMoveInCircle](https://arongranberg.com/astar/docs/destinationmoveincircle.html) component. * Added [FollowerEntityProxy](https://arongranberg.com/astar/docs/followerentityproxy.html) which allows you to use a high-level API to interact with a baked [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) . * Added [AstarData.SerializeGraph](https://arongranberg.com/astar/docs/astardata/serializegraph.html) , to serialize a single graph, instead of all of them. * It is now possible to visualize graphs in standalone games. Check the [AstarPath.showGraphsInStandalonePlayer](https://arongranberg.com/astar/docs/astarpath.html#showGraphsInStandalonePlayer) checkbox in A\* Inspector → Settings → Debug. * Added an option for visualizing the bounding boxes of graph updates in the scene view. A\* Inspector → Settings → Debug → [Graph Update Debug Mode](https://arongranberg.com/astar/docs/astarpath.html#graphUpdateDebugMode) . ![](https://arongranberg.com/astar/docs/images/graph_update_debug_mode_inspector@2x.png) ![](https://arongranberg.com/astar/docs/images/graph_update_debug_mode.png) * Added [per terrain layer modifications](https://arongranberg.com/astar/docs/recastgraph.html#perTerrainLayerModifications) to recast graphs. You can use this to paint different tags on recast graphs. For example to make an agent prefer to walk along a road, instead of on the grass next to it. ![](https://arongranberg.com/astar/docs/images/recast/per_terrain_layer_modifications@2x.png) ![](https://arongranberg.com/astar/docs/images/generated/scenes/RecastTerrain/terraintagswithgraph.png) * Making regions harder or easier to traverse has been made more intuitive and accurate. Instead of only allowing a cost for entering a node (which is not very accurate on navmesh/recast graphs as their nodes can vary so much in size), you can now set a cost multiplier which is scaled by the distance traversed inside the node. ![](https://arongranberg.com/astar/docs/images/changelog/tagpopup@2x.png) See [New and more accurate traversal costs on navmesh/recast graphs](https://arongranberg.com/astar/docs/upgrading.html#upgrade-traversalcosts) for more details. * Added a new [NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) struct, which replaces [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) . It works the same as the old NNConstraint, but is more efficient and has a few new features. See [Replace NNConstraint with NearestNodeConstraint](https://arongranberg.com/astar/docs/upgrading.html#upgrade-nnconstraint) for more details. * Added new [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint.html) and [TraversalCosts](https://arongranberg.com/astar/docs/traversalcosts.html) structs to more easily set what nodes are traversable and what costs they have. See [New ways to set traversal constraints and costs on paths](https://arongranberg.com/astar/docs/upgrading.html#upgrade-traversalconstraint) for more details. * The [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) interface has received an overhaul, and can now block individual connections, and provide costs that scale with the distance traversed in a node. See [Overhauled ITraversalProvider](https://arongranberg.com/astar/docs/upgrading.html#upgrade-itraversalprovider) for more details. * Due to the above updates, using tags to create areas with different traversal costs is now much better supported on recast and navmesh graphs. * Added [AIMovementSystemGroup.CustomTimeScale](https://arongranberg.com/astar/docs/aimovementsystemgroup.html#CustomTimeScale) , to control the simulation speed of the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) movement script separately from Unity's Time.timeScale. * Added [FollowerEntity.localAvoidanceTemporarilyDisabled](https://arongranberg.com/astar/docs/followerentity.html#localAvoidanceTemporarilyDisabled) to indicate if local avoidance has been temporarily disabled while traversing an off-mesh link. * Improved performance of the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) movement script. * Added [AstarPath.GetNearestBorder](https://arongranberg.com/astar/docs/astarpath/getnearestborder.html) which finds the nearest navmesh border to a given position. * Added [FollowerEntity.nearestNavmeshBorder](https://arongranberg.com/astar/docs/followerentity.html#nearestNavmeshBorder) as a convenience property for getting the nearest navmesh border to the agent. Your browser does not support the video tag. * Added a nicer error message for the extremely unlikely case that the graphs are fragmented enough to run out of hierarchical nodes. * Improved performance when scanning or updating recast graphs. In particular on the main thread and especially so when using terrains. * Improved performance of linecasts on recast graphs, for many cases quite significantly. * Added an overload of [NavGraph.GetNodes](https://arongranberg.com/astar/docs/navgraph/getnodes.html) that takes a ref parameter with custom data to be passed to the callback. This is useful for avoiding GC allocations when iterating over all nodes in a graph. * The graph index is now displayed in the graph info box in the A\* inspector. * Added [PointGraph.Clear](https://arongranberg.com/astar/docs/pointgraph/clear.html#Clear) , to remove all nodes from a point graph. * Improved [GraphMask](https://arongranberg.com/astar/docs/graphmask.html) so that it can now hold a limited number of large graph indices. Previously it was limited to only graph indices smaller than 31. * Added [GraphMask.FromGraph](https://arongranberg.com/astar/docs/graphmask/fromgraph.html#FromGraph) . * Added [GraphMask.Contains(NavGraph)](https://arongranberg.com/astar/docs/graphmask/contains.html#Contains2) . * Added [GraphMask.containsAllGraphs](https://arongranberg.com/astar/docs/graphmask.html#containsAllGraphs) . * Rewrote the [Working with tags](https://arongranberg.com/astar/docs/tags.html) documentation page to be more clear and up-to-date. * Changes * Made the new version popup a bit less obnoxious. * Changed [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) to look for navmesh borders at the closest point on the navmesh to it, instead of close to its own pivot. This fixes the agent ignoring navmesh walls when being raised high up in the air, and having gravity disabled. * Changed voxel size on recast graphs to be rounded to the nearest multiple of 0.001 (internal integer precision) to fix some issues with rounding errors. * Renamed [IAstarAI.canMove](https://arongranberg.com/astar/docs/iastarai.html#canMove) to [IAstarAI.simulateMovement](https://arongranberg.com/astar/docs/iastarai.html#simulateMovement) , to avoid confusion with the [IAstarAI.isStopped](https://arongranberg.com/astar/docs/iastarai.html#isStopped) property. * Reduced pathfinding thread count on machines with more than 8 cores, when using the AutomaticHighLoad thread count mode. These machines are likely using hyperthreading anyway, and the performance boost from using more threads is not large. However, reducing the thread count reduces the memory overhead quite a bit. * Exposed [FollowerEntity.destinationFacingDirection](https://arongranberg.com/astar/docs/followerentity.html#destinationFacingDirection) . * Linecasts on grid graphs that go directly through a diagonal connection will now actually use that diagonal connection, instead of only using axis-aligned connections. Axis-aligned connections are still possible to use as an automatic fallback, however. * Deprecated GraphUpdateObject.nnConstraint and replaced it with [GraphUpdateObject.graphMask](https://arongranberg.com/astar/docs/graphupdateobject.html#graphMask) . * Changed linecasts on graphs to take a [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint.html) instead of a filter function, for more flexibility. * Made [GraphMask.value](https://arongranberg.com/astar/docs/graphmask.html#value) private. * Removed implicit conversion from integers to [GraphMask](https://arongranberg.com/astar/docs/graphmask.html) s, use e.g. [GraphMask.everything](https://arongranberg.com/astar/docs/graphmask.html#everything) or [GraphMask.FromGraphIndex](https://arongranberg.com/astar/docs/graphmask/fromgraphindex.html#FromGraphIndex) instead. Check [Upgrading to 5.4 from 5.x](https://arongranberg.com/astar/docs/upgrading.html#v5_4) for more info. * Fixes * Fixed local avoidance agents could sometimes get stuck on ghost obstacles, due to hash collisions that were much more likely than they should have been. * Fixed exception when scanning recast graphs on Unity 6.2+ when the new Mesh LOD feature was used. * Fixed compilation warning in Unity 6.2+. * Fixed compatibility with Unity 6.2+, which would otherwise cause baked FollowerEntities to fall through the ground. * Improved error checking when scanning and updating recast graphs. Previously, if the tile contained too many vertices, it could lead to an invalid navmesh and potentially exceptions. Now it will log an error, with instructions for how to remedy the situation, and leave the tile empty. * Fixed some edge cases where the graph visualizations would not show/hide when they should. * Fixed RVO agents that are in the exact same position and have the same destination will now manage to untangle themselves, instead of getting stuck together. * Fixed creating a [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) and immediately setting [FollowerEntity.simulateMovement](https://arongranberg.com/astar/docs/followerentity.html#simulateMovement) to false on the same frame, could cause an exception to be thrown. * Fixed a [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) whose path calculations were failing, would try to recalculate its path basically every frame, instead of backing off after a little while. * Fixed setting the rotation speed of a [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) to infinity would break movement. Now it will be allowed to rotate any amount instantly. * Fixed a [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) whose path calculation failed would continue following its previous path indefinitely. Now the agent will slow down similarly to if [FollowerEntity.isStopped](https://arongranberg.com/astar/docs/followerentity.html#isStopped) is set. * Fixed [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) could in some situations start sliding a tiny amount (around one millimeter per second) when it should be standing still, due to a floating point error. * Fixed removing the [SimulateMovementFinalize](https://arongranberg.com/astar/docs/simulatemovementfinalize.html) ECS component from a [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) would disable too many jobs, and not easily allow you to override how movement was handled. * Fixed the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) could, in some rare cases, end up endlessly spinning in place when a desired facing direction had been set for it. * Fixed selecting a [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) in the unity editor could end up clearing [FollowerEntity.destinationFacingDirection](https://arongranberg.com/astar/docs/followerentity.html#destinationFacingDirection) unintentionally. * Fixed linecasts on grid graphs could produce a longer list of passed through nodes than expected, when the target point was exactly in the corner of a node. * Fixed various issues with using the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) on a grid graph, that could result in choppy movement. * Fixed editing the points of a [GraphUpdateScene](https://arongranberg.com/astar/docs/graphupdatescene.html) could fail to save some changes, due to limitations in Unity's Undo system. * Fixed scanning a recast graph in a world with a terrain that had a missing tree prefab could result in an exception. * Fixed scanning a recast graph in a scene with multiple terrains that shared tree prefabs could throw an exception. * Fixed a memory leak that could cause nodes to linger in memory long after they were removed from the graph. * Fixed [FunnelModifier](https://arongranberg.com/astar/docs/funnelmodifier.html) could skip the first and last portal when [FunnelModifier.splitAtEveryPortal](https://arongranberg.com/astar/docs/funnelmodifier.html#splitAtEveryPortal) was enabled. * Fixed an incompatibility with an older version of the unity collections package, which could cause an exception to be thrown when exiting the scene (introduced in 5.3.7). * Fixed scanning very large layered grid graphs could throw an exception. * Got rid of some small but persistent GC allocations related to debug drawing. * Got rid of some small GC allocations in the example scenes relating to OnGUI calls. * Fixed the update checker throwing exceptions in some rare cases. This was a regression in 5.3.5. * Fixed [ConstantPath.allNodes](https://arongranberg.com/astar/docs/constantpath.html#allNodes) could contain duplicate nodes when used on recast graphs. This was a regression in 5.0. * 5.3.7 (2025-05-06) * Significantly improved performance when scanning grid graphs when using Unity 6000.1+. This optimization has been tried multiple times before, but due to Unity bugs it has had to be rolled back. I think Unity has fixed the final physx bug relating to this now, so this optimization is back. Please report in the forum if you notice any hard crashes of the unity editor, when scanning grid graphs, after this update. * Fixed using local avoidance on rotated graphs and isometric/hexagonal grid graphs could result in agents taking curved instead of straight paths. * Fixed enabling thick raycasts on grid graphs did not do anything. * 5.3.6 (2025-04-25) * Fixed a tiny native memory leak accidentally introduced in 5.3.5. * Fixed using the 'Duplicate Graph' button in the A\* inspector would log a warning about duplicate guids. * Reduced overhead of the RVO system when there are no agents using local avoidance in the scene. * 5.3.5 (2025-04-22) * Added [RecastGraph.collectionSettings.physicsScene](https://arongranberg.com/astar/docs/collectionsettings.html#physicsScene) and [RecastGraph.collectionSettings.physicsScene2D](https://arongranberg.com/astar/docs/collectionsettings.html#physicsScene2D) to allow specifying which physics scene to use when scanning a recast graph. * Added [FollowerEntity.reachedCrowdedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedCrowdedEndOfPath) which is like [FollowerEntity.reachedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedEndOfPath) , but will also return true if the end of the path is crowded, and this agent has stopped because it cannot get closer. Your browser does not support the video tag. * Fixed an edge case which could cause navmesh cutting to throw an exception (regression in 5.3.4). * Fixed [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) would not take tags or penalties into account when simplifying its path on recast/navmesh graphs. This could cause it to move over high penalty areas that it should have avoided. * Fixed [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) would behave strangely on isometric grid graphs. * [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) now behaves better (though not perfectly) on hexagonal graphs. * Fixed [FunnelModifier](https://arongranberg.com/astar/docs/funnelmodifier.html) would not take [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) s into account when simplifying its path on recast/navmesh graphs. * Fixed a minor GC allocation happening every frame when using URP. * Fixed debug drawing would cause a minor overhead even in standalone builds, where it wasn't used. * Fixed a significant memory leak when starting unity in batch mode. * Fixed modifiers attached to a Seeker would not run when pathfinding is done outside of play-mode. * When using [AstarData.DeserializeGraphsAdditive](https://arongranberg.com/astar/docs/astardata/deserializegraphsadditive.html) , the new graphs will fill any empty slots in the array of graphs (if any graphs have been removed), instead of always being appended to the end of the array. This fixes the graphs array growing indefinitely when repeatedly removing and adding graphs in some cases. * 5.3.4 (2025-03-18) * Navmesh cuts now work much better in slopes. Previously, whenever the navmesh cut bounds touched a triangle bounds, the triangle would be cut by the full navmesh cut. Now, the full 3d extruded cut shape is used to calculate the cut. Resulting is more predictable cuts, and fixes a ton of edge cases where a navmesh cut could cause an agent to not be able to navigate across a seemingly navigable area. The video below shows the old behavior on the left, and the new one on the right. Your browser does not support the video tag. * Navmesh cut gizmos are now oriented relative to the closest graph, instead of the first graph. This has no effect on the actual navmesh cut, but it makes it easier to see where the cut will be applied, in case there are multiple graphs in the scene. * Fixed updating a recast graph on a unity terrain could in rare cases create reactangular gaps along a border of tiles. * Reflection is now used to find graph types even in WebGL builds. This allows you to use custom graph types in WebGL builds too. Make sure your custom graph types are annotated with the \[Pathfinding.Util.Preserve\] attribute, otherwise they may be stripped out by the Unity WebGL build process. * Fixed a bug causing navmesh cuts to add a tiny gap in the navmesh. * 5.3.3 (2025-01-31) * Fixed sometimes not being able to delete graphs from [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) components on prefabs. * Fixed a tiny memory leak happening sometimes when editing a prefab with an [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component. * Fixed scanning grid graphs in Unity 6000.0.36f1+ would throw an exception, due to changes to unity's job system. * Fixed setting Recast graph -> 'Filter Objects By' to Tags would incorrectly include everything in the scene. * 5.3.2 (2025-01-27) * Fixed compatibility with com.unity.entities version 1.3.9 (latest version at the time of this update). * Fixed an out of range exception that could happen when using local avoidance and the latest burst package was installed (it was optimizing away my error checking!). * Fixed a rare edge case that could cause the [FunnelModifier](https://arongranberg.com/astar/docs/funnelmodifier.html) on the High setting to produce a weird looking path that included some backtracking. * Fixed an exception could be thrown when cameras were rendered without a color target. * Fixed a race condition that could in rare cases cause an exception to be thrown from [FollowerEntity.SearchPath](https://arongranberg.com/astar/docs/followerentity/searchpath.html#SearchPath) . * Fixed scanning grid graphs with invalid settings could throw an exception. * [GridGraph.SetDimensions](https://arongranberg.com/astar/docs/gridgraph/setdimensions.html#SetDimensions) will now throw an exception if the given width, depth or node size is less than or equal to zero. * [MovementState.hierarchicalNodeIndex](https://arongranberg.com/astar/docs/movementstate.html#hierarchicalNodeIndex) and [MovementControl.hierarchicalNodeIndex](https://arongranberg.com/astar/docs/movementcontrol.html#hierarchicalNodeIndex) are now set to -1 at the end of the [AIMovementSystemGroup](https://arongranberg.com/astar/docs/aimovementsystemgroup.html) to prevent accidental use of stale data. * Fixed the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) would sometimes still use gravity during traversal of off-mesh links, even if the built-in movement was disabled. * Fixed a memory leak that could sometimes happen when calling [FollowerEntity.GetRemainingPath](https://arongranberg.com/astar/docs/followerentity/getremainingpath.html) . * 5.3.1 (2025-01-13) * Fixed a regression in 5.3.0 causing navmesh cutting to be much slower than it should be. * Fixed triangle nodes on recast/navmesh graphs with no adjacent triangles would not be able to be traversed via off-mesh links. * Fixed triangle nodes on recast/navmesh graphs with no adjacent triangles would not be detected by the [ConstantPath](https://arongranberg.com/astar/docs/constantpath.html) path type. * Fixed some missing videos in the [Get started with recast graphs](https://arongranberg.com/astar/docs/getstartedrecast.html) tutorial. * 5.3.0 (2025-01-09) * Added a new get started video: * Rewrote the [Get Started Guide](https://arongranberg.com/astar/docs/getstarted.html) to make it easier to follow, and more up-to-date. * Added a new tutorial: [Get started with grid graphs](https://arongranberg.com/astar/docs/getstartedgrid.html) . * Added a new tutorial: [Get started with point graphs](https://arongranberg.com/astar/docs/getstartedpoint.html) . * Added a new tutorial: [Get started with recast graphs](https://arongranberg.com/astar/docs/getstartedrecast.html) . * Added a lightbox to all images in the documentation. * Various other documentation improvements. * Fixed enabling [FollowerEntity.isStopped](https://arongranberg.com/astar/docs/followerentity.html#isStopped) would make the agent resist being rotated by other means. * Fixed [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) could vibrate a lot when being dragged outside the navmesh. * The [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) control loop now always runs at least once per frame, instead of skipping some frames if the fps was very high. * Fixed a bug causing paths calculating using the Manhattan or None heuristics on grid graphs to look much worse than they should (regression in 5.0). The paths were still optimal, but they were not as straight as they should have been. * Fixed compilation errors when the "com.danielmansson.mathematics.fixedpoint" package was installed in the same project. * Fixed some edge cases where navmesh cuts on recast graphs could break connections between adjacent tiles. * The [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component now defaults to drawing its path in the scene view. This can be disabled in the inspector, or by changing [FollowerEntity.debugFlags](https://arongranberg.com/astar/docs/followerentity.html#debugFlags) . * Fixed the [RuleTexture](https://arongranberg.com/astar/docs/ruletexture.html) on grid graphs would not necessarily realize if its texture reference had changed. * The [RecastGraph](https://arongranberg.com/astar/docs/recastgraph.html) now defaults to a voxel size of 0.25, instead of 0.5. The default character radius was reduced a few versions ago, but the voxel size was not updated to match (it's recommended to keep the voxel size to at most half the character radius). * Fixed the layer mask for the recast graph would be used even if the graph was set to filter by tags, not by layers. * Fixed navmesh cuts could, in very degenerate cases, throw an exception due to an incorrect comparator. * Fixed some edge cases where linecasts on recast/navmesh graphs could return that an obstacle existed if the end point of the linecast was exactly on the border between two nodes. * Fixed an edge case when adding nodes to a point graph that could result in an exception being thrown. * Local avoidance agents in layers that an agent does not try to avoid, no longer count towards the "Max Neighbours" limit. * The FollowerEntity is will now use exponential back off if its path calculations continue to fail. Previously it would try to recalculate its path as quickly as possible in this case, but now it will recalculate its path more slowly to improve performance. * 5.2.5 (2024-11-20) * Breaking changes * If you have built your own ECS baker for the FollowerEntity. You must now also add the [PhysicsSceneRef](https://arongranberg.com/astar/docs/physicssceneref.html) component to the entity. * When the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) traverses off-mesh links and custom off mesh link handling code is used, it will no longer enable the agent's built-in movement by default. Instead it will only be enabled if [AgentOffMeshLinkTraversalContext.enableBuiltInMovement](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext.html#enableBuiltInMovement) is enabled or [AgentOffMeshLinkTraversalContext.MoveTowards](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext/movetowa.html#MoveTowards) is called. This resolves issues many users have had where the agent's built-in movement was interefering with animation-driven movement during off-mesh links. * Fixed navmesh cutting could throw an exception due to a multithreading race condition, if navmesh cutting was used and multiple regular graph updates were happening at the same time (regression in 5.2.0). * Improved performance of [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) slightly. * Fixed the inspector for [RulePerLayerModifications](https://arongranberg.com/astar/docs/ruleperlayermodifications.html) would not properly show the tag dropdown (possibly only an issue in Unity 6). * [RecastGraph.SnapBoundsToScene](https://arongranberg.com/astar/docs/recastgraph/snapboundstoscene.html#SnapBoundsToScene) will now make the bounding box taller to ensure the agent can stand on every valid surface. * The [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) will now use the physics scene from its GameObject when performing raycasts. Previously it always used the default physics scene. This is useful when, for example, you use Unity's multiplayer testing mode, which creates multiple players in the same unity editor instance, each with their own physics scene. * [RecastGraph](https://arongranberg.com/astar/docs/recastgraph.html) s now default to rasterizing colliders, instead of meshes. This has slightly better performance, and is a better choice for most games. * Improved performance when deep profiling is enabled. * Increased the minimum supported version of the (optional) entities package to 1.1.0 (up from 1.0.0). * 5.2.4 (2024-10-14) * Fixed trying to use navmesh cutting with an older version of the Unity collections package could throw an exception, instead of logging an error message saying that this is unsupported. * Fixed an exception that could happen when setting FollowerEntity.movementPlaneSource to NavmeshNormal and the agent lost the path it was following. * Fixed using the [NavmeshAdd](https://arongranberg.com/astar/docs/navmeshadd.html) component could cause Unity to crash (regression in 5.2.0). * Fixed incompatibility with the high definition render pipeline accidentally introduced in 5.2.3. * Fixed the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component throwing an exception if it was opened in prefab isolation mode while the game was running. * Fixed [NavmeshAdd.ForceUpdate](https://arongranberg.com/astar/docs/navmeshadd/forceupdate.html#ForceUpdate) throwing an exception if there was no [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component in the scene. * Fixed gizmos were not rendered when opening prefab assets in isolation mode and the high definition render pipeline was used. * Fixed a memory leak when the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component was put in a prefab. * Fixed an exception that could happen if one tried to load a graph from a zip file that contained nodes (not just settings) into an [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component on a prefab. * 5.2.3 (2024-10-07) * Fixed point graphs could in rare cases get stuck in an infinite loop when scanning. * 5.2.2 (2024-10-05) * **Please** **delete** **your** **previous** **installation** **before** **upgrading**. * Fixed standalone builds would fail for some platforms and configuration options (regression in 5.2.0). * Fixed changing the gravity setting on the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component during runtime would not affect anything. * Changed [FollowerEntity.enableGravity](https://arongranberg.com/astar/docs/followerentity.html#enableGravity) to have no effect if the agent's orientation is set to YAxisForward (2D mode). Gravity does not really make sense for top-down 2D games. The gravity setting is also hidden from the inspector in this mode. * 5.2.1 (2024-10-03) * Fixed upgrading to 5.2.0 from an older version could result in compilation errors. UnityPackages are truly terrible. * Fixed a few edge cases with navmesh cutting (regression in 5.2.0). * Improved navmesh simplification when using navmesh cutting. * 5.2.0 (2024-10-01) * Breaking changes * Renamed RecastMeshObj to [RecastNavmeshModifier](https://arongranberg.com/astar/docs/recastnavmeshmodifier.html) . An interface has been provided to handle backwards compatibility for most cases, but there are some cases where manual script changes are required (a search and replace will do it). * Renamed DynamicGridObstacle to [DynamicObstacle](https://arongranberg.com/astar/docs/dynamicobstacle.html) , because it supports recast graphs too, since a while back. An interface has been provided to handle backwards compatibility for most cases, but there are some cases where manual script changes are required (a search and replace will do it). * The [NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) component now requires Unity 2022.3 or newer to use, due to Unity bugs in earlier versions. * The [NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) component now requires com.unity.collections version 2.2.0 or newer to use. * Moved [ListPool](https://arongranberg.com/astar/docs/listpool.html) , [ArrayPool](https://arongranberg.com/astar/docs/arraypool.html) and [PathPool](https://arongranberg.com/astar/docs/pathpool.html) to a new namespace [Pathfinding.Pooling](https://arongranberg.com/astar/docs/pooling2.html) . * Removed all usages of the custom Int2 struct, and replaced them with Unity's equivalent Vector2Int struct. * Improvements and new features * Significantly improved robustness of navmesh cutting. Previously, if navmesh cuts were placed in just the right way, the cutting could fail and the navmesh would not be updated correctly. This was rare, but if the game allowed user-placed navmesh cuts, it was bound to happen eventually. * Reduced GC allocations during navmesh cutting by up to 85%. * Improved performance of navmesh cutting by about 25%. * Navmesh cutting now works outside play mode too. * Added [AstarPath.Linecast](https://arongranberg.com/astar/docs/astarpath/linecast.html) , which is a convenience method for checking if there is line-of-sight between two points. This will delegate the check to the most reasonable graph. * Added a tutorial on linecasting: [Detecting obstacles along a line](https://arongranberg.com/astar/docs/linecasting.html) . Your browser does not support the video tag. * Added a tutorial on how to add and remove nodes from a point graph: [Adding custom nodes to point graphs](https://arongranberg.com/astar/docs/creatingpointnodes.html) . * Added [FollowerEntity.CreateEntity](https://arongranberg.com/astar/docs/followerentity/createentity.html#CreateEntity) . A static function to create an entity without using the FollowerEntity MonoBehaviour itself. * Added [NavGraph.RandomPointOnSurface](https://arongranberg.com/astar/docs/navgraph/randompointonsurface.html) to get a random point on the surface of a graph, optionally filtered by a [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) . * Nodes in point graphs can now be removed using [PointGraph.RemoveNode](https://arongranberg.com/astar/docs/pointgraph/removenode.html#RemoveNode) . Previously it was only possible to add nodes. * Point graphs will now draw a box around each node in the scene view, even for nodes that have been added using a script. * It's now possible to duplicate graphs in the inspector. * Improved styling of graph edit icons in the inspector: ![](https://arongranberg.com/astar/docs/images/changelog/edit_icon2@2x.png) * Added [AstarData.DuplicateGraph](https://arongranberg.com/astar/docs/astardata/duplicategraph.html#DuplicateGraph) . * Updated various screenshots in the documentation to be more up to date, and in HiDPI, so they look great on retina displays too. * [FollowerEntity.velocity](https://arongranberg.com/astar/docs/followerentity.html#velocity) can now be assigned to. * Added [IAstarAI.updatePosition](https://arongranberg.com/astar/docs/iastarai.html#updatePosition) and [IAstarAI.updateRotation](https://arongranberg.com/astar/docs/iastarai.html#updateRotation) . These properties have existed on all movement scripts, but they were not added to the interface before. * Reduced GC allocations and improved performance slightly, when loading a sequence of scenes that contain the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component. * Fixes * Fixed [ManagedState.Clone](https://arongranberg.com/astar/docs/managedstate/clone.html#Clone) would throw an exception if its PathTracer was not initialized. * Fixed [SingleNodeBlocker.Block](https://arongranberg.com/astar/docs/singlenodeblocker/block.html#Block) would not unblock the previously blocked node (in contrast to what the documentation said, and different from what the BlockAt method did). * Fixed layered grid graphs could in rare cases generate one-way connections between nodes, when [GridGraph.maxStepUsesSlope](https://arongranberg.com/astar/docs/gridgraph.html#maxStepUsesSlope) was enabled. * Fixed the graph display window in the scene view would be rendered off-screen on HiDPI displays. * Fixed the [GraphUpdateScene](https://arongranberg.com/astar/docs/graphupdatescene.html) shortcuts help window in the scene view would be rendered off-screen on HiDPI displays. * Fixed [FollowerEntity.SearchPath](https://arongranberg.com/astar/docs/followerentity/searchpath.html#SearchPath) would not take into account any custom pathfinding settings set on the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component. * Fixed undo events could in some situations reset pathfinding settings on the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component. * Fixed calling [FollowerEntity.GetRemainingPath](https://arongranberg.com/astar/docs/followerentity/getremainingpath.html) could throw an exception if the path contained off-mesh links (recent regression). * Fixed having [FollowerEntity.isStopped](https://arongranberg.com/astar/docs/followerentity.html#isStopped) enabled when a FollowerEntity component was enabled, could cause its rotation to be reset. * Fixed the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) could attach itself to a graph that did not match its graph mask, for a few frames, until its first path was calculated. * Fixed updating a layered grid graph and forcing nodes to be walkable, could, in some cases, create connections to nodes that didn't exist, causing errors later on. * Reduced "shyness" around locked local avoidance agents close to the end of an agent's path. * Fixed the heuristic optimization subsystem could throw an exception in some cases if all graphs were empty. * Fixed scanning a recast graph with very tiny [RecastNavmeshModifier](https://arongranberg.com/astar/docs/recastnavmeshmodifier.html) components could in exceedingly rare cases freeze Unity. * Fixed the [Writing Graph Generators](https://arongranberg.com/astar/docs/writinggraphgenerators.html) tutorial created node connections incorrectly (regression in 5.0). * Fixed one overload of NavmeshBase.Linecast would ignore the **hint** parameter. * Worked around a Unity bug which could cause the welcome screen to throw an exception. * Changes * Removed obsolete script MineBotAI. It has been deprecated for around 7 years and has been replaced by AIPath together with MineBotAnimation. * Removed the experimental warning for the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component. * [RecastGraph.characterRadius](https://arongranberg.com/astar/docs/recastgraph.html#characterRadius) now defaults to 0.5, instead of 1.5. This is a more reasonable default for most humanoid characters. * Split out the [RepairPathSystem](https://arongranberg.com/astar/docs/repairpathsystem.html) from the [FollowerControlSystem](https://arongranberg.com/astar/docs/followercontrolsystem.html) . * Added the DisallowMultipleComponent attribute to the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component, and all built-in movement scripts. * Renamed AstarData.navmesh to [AstarData.navmeshGraph](https://arongranberg.com/astar/docs/astardata.html#navmeshGraph) for consistency. * [NavGraph.RelocateNodes](https://arongranberg.com/astar/docs/navgraph/relocatenodes.html#RelocateNodes) will now verify that it is safe to update nodes. It's safe to update nodes in a work item, or during a graph update. * Moved various internal classes to a new namespace [Pathfinding.Collections](https://arongranberg.com/astar/docs/collections.html) . * Moved various internal classes to a new namespace [Pathfinding.Sync](https://arongranberg.com/astar/docs/sync.html) . * Moved [ListPool](https://arongranberg.com/astar/docs/listpool.html) , [ArrayPool](https://arongranberg.com/astar/docs/arraypool.html) and [PathPool](https://arongranberg.com/astar/docs/pathpool.html) to a new namespace [Pathfinding.Pooling](https://arongranberg.com/astar/docs/pooling2.html) . * Removed AIBase.centerOffset, as it's been deprecated for 6 years. * Removed AIBase.rotationIn2D, as it's been deprecated for 6 years. Use [AIBase.orientation](https://arongranberg.com/astar/docs/aibase.html#orientation) instead. * Removed AILerp.rotationIn2D, as it's been deprecated for 6 years. Use [AILerp.orientation](https://arongranberg.com/astar/docs/ailerp.html#orientation) instead. * Removed AIBase.target, as it's been deprecated for 7 years. Use the [AIDestinationSetter](https://arongranberg.com/astar/docs/aidestinationsetter.html) component instead. * Removed AILerp.target, as it's been deprecated for 7 years. Use the [AIDestinationSetter](https://arongranberg.com/astar/docs/aidestinationsetter.html) component instead. * Removed AILerp.ForceSearchPath, as it's been deprecated for 7 years. Use [AILerp.SearchPath](https://arongranberg.com/astar/docs/ailerp/searchpath.html#SearchPath) instead. * Removed GridNode.GetConnectionInternal, as it's been deprecated for 8 years. Use [GridNode.HasConnectionInDirection](https://arongranberg.com/astar/docs/gridnode/hasconnectionindirection.html#HasConnectionInDirection) instead. * Removed LevelGridNode.HasConnection, as it's been deprecated for 8 years. Use [LevelGridNode.HasConnectionInDirection](https://arongranberg.com/astar/docs/levelgridnode/hasconnectionindirection.html#HasConnectionInDirection) instead. * Removed RVOController.mask, as it's been deprecated for 7 years. Use settings on your movement script instead. * Removed RVOController.enableRotation, as it's been deprecated for 7 years. Use settings on your movement script instead. * Removed RVOController.rotationSpeed, as it's been deprecated for 7 years. Use settings on your movement script instead. * Removed RVOController.maxSpeed, as it's been deprecated for 7 years. Use settings on your movement script instead. * Removed RVOController.ForceSetVelocity, as it's been deprecated for 7 years. Use [RVOController.velocity](https://arongranberg.com/astar/docs/rvocontroller.html#velocity) instead. * Removed RVOController.Teleport, as it's been deprecated for 8 years. It is no longer necessary. * 5.1.6 (2024-08-06) * Fixed compatibility with com.unity.mathematics 1.3.0 and lower. * 5.1.5 (2024-08-06) * If an async scan is running when the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component is disabled, or another scan is started, then the code will block until the in-progress async scan has finished. Previously, unloading a scene while an async scan was running could in some cases lead to memory leaks and exceptions. * Fixed [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) could get teleported a small distance in 2D games, right when the game started. * Fixed [PointGraph.GetNearest](https://arongranberg.com/astar/docs/pointgraph/getnearest.html) could throw an exception in some situations if there was no acceptable node nearby. * Fixed [GridGraph.RelocateNodes](https://arongranberg.com/astar/docs/gridgraph/relocatenodes.html) could leave the grid graph with a corrupted state. * Fixed updating point graphs could throw an exception if some nodes had been manually added to the graph. * Fixed some compilation warnings in Unity 6. * Fixed [FollowerEntity.updateRotation](https://arongranberg.com/astar/docs/followerentity.html#updateRotation) and [FollowerEntity.updatePosition](https://arongranberg.com/astar/docs/followerentity.html#updatePosition) would not always take effect when set from the unity inspector. * Fixed [AstarPath.showSearchTree](https://arongranberg.com/astar/docs/astarpath.html#showSearchTree) could show incorrect information on recast graphs. * Fixed [FloodPathTracer](https://arongranberg.com/astar/docs/floodpathtracer.html) not working with recast graphs (regression in 5.0). * Fixed using graph coloring modes G, H or F on recast graphs could display incorrect information. * Fixed toggling [AstarPath.showSearchTree](https://arongranberg.com/astar/docs/astarpath.html#showSearchTree) would not always re-render the graph visualization. * Fixed an [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) on a [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) could be called with a null node in some cases. * Fixed tons of grammar and spelling mistakes in the documentation. * Fixed Seeker.StartMultiTargetPath would never use the Seeker's graphMask. * Fixed calling [AstarPath.FlushWorkItems](https://arongranberg.com/astar/docs/astarpath/flushworkitems.html#FlushWorkItems) would freeze unity if a work item threw an exception. * [AstarData.DeserializeGraphsAdditive](https://arongranberg.com/astar/docs/astardata/deserializegraphsadditive.html) now returns an array with the deserialized graphs. * Trying to deserialize graphs from an invalid zip file will now throw an exception instead of just logging an error message. * Renamed RecastGraph.SnapForceBoundsToScene to [RecastGraph.SnapBoundsToScene](https://arongranberg.com/astar/docs/recastgraph/snapboundstoscene.html#SnapBoundsToScene) . * RecastGraph.SnapBoundsToScene will now ensure the resulting bounds are non-zero along all axes. * Improved smoothness of the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) when using the [MovementPlaneSource](https://arongranberg.com/astar/docs/ecs2.html#MovementPlaneSource) .NavmeshNormal mode. * The [Spherical Worlds](https://arongranberg.com/astar/docs/spherical.html) example scene now uses the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component instead of the [AIPathAlignedToSurface](https://arongranberg.com/astar/docs/aipathalignedtosurface.html) component. * [AstarPath.showSearchTree](https://arongranberg.com/astar/docs/astarpath.html#showSearchTree) now renders the search tree with thicker lines, to make it easier to see. * Deprecated [PointNode.SetPosition](https://arongranberg.com/astar/docs/pointnode/setposition.html#SetPosition) . Use [PointNode.position](https://arongranberg.com/astar/docs/graphnode.html#position) instead. * Fixed [GridGraphRule.Pass](https://arongranberg.com/astar/docs/gridgraphrule.html#Pass) .AfterApplied not being called in some cases. * 5.1.4 (2024-06-12) * Fixed an exception that could be thrown after updating a graph (regression in 5.1.3). * Reduced memory usage slightly. * Improved performance when updating a recast graph in a scene with a terrain. * 5.1.3 (2024-06-11) * [FollowerEntity.updatePosition](https://arongranberg.com/astar/docs/followerentity.html#updatePosition) and [FollowerEntity.updateRotation](https://arongranberg.com/astar/docs/followerentity.html#updateRotation) can now be set in the inspector, and the values are no longer reset if the component is disabled. * Fixed Unity's Random state would get reset by the FollowerEntity movement script on scene initialization. * Paths now take their assigned [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) into account when finding the start and end nodes. This fixes several issues where an agent could get stuck and not be able to calculate a path, because the node it was standing on (or the node closest to the destination) was walkable according to the path's [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) , but not according to its [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) . * Fixed [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) sometimes getting stuck when traversing non-flat grid graphs. * Fixed [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) could throw an exception if it was disabled while it was traversing an off-mesh link. * Exposed a few more properties in the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) class, and improved its documentation. * The number of temporary nodes for path calculations can now grow automatically. Therefore the ASTAR\_MORE\_MULTI\_TARGET\_PATH\_TARGETS define is no longer needed. This was only of importance if you used multi target paths with a lot of targets, or if you had a very large number of off-mesh links in your scene. * Fixed the 'Round Collider Detail' setting was not visible in the recast graph inspector when in 2D mode in some cases, even when it should. * Fixed [AstarData.DeserializeGraphsAdditive](https://arongranberg.com/astar/docs/astardata/deserializegraphsadditive.html) would not remove null graphs from the end of the list of graphs before appending the new ones. * Fixed disabling a [NavmeshPrefab](https://arongranberg.com/astar/docs/navmeshprefab.html) component could later cause a null reference exception when the graph was destroyed. * Fixed [NavmeshPrefab](https://arongranberg.com/astar/docs/navmeshprefab.html) s could sometimes leave a 1 voxel wide gap at their borders (recent regression). * Various documentation improvements. * 5.1.2 (2024-05-29) * Added [AstarPath.IsPointOnNavmesh](https://arongranberg.com/astar/docs/astarpath/ispointonnavmesh.html#IsPointOnNavmesh) to more easily check if a point is on the navmesh surface of any graph. * Added [NavGraph.IsPointOnNavmesh](https://arongranberg.com/astar/docs/navgraph/ispointonnavmesh.html#IsPointOnNavmesh) , which works the same, but only checks a single graph. * Fixed [ProceduralGraphMover](https://arongranberg.com/astar/docs/proceduralgraphmover.html) would not scan new tiles correctly when moving in the +x or +z directions (recent regression). * Fixed the recast graph inspector would not show the Character Radius field in 2D mode (regression in 5.1.0). * 5.1.1 (2024-05-08) * Added a welcome screen when importing the package into a new project. It makes it easy to import the example scenes into the project, something new users are often confused about how to do. It also has convenient links to the documentation and changelog. ![](https://arongranberg.com/astar/docs/images/changelog/welcome_screen.png) * Added [RecastGraph.collectionSettings.onCollectMeshes](https://arongranberg.com/astar/docs/collectionsettings.html#onCollectMeshes) to allow adding custom meshes to be rasterized by the recast graph. * Fixed [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) could throw an exception when it was scaled by a negative value. * Improved compatibility with other packages. Previously, [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) could throw an exception in some projects if, for example, DoTween Pro was installed. * Improved styling of the documentation. * 5.1.0 (2024-05-02) * Breaking changes * It is no longer possible to use both the layer mask and tag mask at the same time when scanning recast graphs. The tag mask was very seldom used and it was a bit confusing to have both options available at the same time in the inspector. * New Features and improvements * Tags applied when recast graphs are scanned will now be preserved even when using navmesh cutting. Previously, navmesh cutting would not be able to preserve these tags. Note that this only applies to tags that are set either on a [RecastNavmeshModifier](https://arongranberg.com/astar/docs/recastnavmeshmodifier.html) component, or using a graph update that happens during the initial scan. * Navmesh cutting is now better at collapsing adjacent triangles into fewer triangles, if possible. This can improve pathfinding quality, and improve performance ever so slightly. * Restructured the recast graph inspector, with clearer headings and a more consistent layout. ![](https://arongranberg.com/astar/docs/images/changelog/recastgraph_inspector.png) * Recast graphs now have a new option for per layer modifications. This means you can now set tags or make nodes unwalkable based on the layer of the surface under the node, without having to attach a [RecastNavmeshModifier](https://arongranberg.com/astar/docs/recastnavmeshmodifier.html) component to every object. ![](https://arongranberg.com/astar/docs/images/recast/per_layer_modifications@2x.png) * [MecanimBridge](https://arongranberg.com/astar/docs/mecanimbridge.html) now supports the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) movement script. * There's now a button in all relevant example scenes that link them to the corresponding page in the documentation. * When the scene view camera is in 2D mode, one can now add points to the [GraphUpdateScene](https://arongranberg.com/astar/docs/graphupdatescene.html) by shift-clicking even in empty areas of the screen. Previously, one had to click on a GameObject. This should improve the workflow when working on 2D games. * Implemented [FollowerEntity.Move](https://arongranberg.com/astar/docs/followerentity/move.html#Move) . * Changing [FollowerEntity.enableGravity](https://arongranberg.com/astar/docs/followerentity.html#enableGravity) doesn't cause a structural entity change anymore, which means it can be used from an off-mesh link handler. * Fixes and changes * Fixed scanning recast graphs asynchronously could block due to it creating too many jobs, so that Unity forced some to execute on the main thread. * Fixed a few edge cases when scanning recast graphs. * Fixed asynchronously scanning grid graphs would not split up some main thread work into smaller chunks, which could cause frame drops. * Fixed [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) could throw exceptions when traversing a grid graph that was being updated at the same time. * Fixed when adding the first point to a [GraphUpdateScene](https://arongranberg.com/astar/docs/graphupdatescene.html) component by shift-clicking in the scene view, the GameObject could end up being deselected. * Recast graphs now handle degenerate triangles a bit better. * Fixed tiled recast graphs could generate a navmesh outside the bounding box of the graph, if the tile size didn't divide the graph size evenly. * Fixed [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) could get stuck when one of its world coordinates were around 2100, due to coordinate overflows in some calculations. * Added a warning in the grid graph inspector when trying to use the [per layer modifications rule](https://arongranberg.com/astar/docs/ruleperlayermodifications.html) without height testing enabled. * Minor other improvements to editing points for the [GraphUpdateScene](https://arongranberg.com/astar/docs/graphupdatescene.html) component. * Renamed RecastGraph.rasterizeColliders to [RecastGraph.collectionSettings.rasterizeColliders](https://arongranberg.com/astar/docs/collectionsettings.html#rasterizeColliders) . * Renamed RecastGraph.rasterizeMeshes to [RecastGraph.collectionSettings.rasterizeMeshes](https://arongranberg.com/astar/docs/collectionsettings.html#rasterizeMeshes) . * Renamed RecastGraph.rasterizeTerrain to [RecastGraph.collectionSettings.rasterizeTerrain](https://arongranberg.com/astar/docs/collectionsettings.html#rasterizeTerrain) . * Renamed RecastGraph.rasterizeTrees to [RecastGraph.collectionSettings.rasterizeTrees](https://arongranberg.com/astar/docs/collectionsettings.html#rasterizeTrees) . * Renamed RecastGraph.colliderRasterizeDetail to [RecastGraph.collectionSettings.colliderRasterizeDetail](https://arongranberg.com/astar/docs/collectionsettings.html#colliderRasterizeDetail) . * Renamed RecastGraph.mask to [RecastGraph.collectionSettings.layerMask](https://arongranberg.com/astar/docs/collectionsettings.html#layerMask) . * Renamed RecastGraph.tagMask to [RecastGraph.collectionSettings.tagMask](https://arongranberg.com/astar/docs/collectionsettings.html#tagMask) . * Renamed RecastGraph.terrainSampleSize to [RecastGraph.collectionSettings.terrainHeightmapDownsamplingFactor](https://arongranberg.com/astar/docs/collectionsettings.html#terrainHeightmapDownsamplingFactor) . * 5.0.9 (2024-04-15) * Minor internal changes. * Various minor documentation improvements. * Reduced allocations during pathfinding slightly. * 5.0.8 (2024-04-12) * Made [AstarPath.PausePathfindingSoon](https://arongranberg.com/astar/docs/astarpath/pausepathfindingsoon.html#PausePathfindingSoon) public. * Made [RepairPathSystem.ResolveOffMeshLinkHandler](https://arongranberg.com/astar/docs/repairpathsystem/resolveoffmeshlinkhandle.html#ResolveOffMeshLinkHandler) public. * Made [RepairPathSystem.NextLinkToTraverse](https://arongranberg.com/astar/docs/repairpathsystem/nextlinktotraverse.html#NextLinkToTraverse) public. * Added a public constructor for [MovementTarget](https://arongranberg.com/astar/docs/movementtarget.html) . * 5.0.7 (2024-04-11) * New Features and improvements * Improved the [Searching for paths](https://arongranberg.com/astar/docs/callingpathfinding.html) documentation page. * Improved support for [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) on spherical (or other weirdly shaped) worlds, using the new [MovementPlaneSource](https://arongranberg.com/astar/docs/ecs2.html#MovementPlaneSource) .NavmeshNormal mode. Your browser does not support the video tag. * Explicitly reference .dll files in the project to improve compatibility with some IDEs. * Added [AstarPath.GetNavmeshBorderData](https://arongranberg.com/astar/docs/astarpath/getnavmeshborderdata.html#GetNavmeshBorderData) . * Added [AgentOffMeshLinkTraversalContext.Abort](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext/abort.html#Abort) , which can be used to abort traversal of an off-mesh link, from the coroutine that handles it. * Improved performance of the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component. * Fixes and changes * The [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component now shows up as "AstarPath" in the component menu, instead of "Pathfinder". This should make it easier to find for new users, as it is referred to as [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) in the documentation. * Fixed the agent would get stuck on obstacles placed using the "P" key in the "InfiniteWorld" example scene, due to incorrect layer settings. * Fixed various edge cases when the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component is put in a prefab. * Fixed [FollowerEntity.GetRemainingPath](https://arongranberg.com/astar/docs/followerentity/getremainingpath.html) throwing an exception in some cases (regression in 5.0.6). * Fixed [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) drawing graphs even when an unrelated prefab was opened in isolation mode. * Fixed division by zero in [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) when rotation speed was zero. * Fixed a race condition when scanning or updating recast graphs, which could cause graph updates to throw exception in very rare cases. * Fixed [RecastNavmeshModifier](https://arongranberg.com/astar/docs/recastnavmeshmodifier.html) with the WalkableSurfaceWithTag mode could fail to apply the tag if it was also marked as solid, and the surface was close to another surface. * Fixed a small GC allocation happening every frame when using the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component. * Fixed the gravity applied to the [AIPathAlignedToSurface](https://arongranberg.com/astar/docs/aipathalignedtosurface.html) movement script was much higher than it should be. * Fixed the [AIPathAlignedToSurface](https://arongranberg.com/astar/docs/aipathalignedtosurface.html) movement script could throw an exception when completely inside a convex mesh collider. * Fixed [NodeLink2](https://arongranberg.com/astar/docs/nodelink2.html) components could throw an exception if they were loaded in as enabled, but then immediately destroyed before Unity had a chance to call the OnEnable method. * Reduced max graph count from 256 to 255. * Added [GraphNode.InvalidGraphIndex](https://arongranberg.com/astar/docs/graphnode.html#InvalidGraphIndex) . * Renamed AgentOffMeshLinkTraversalContext.linkInfo to [AgentOffMeshLinkTraversalContext.link](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext.html#link) . * 5.0.6 (2024-03-29) * Added [IAstarAI.GetRemainingPath(List,List,bool)](https://arongranberg.com/astar/docs/iastarai/getremainingpath.html#GetRemainingPath2) to get information about all the parts (including off-mesh links) of the path that the agent is currently following. ![](https://arongranberg.com/astar/docs/images/generated/scenes/RecastOffMeshLinks/remainingpath.png) * Fixed [FollowerEntity.GetRemainingPath(List,bool)](https://arongranberg.com/astar/docs/followerentity/getremainingpath.html#GetRemainingPath) would only output the path up to the next off-mesh link. * Fixed [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) could return incorrect values for a few properties (e.g. [FollowerEntity.hasPath](https://arongranberg.com/astar/docs/followerentity.html#hasPath) ) after it had been disabled. * Fixed [RandomPath](https://arongranberg.com/astar/docs/randompath.html) could in very rare situations cause an exception that crashed the pathfinding threads, due to a race condition. * Fixed [MultiTargetPath](https://arongranberg.com/astar/docs/multitargetpath.html) could calculate incorrect paths on grid graphs in some situations. * Fixed various edge cases when the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component is put in a prefab. * Fixed [RecastNavmeshModifier](https://arongranberg.com/astar/docs/recastnavmeshmodifier.html) components could log an error message about being moved, even if they had not moved. * Fixed enabling [ABPath.calculatePartial](https://arongranberg.com/astar/docs/abpath.html#calculatePartial) could cause an exception or an incorrect path to be calculated, in some situations. * Fixed several broken documentation links. * If an [RVOSimulator](https://arongranberg.com/astar/docs/rvosimulator.html) is enabled in a scene that already has an active RVOSimulator, the new one will be disabled and a warning will be logged. This now works like the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component, which also uses a singleton pattern. * 5.0.5 (2024-03-21) * Added [FollowerEntity.movementOverrides](https://arongranberg.com/astar/docs/followerentity.html#movementOverrides) to allow more easily overriding custom movement logic for the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component. Your browser does not support the video tag. * Made [GraphUpdateScene.GetGraphUpdate](https://arongranberg.com/astar/docs/graphupdatescene/getgraphupdate.html#GetGraphUpdate) virtual. * Fixed agents with the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component trying to traverse an off-mesh link could get stuck waiting for a long time at the beginning of the link, if either local avoidance or rotation smoothing was enabled. * Fixed help links for components used an incorrect extension, and would therefore often not work. * 5.0.4 (2024-03-15) * Added [RVOController.SetObstacleQuery](https://arongranberg.com/astar/docs/rvocontroller/setobstaclequery.html#SetObstacleQuery) . * Added [GridGraph.GetBoundsFromRect](https://arongranberg.com/astar/docs/gridgraph/getboundsfromrect.html#GetBoundsFromRect) . * Exposed [AstarPath.Snapshot](https://arongranberg.com/astar/docs/astarpath/snapshot.html#Snapshot) . * Improve the [Upgrade Guide](https://arongranberg.com/astar/docs/upgrading.html) . * Clarified the [Installation Guide](https://arongranberg.com/astar/docs/installation.html) . * Fixed [NavmeshAdd](https://arongranberg.com/astar/docs/navmeshadd.html) components not affecting completely empty recast graph tiles. * Fixed [RichAI.steeringTarget](https://arongranberg.com/astar/docs/richai.html#steeringTarget) being incorrect when very close to the destination. * Fixed [NavmeshBase.PointOnNavmesh](https://arongranberg.com/astar/docs/navmeshbase/pointonnavmesh.html) could return null right on the edge beteween two triangles, in some cases. * Fixed an exception that could happen when a degenerate triangle was generated when scanning a recast graph or a navmesh prefab. * Fixed exception that could happen sometimes when the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) was simplifying its path on a grid graph. * Fixed [GridGraph.SetWalkability](https://arongranberg.com/astar/docs/gridgraph/setwalkability.html#SetWalkability) not refreshing off-mesh links. * 5.0.3 (2024-03-09) * Added [NavmeshPrefab.removeTilesWhenDisabled](https://arongranberg.com/astar/docs/navmeshprefab.html#removeTilesWhenDisabled) . * The [NavmeshPrefab](https://arongranberg.com/astar/docs/navmeshprefab.html) will now add its stored tiles to the graph every time the component is enabled, instead of only the first time. * Clarified the [Installation Guide](https://arongranberg.com/astar/docs/installation.html) . * Fixed teleport link in the off-mesh link example scene only worked in the start->end direction, but not in the end->start direction. * Fixed [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) not taking penalties into account when simplifying its path on grid graphs. * Fixed some data migrations for components would not run. * Fixed compilation errors in Unity 2022.1. * Fixed compilation warnings when using older versions of the collections package (before 2.1.0). * Fixed [RVOSimulator.useNavmeshAsObstacle](https://arongranberg.com/astar/docs/rvosimulator.html#useNavmeshAsObstacle) not working with the [AIPath](https://arongranberg.com/astar/docs/aipath.html) and [RichAI](https://arongranberg.com/astar/docs/richai.html) movement scripts. * Renamed AgentOffMeshLinkTraversal.firstPosition to [AgentOffMeshLinkTraversal.relativeStart](https://arongranberg.com/astar/docs/agentoffmeshlinktraversal.html#relativeStart) . * Renamed AgentOffMeshLinkTraversal.secondPosition to [AgentOffMeshLinkTraversal.relativeEnd](https://arongranberg.com/astar/docs/agentoffmeshlinktraversal.html#relativeEnd) . * 5.0.2 (2024-03-06) * Fixed some example scenes contained objects only intended for development, with missing scripts. * 5.0.1 (2024-03-05) * The Asset Store version of the package is now distributed as an NPM package, instead of a UnityPackage. This should make it easier to install and update the package. * 5.0 (2024-03-05) * **Read more about the new features in the [blog post](https://arongranberg.com/2024/02/a-pathfinding-project-5-0/) **. * These release notes combine all changes that were evaluated in the 4.3.x beta versions which lead up to the 5.0 release. * **Major New Features** * Burst powered scanning of recast graphs. Recast graphs now use the Burst Compiler and the Unity Job System. Together with a lot of work on improving the underlying algorithms, this has resulted in much faster scans and updates of recast graphs. It’s now up to 3.5x faster. Graph updates and async scans also run almost entirely in separate threads now, to make the fps impact as minimal as possible. * Burst powered scanning of grid graphs and layered grid graphs. Grid graphs have received a major rewrite in how they scan the graph. It is now powered by burst and the unity job system, which makes scanning graphs around 3x faster. It also supports new features like the [Max Step Uses Slope](https://arongranberg.com/astar/docs/gridgraph.html#maxStepUsesSlope) option, which makes the graph much better connected in most scenarios involving slopes. When upgrading this field will be disabled for compatibility reasons, but it will be enabled for all new graphs. ![](https://arongranberg.com/astar/docs/images/gridgraph/max_step_uses_slope.png) * There's also a whole new system for creating rules for grid graphs. These rules allow you to tweak the grid graph scanning process in a very flexible way, which also works with graph updates transparently. See [Grid Graph Rules](https://arongranberg.com/astar/docs/gridrules.html) . * For 2D enthusiasts, the grid graph can now align itself to a Tilemap directly from the inspector. Something which otherwise might require complex trigonometry, especially for isometric games, or those using hexagonal tiles. ![](https://arongranberg.com/astar/docs/images/gridgraph/tilemap_result.png) * More accurate and faster linecasts on grid graphs Linecasts on grid graphs have received a major rewrite, with a big focus on robustness and correctness. Previously, edge cases like "the linecast goes precisely along the border to an unwalkable obstacle", or "the linecast ends exactly at a corner of an obstacle", were not well defined. Now, the between the walkable part of the navmesh and the obstacles is defined as walkable. Edge cases are handled a lot better now. * New local avoidance algorithm * The new local avoidance algorithm based on ORCA (Optimal Reciprocal Collision Avoidance), leads to nicer movement in most cases. * It's also faster! Not only due to the new algorithm, but also because now everything is powered by burst and the unity job system. Local avoidance is up to **10x faster** than in 4.2.x. * Takes the navmesh into account. The local avoidance system now takes the navmesh into account automatically, and with good performance. Previously, the RVONavmesh component has been used for a similar result, but it had much worse performance, and it was not as robust. ![](https://arongranberg.com/astar/docs/images/rvo/rvo_stress_30000_white.png) * New ECS-powered movement script: [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) . The focus for this new movement script is that it should “just work”, and that it should be very robust and handle all those pesky edge cases. In terms of performance, it’s also slightly better than both the AIPath and RichAI movement scripts. Out of the box, it supports local avoidance, smooth and very responsive movement, off-mesh links, staying away from walls, facing a given direction when it reaches its destination, and a lot more. You do not need to know anything about ECS to use it, everything is abstracted away, and you can use it much like the other movement scripts. * The [ProceduralGraphMover](https://arongranberg.com/astar/docs/proceduralgraphmover.html) (previously ProceduralGridMover) now supports recast graphs too. Now your infinite worlds can have recast graphs too! Your browser does not support the video tag. * Improved off-mesh links Off-mesh links have been almost completely rewritten to be more robust and easier to use. You can now specify a tag for them, and choose which graphs they are allowed to link. They are also much more robust when combined with graph updates, whereas previously they could sometimes lose their connection to the navmesh. And during those graph updates, they require much less cpu power to refresh themselves, so now you can have a lot more of them in your scene without any performance issues. Take a look at the new tutorial on off-mesh links: [Recast graph with off-mesh links](https://arongranberg.com/astar/docs/example_recast_offmeshlinks.html) . Your browser does not support the video tag. * Added support for all 'Enter Play Mode Options' options. This means you can cut down on your iteration times significantly. See [https://docs.unity3d.com/Manual/ConfigurableEnterPlayMode.html](https://docs.unity3d.com/Manual/ConfigurableEnterPlayMode.html) * Improved Documentation * Added new tutorials and documentation pages: * [Off-mesh links](https://arongranberg.com/astar/docs/offmeshlinks2.html) . Your browser does not support the video tag. * [Pathfinding on tilemaps](https://arongranberg.com/astar/docs/tilemaps.html) . ![](https://arongranberg.com/astar/docs/images/gridgraph/tilemap_result.png) * [Circling a target](https://arongranberg.com/astar/docs/move_in_circle.html) . Your browser does not support the video tag. * [Moving a graph at runtime](https://arongranberg.com/astar/docs/moving_graph.html) . * [Agent-Specific Pathfinding](https://arongranberg.com/astar/docs/traversal_provider.html) . * [Grid Graph Rules](https://arongranberg.com/astar/docs/gridrules.html) . * [Writing Custom Grid Graph Rules](https://arongranberg.com/astar/docs/gridruleswrite.html) . * [Manual Player Movement](https://arongranberg.com/astar/docs/playermovement.html) . * Added 6 new example scenes, each with their own dedicated page in the documentation: * Added a new example scene: [Recast graph in a 3D game](https://arongranberg.com/astar/docs/example_recast3d.html) ![](https://arongranberg.com/astar/docs/images/generated/scenes/Recast3D/overview.png) * Added a new example scene: [Recast graph with doors](https://arongranberg.com/astar/docs/example_recast_doors.html) ![](https://arongranberg.com/astar/docs/images/generated/scenes/RecastDoors/overview.png) * Added a new example scene: [Recast graph in a 2D game](https://arongranberg.com/astar/docs/example_recast2d.html) ![](https://arongranberg.com/astar/docs/images/generated/scenes/Recast2D/overview.png) * Added a new example scene: [Recast graph with off-mesh links](https://arongranberg.com/astar/docs/example_recast_offmeshlinks.html) Your browser does not support the video tag. * Added a new example scene: [Recast graph with tags](https://arongranberg.com/astar/docs/example_recast_tags.html) ![](https://arongranberg.com/astar/docs/images/generated/scenes/RecastTags/overview.png) * Added a new example scene: [Recast graph on a terrain](https://arongranberg.com/astar/docs/example_recast_terrain.html) ![](https://arongranberg.com/astar/docs/images/generated/scenes/RecastTerrain/overview.png) * Added a documentation page for the turn based example scene: [Hexagonal Turn Based](https://arongranberg.com/astar/docs/example_turn_based.html) ![](https://arongranberg.com/astar/docs/images/generated/scenes/HexagonalTurnBased/overview.png) * Improved the infinite world example scene with nicer meshes: [Infinite procedurally generated world](https://arongranberg.com/astar/docs/example_infinite_world.html) ![](https://arongranberg.com/astar/docs/images/generated/scenes/InfiniteWorld/overview.png) * Improved documentation and look of the path types example scene: [Path Types](https://arongranberg.com/astar/docs/example_path_types.html) ![](https://arongranberg.com/astar/docs/images/generated/scenes/PathTypes/multitargetpath.png) * Improved documentation and look of the moving example scene: [Recast graph on a moving surface](https://arongranberg.com/astar/docs/example_recast_moving.html) ![](https://arongranberg.com/astar/docs/images/generated/scenes/RecastMoving/overview.png) * Added a flowchart to help new users find the right graph type for their game. See [TL;DR Which graph should I use?](https://arongranberg.com/astar/docs/graphtypes.html#graph-tldr) . * Improved accuracy of path searches on recast/navmesh graphs significantly. * Previously, paths on recast/navmesh graphs have been searched by going from triangle center to triangle center. This is not very accurate and can lead to agents choosing suboptimal paths. Now, paths use a more accurate method which moves between different points on the sides of the triangles instead of the centers. This is much more accurate and should lead to agents choosing better paths in almost all cases. * It also accounts for the exact start and end point of the path more accurately now. * However, this improved accuracy comes with a cost, and pathfinding performance on navmesh/recast graphs is a bit lower than before. Luckily, it is still very fast, and most games are not bottlenecked by this. * Recast graphs now treat convex colliders (box, sphere, capsule and convex mesh colliders) are as solid, and will no longer generate a navmesh inside of them. * Recast graphs now have better support for trees * Colliders on child objects will also be taken into account. * You can use the [RecastNavmeshModifier](https://arongranberg.com/astar/docs/recastnavmeshmodifier.html) component on trees to cutomize how they are rasterized. * Significantly improved performance when you have many trees. * Tree rotation is now taken into account. * You can now mark surfaces with specific tags, for recast graphs. Just add the [RecastNavmeshModifier](https://arongranberg.com/astar/docs/recastnavmeshmodifier.html) component to an object and set the mode to [RecastNavmeshModifier.Mode.WalkableSurfaceWithTag](https://arongranberg.com/astar/docs/recastnavmeshmodifier.html#WalkableSurfaceWithTag) . * [NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) s now support some 3D shapes (box/sphere/capsule) in addition to the previous 2D shapes (rectangle/circle) which makes them a lot more pleasant to use. * Your browser does not support the video tag. * [NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) s now support expanding the cut by the agent radius. Making them more useful if you have multiple graphs for different agent sizes. * The recast graph now supports terrain holes. * Added support for pathfinding, local avoidance and movement on spherical worlds, and other strange world shapes. See [Spherical Worlds](https://arongranberg.com/astar/docs/spherical.html) . * Added 2D support for the recast graph. The recast graph now supports 2D colliders and the inspector has a new enum that allows you to change between 2D and 3D mode. There's a new field [RecastGraph.backgroundTraversability](https://arongranberg.com/astar/docs/recastgraph.html#backgroundTraversability) that controls if a navmesh should be generated for an unobstructed background in 2D mode. * Improved consistency guarantees when doing an async graph scan. Previously, the graphs could be in partially scanned states during the scan, which could cause e.g. GetNearest calls to return incorrect results, or throw exceptions. Now, the graphs will be in a consistent state at all times during the scan (from the main thread's perspective). * Added icons to many components. This should make it easier to find the right component in the inspector. ![](https://arongranberg.com/astar/docs/images/changelog/component_icons.png) * Added [NavmeshPrefab](https://arongranberg.com/astar/docs/navmeshprefab.html) to allow easily storing recast graph tiles in prefabs and load them at runtime (great for big procedurally generated levels). * The LayeredGridGraph now supports 8 neighbours per node instead of 4 as was the case previously. * You can now right-click on almost any property in a component, and get a link directly to the online-documentation for it. This existed in some old versions too, but it had to be removed due to Unity limitations. But now it’s back again! * When hovering over properties in the Unity inspector, you now get much better tooltips on most components. * **New Features and Improvements** * Added [NodeLink2.graphMask](https://arongranberg.com/astar/docs/nodelink2.html#graphMask) , which allows you to set which graphs a link is allowed to connect. * Added [GridNodeBase.OffsetToConnectionDirection](https://arongranberg.com/astar/docs/gridnodebase/offsettoconnectiondirection.html#OffsetToConnectionDirection) . * Added [GridNodeBase.CoordinatesInGrid](https://arongranberg.com/astar/docs/gridnodebase.html#CoordinatesInGrid) , which is the vector ( [GridNodeBase.XCoordinateInGrid](https://arongranberg.com/astar/docs/gridnodebase.html#XCoordinateInGrid) , [GridNodeBase.ZCoordinateInGrid](https://arongranberg.com/astar/docs/gridnodebase.html#ZCoordinateInGrid) ), but calculated in a more optimized way. * Added support for triggering an [Interactable](https://arongranberg.com/astar/docs/interactable.html) component using an off-mesh link. * Added [NodeLink2.onTraverseOffMeshLink](https://arongranberg.com/astar/docs/nodelink2.html#onTraverseOffMeshLink) to allow custom traversal logic for specific off-mesh links. * [NodeLink2](https://arongranberg.com/astar/docs/nodelink2.html) now automatically updates the graph connections when the links is moved around, even when not in play mode. * [NodeLink2](https://arongranberg.com/astar/docs/nodelink2.html) 's gizmos are now aligned to the graph it is connected to. * Improved performance when doing small graph updates on a recast graph, when there's a large terrain in the scene. * Optimized graph updates on recast graph so that if multiple graph updates are scheduled that try to update the same tiles, it will try to avoid doing duplicate work. This can significantly improve performance when using e.g. the [DynamicObstacle](https://arongranberg.com/astar/docs/dynamicobstacle.html) component. * Reworked how one-way links are handled internally. This fixes a number of issues with one-way links, that could lead to exceptions or pathfinding just not working. Even for a one-way link, the target node now also knows that it has a connection to the source node. * Added [GraphNode.AddPartialConnection](https://arongranberg.com/astar/docs/graphnode/addpartialconnection.html#AddPartialConnection) and [GraphNode.RemovePartialConnection](https://arongranberg.com/astar/docs/graphnode/removepartialconnection.html#RemovePartialConnection) for the cases where you need low-level connection modifications. * Added a filter parameter to [GraphNode.GetConnections](https://arongranberg.com/astar/docs/graphnode/getconnections.html) to allow excluding incoming or outgoing connections. By default it only includes outgoing connections. * Added a link to the online documentation when right-clicking on fields in the Unity inspector (supported for most, but not all, fields). This was removed a while ago due to Unity limitations, but it is now back! * Added better tooltips for most components. * Added [NavGraph.bounds](https://arongranberg.com/astar/docs/navgraph.html#bounds) . * Added a warning if the input mesh to a navmesh graph contains degenerate triangles. These triangles are now also removed automatically, instead of causing errors down the line. * Added [GridGraph.SetWalkability](https://arongranberg.com/astar/docs/gridgraph/setwalkability.html#SetWalkability) as a helper function to set walkability for many nodes at once. * Added [IAstarAI.movementPlane](https://arongranberg.com/astar/docs/iastarai.html#movementPlane) . * Off-mesh links are now never serialized with the graphs. Instead, the NodeLink2 component will always recreate them when the scene is loaded. This significantly reduces ways things can get out of sync. * Off-mesh links are now smarter about when they recalculate their connections due to graph updates. This resolves several previous issues in which off-mesh links could be broken by graph updates. * Significantly refactored how graphs are updated and scanned. All graph updates now guarantee that any updates will be done atomically from the main-thread's perspective. Previously, in-progress graph updates could in some cases be visible, leading to weird results from e.g. the GetNearest method. It could also lead to exceptions when using the FollowerEntity component. * Graphs are now scanned and updated concurrently. Previously, only one graph could be scanned or updated at a time (even if they might have used parallelism internally). * Added a new example movement behavior: [MoveInCircle](https://arongranberg.com/astar/docs/moveincircle.html) . * Improve graph update performance when there are lots of dynamic [RecastNavmeshModifier](https://arongranberg.com/astar/docs/recastnavmeshmodifier.html) components in the scene. * The documentation now includes screenshots of the inspector for all components in the package. * Added [AstarPath.OnPathsCalculated](https://arongranberg.com/astar/docs/astarpath.html#OnPathsCalculated) . * Added [GraphDebugMode.NavmeshBorderObstacles](https://arongranberg.com/astar/docs/pathfinding.html#NavmeshBorderObstacles) . * Clarified documentation on [GraphHitInfo](https://arongranberg.com/astar/docs/graphhitinfo.html) 's fields, about what their values are when no obstacle was hit. * Added ASTAR\_MORE\_MULTI\_TARGET\_PATH\_TARGETS to the A\* Inspector -> Optimizations tab. It allows you to increase the maximum number of targets for a multi target path from around 256 to around 4096. * Reduced likelyhood of gaps being generated between tiles in recast graphs. This will reduce the precision of the navmesh a bit on the y-axis along tile edges, but agents should be able to navigate better (and it will look better). * Combined several methods in the layered grid graph and regular grid graph to use the same implementation, reducing code duplication and improving compile times. * Added [GridGraph.RecalculateConnectionsInRegion](https://arongranberg.com/astar/docs/gridgraph/recalculateconnectionsinregion.html#RecalculateConnectionsInRegion) . * Added [GridGraph.RecalculateAllConnections](https://arongranberg.com/astar/docs/gridgraph/recalculateallconnections.html#RecalculateAllConnections) . * The grid graph inspector will now list which tags will be used for erosion, when the tags option is enabled. * You can now choose which tags erosion is allowed to overwrite, when the tags option is enabled, using the new [GridGraph.erosionTagsPrecedenceMask](https://arongranberg.com/astar/docs/gridgraph.html#erosionTagsPrecedenceMask) option. * Changed the behavior of the recast graph's collider detail field. Previously it would not scale with the cell size, which made it hard to transfer between scenes of different scales. Now it scales with the cell size, so leaving it at the default value of 1 should work well for almost all games. * The recast graph's center, size and rotation fields will now be rounded to a multiple of 0.5 if it is very close to one. * Added [AIDestinationSetter.useRotation](https://arongranberg.com/astar/docs/aidestinationsetter.html#useRotation) , which is usable with the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) movement script. Your browser does not support the video tag. * Navmesh graphs now have an option to expand all navmesh cuts by a constant amount. * Simplified the code for path types significantly. There's now a lot more code sharing. * Improved the [MultiTargetPath](https://arongranberg.com/astar/docs/multitargetpath.html) . * It now properly properly works even with multiple targets within a single node. This is particularly important for accuracy on navmesh graphs. Previously all endpoints would be snapped to the closest node center. * Improved performance when only finding the closest target ( [MultiTargetPath.pathsForAll](https://arongranberg.com/astar/docs/multitargetpath.html#pathsForAll) \=false), sometimes significantly so. * Removed the MultiTargetPath.heuristicMode field, it now automatically does the best thing. * Added an overload of [GraphNode.GetConnections](https://arongranberg.com/astar/docs/graphnode/getconnections.html) which takes a ref value that will be passed to the callback. This can be used to avoid allocations when getting connections due to not having to allocate a closure. * [ABPath](https://arongranberg.com/astar/docs/abpath.html) now accepts an ending condition ( [ABPath.endingCondition](https://arongranberg.com/astar/docs/abpath.html#endingCondition) ), making the XPath path type obsolete. * Added [NodeLink2.pathfindingTag](https://arongranberg.com/astar/docs/nodelink2.html#pathfindingTag) to be able to control which agents can traverse an off-mesh link. * Added the [PathfindingTag](https://arongranberg.com/astar/docs/pathfindingtag.html) struct. You can add this to your scripts to automatically get a nice dropdown in the inspector for selecting pathfinding tags. * Added [GraphNode.ContainsPoint(Vector3)](https://arongranberg.com/astar/docs/graphnode/containspoint.html#ContainsPoint) and [GraphNode.ContainsPointInGraphSpace](https://arongranberg.com/astar/docs/graphnode/containspointingraphspace.html#ContainsPointInGraphSpace) . * Added [GridNodeBase.ContainsPoint](https://arongranberg.com/astar/docs/gridnodebase/containspoint.html) and [GridNodeBase.ContainsPointInGraphSpace](https://arongranberg.com/astar/docs/gridnodebase/containspointingraphspace.html#ContainsPointInGraphSpace) . * [RecastNavmeshModifier](https://arongranberg.com/astar/docs/recastnavmeshmodifier.html) components now have a "Geometry Source" field, so that you can choose manually if you want to use a mesh or a collider when voxelizing it. * [RecastNavmeshModifier](https://arongranberg.com/astar/docs/recastnavmeshmodifier.html) components now have a "Include In Scan" field, which allows you to choose if the object should be filtered using layer/tag masks, or if it should always/never be included in the scan. Previously RecastNavmeshModifier components were always included in the scan. When upgrading from, all existing RecastNavmeshModifier components will be set to "AlwaysInclude" for compatibility. * Added support for scheduling paths ( [AstarPath.StartPath](https://arongranberg.com/astar/docs/astarpath/startpath.html#StartPath) ) from within the Unity Job System. * Allow running nearest node queries and other node lookup functions from within the unity job system. This requires you to call the [AstarPath.LockGraphDataForReading](https://arongranberg.com/astar/docs/astarpath/lockgraphdataforreading.html#LockGraphDataForReading) function to ensure safety. * Reduced the overhead of having many [AIDestinationSetter](https://arongranberg.com/astar/docs/aidestinationsetter.html) components. * Added a new distance metric when searching for the closest node: [DistanceMetric.ClosestAsSeenFromAboveSoft(Vector3)](https://arongranberg.com/astar/docs/distancemetric/closestasseenfromabovesoft.html#ClosestAsSeenFromAboveSoft2) . This is much nicer for character movement in most cases, and also usually faster than the default euclidean metric. ![](https://arongranberg.com/astar/docs/images/distance_metric/distance_metric_manhattan_soft.png) * Improved performance when searching for nearest nodes on navmesh/recast graphs (sometimes up to 5x, but typically only by a small percentage). * Improved rebuild performance of the recast/navmesh internal bounding box tree (particularly important when using navmesh cutting). * Improved accuracy of GetNearest calls on grid graphs. Previously the returned node was not necessarily the closest one if [AstarPath.fullGetNearestSearch](https://arongranberg.com/astar/docs/astarpath.html#fullGetNearestSearch) was not enabled. * Added [RecastGraph.Resize](https://arongranberg.com/astar/docs/recastgraph/resize.html#Resize) to allow changing the number of tiles of a graph during runtime. * Added [RecastGraph.ReplaceTiles](https://arongranberg.com/astar/docs/navmeshbase/replacetiles.html#ReplaceTiles) to allow replacing multiple tiles at once. * Added [ITraversalProvider.filterDiagonalGridConnections](https://arongranberg.com/astar/docs/itraversalprovider.html#filterDiagonalGridConnections) for better control over how diagonal grid connections are handled. * Added a warning to the inspector when scanning a recast graph that includes unreadable meshes. Previously a warning would only be logged to the console. ![](https://arongranberg.com/astar/docs/images/changelog/recast_unreadable_warning.png) * Implemented a new and better algorithm for path simplification on grid graphs based on the paper "Toward a String-Pulling Approach to Path Smoothing on Grid Graphs". This essentially makes the raycast modifier obsolete for grid graphs (unless you use the physics raycasting option) as the new algorithm is both faster and more accurate. It is used automatically by the [FunnelModifier](https://arongranberg.com/astar/docs/funnelmodifier.html) on grid graphs. It also takes penalties/tags into account, which has been a long requested feature. * Improved handling of tags and [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) s for grid graphs. Previously when a path was calculated it would only take tag walkability and ITraversalProviders into account in a very basic way. For example normally an agent is not allowed to move diagonally between two unwalkable nodes, even if both the start and end nodes are themselves walkable. However this check did not apply to tags and ITraversalProviders because that info was precalculated and tags/ITraversalProviders can be set per path. Now this is properly taken into account. This also means things like the [GridGraph.cutCorners](https://arongranberg.com/astar/docs/gridgraph.html#cutCorners) option will apply to tags and ITraversalProviders. See [GridNode.FilterDiagonalConnections](https://arongranberg.com/astar/docs/gridnode/filterdiagonalconnections.html#FilterDiagonalConnections) for more details. * Changed when the AIPath/RichAI movement scripts stop when [AIBase.whenCloseToDestination](https://arongranberg.com/astar/docs/aibase.html#whenCloseToDestination) is set to Stop. Previously it would stop up to [AIBase.endReachedDistance](https://arongranberg.com/astar/docs/aibase.html#endReachedDistance) units from the end of the path. end up within [AIBase.endReachedDistance](https://arongranberg.com/astar/docs/aibase.html#endReachedDistance) units from the destination. Essentially [AIBase.reachedDestination](https://arongranberg.com/astar/docs/aibase.html#reachedDestination) would remain false even though the agent could actually reach the destination by just moving a bit further. So this behavior has been changed so that it now only stops when it is within [AIBase.endReachedDistance](https://arongranberg.com/astar/docs/aibase.html#endReachedDistance) units from the destination, not the end of the path. * The [RecastNavmeshModifier](https://arongranberg.com/astar/docs/recastnavmeshmodifier.html) now has an option for making a mesh solid. This is useful to prevent a navmesh from being generated inside objects. * Added [ITraversalProvider.CanTraverse(path,from,to)](https://arongranberg.com/astar/docs/itraversalprovider.html) . This allows you to control not only which nodes are traversable, but also which connections can be used. * The [ProceduralGraphMover](https://arongranberg.com/astar/docs/proceduralgraphmover.html) script now has an option for specifying which graph to update. * Added a mode for the RecastNavmeshModifier to make objects be completely ignored when scanning recast graphs. This is useful if you are running out of layers in your project. * Added [GridNodeBase.HasAnyGridConnections](https://arongranberg.com/astar/docs/gridnodebase.html#HasAnyGridConnections) . * Removed LayerGridGraph.mergeSpanRange. This was a rarely used and hard to understand setting. Now it is automatically set to half the LayerGridGraph.characterHeight. * Improved performance when scanning graphs in the editor outside of play mode by not searching through assemblies for graph types every time. * Made [AstarData.ClearGraphs](https://arongranberg.com/astar/docs/astardata/cleargraphs.html#ClearGraphs) public. * Added a helper window with shortcuts when the GraphUpdateScene object is selected and the Move tool is active. * When GraphModifier events and some callbacks like [AstarPath.OnGraphsUpdated](https://arongranberg.com/astar/docs/astarpath.html#OnGraphsUpdated) are actually fired has been inconsistent and not very well (or accurately) documented for a long time. This release makes it more consistent and better documented. Note that this is a breaking change so if you have used any of those callbacks in your code you may want to have a look at the [Pathfinding.GraphModifier](https://arongranberg.com/astar/docs/graphmodifier.html) documentation which describes when all events are fired. * Added an [FunnelModifier.quality](https://arongranberg.com/astar/docs/funnelmodifier.html#quality) option to try harder to simplify the path when using the FunnelModifier. * To be more descriptive all modifiers have had their visible names changed to include "Modifier" (unless it was already included). This is the same type of simplification that the [RichAI.funnelSimplification](https://arongranberg.com/astar/docs/richai.html#funnelSimplification) option is using. * Added the property [IAstarAI.desiredVelocityWithoutLocalAvoidance](https://arongranberg.com/astar/docs/iastarai.html#desiredVelocityWithoutLocalAvoidance) to the AIPath and RichAI components. This allows you to both read and write the internal velocity of the agent. * The recast graph's position/rotation and size can now be edited using handles in the scene view. * Improved rotation filtering for AIPath/RichAI components. This reduces jitter in the agent's rotation when they are close to standing still. This is particularly important when using local avoidance. * Greatly improved the performance of scanning a grid graph with a high erosion setting. * The RVOSimulator inspector has been improved visually. * Local avoidance now supports more aggressive collision prevention. This is controlled by the [RVOSimulator.hardCollisions](https://arongranberg.com/astar/docs/rvosimulator.html#hardCollisions) field. Enabling this will cause the system to try very hard to avoid any kind of agent overlap, similar to how a physics engine would do it. This does not influence agent avoidance when the agents are not overlapping. * RichAI now has a [RichAI.whenCloseToDestination](https://arongranberg.com/astar/docs/aibase.html#whenCloseToDestination) field which behaves like the one that the AIPath script has had for some time. * AIPath/RichAI now have options for more intelligently stopping earlier if there are already a lot of agents around the destination (see [Pathfinding.AIBase.rvoDensityBehavior](https://arongranberg.com/astar/docs/aibase.html#rvoDensityBehavior) ). This prevents the agents from walking around endlessly trying to reach the destination when many agents have the same destination. This can only be used together with the local avoidance system, i.e. when there's also an RVOController attached to the character. * The [RandomPath](https://arongranberg.com/astar/docs/randompath.html) will now select a random point on the end node, instead of always using the center. If you want to use the center, set Seeker -> Start End Modifier -> End Point Snapping to Node Center. * [GraphNode.RandomPointOnSurface](https://arongranberg.com/astar/docs/graphnode/randompointonsurface.html#RandomPointOnSurface) is now thread-safe. * **Breaking changes** * Take a look at [Upgrade Guide](https://arongranberg.com/astar/docs/upgrading.html) , for help on how to upgrade from 4.2.x to 5.0. * The example script [MineBotAnimation](https://arongranberg.com/astar/docs/minebotanimation.html) has been changed to normalize the NormalizedSpeed parameter it sends to the animator by a new parameter called [MineBotAnimation.naturalSpeed](https://arongranberg.com/astar/docs/minebotanimation.html#naturalSpeed) . * Renamed the ProceduralGridMover component to [ProceduralGraphMover](https://arongranberg.com/astar/docs/proceduralgraphmover.html) , since it now supports more than just grids. * Changed navmesh/recast graph linecasts to return a hit if the linecast started outside the graph. Previously, if doing a linecast from inside the graph to the outside, it would return a hit, but a linecast from the outside to the inside would return no hit. This was a bug, but it's been present for so long that at this point it's basically a breaking change. * The built-in movement scripts no longer listen for **all** paths that their attached Seeker component calculates, instead they only listen for paths that they request. If you have been relying on this by calling seeker.StartPath from another script, and expecting the movement scripts to start to follow the path, you will need to change this to call [ai.SetPath](https://arongranberg.com/astar/docs/iastarai/setpath.html#SetPath) instead. This has been the recommended way to do it for a long time, but now it is required. The Seeker component will log a warning if a path is calculated but no script is listening for its completion. * Namespace structure has been significantly improved. I have tried to keep most changes to internal classes that are not used often by users, but you may have to adjust your **using** statements slightly. Here's a summary of the changes: * [Pathfinding.Graphs.Grid](https://arongranberg.com/astar/docs/grid.html) has been added, and a lot of classes related to the grid graph have been moved there. * [Pathfinding.Graphs.Grid.Jobs](https://arongranberg.com/astar/docs/jobs.html) is new and contains a lot of internal grid scanning code. * [Pathfinding.Graphs.Grid.Rules](https://arongranberg.com/astar/docs/rules.html) is new, and contains grid graph rules. * [Pathfinding.Graphs.Navmesh](https://arongranberg.com/astar/docs/navmesh.html) replaces Pathfinding.Recast. * [Pathfinding.Graphs.Navmesh.Voxelization](https://arongranberg.com/astar/docs/voxelization.html) replaces Pathfinding.Voxels. Sadly C# doesn't support public namespace aliases, so these changes cannot be made backwards compatible. * If you have written your own graph type (one of a rare bunch), you may need to update your scanning code slightly. The [NavGraph.ScanInternal](https://arongranberg.com/astar/docs/navgraph/scaninternal.html) method should now return a [IGraphUpdatePromise](https://arongranberg.com/astar/docs/igraphupdatepromise.html) . Take a look at [Writing Graph Generators](https://arongranberg.com/astar/docs/writinggraphgenerators.html) for more details. * Scanning when the game starts now happens during early **OnEnable** instead of during early **Awake**. This should typically not cause any issues, since it's good practice in Unity to not depend on other components being initialized in **Awake**. But this may cause issues if you have been depending on this very specific initialization order. * The type of some tag fields have changed from int to [PathfindingTag](https://arongranberg.com/astar/docs/pathfindingtag.html) . If you have assigned a tag to those fields before, you will now first need to convert it to a PathfindingTag:`new PathfindingTag((uint)tag) `. * Removed support for deserializing graphs from version 3.8.x and below. 3.8.x was released over 8 years ago, so this should hopefully have given people enough time to upgrade. * [NavGraph.GetNearest](https://arongranberg.com/astar/docs/navgraph/getnearest.html) will now always take the constraint into account. Previously this depended on the graph type and it was generally hard to use to get consistent results across graph types. * [NavGraph.GetNearest](https://arongranberg.com/astar/docs/navgraph/getnearest.html) now returns an [NNInfo](https://arongranberg.com/astar/docs/nninfo.html) instead of a NNInfoInternal. * The [PathInterpolator](https://arongranberg.com/astar/docs/pathinterpolator.html) class has been refactored significantly and now represents points using a Cursor struct, instead of storing it on the interpolator itself. Normally the [PathInterpolator](https://arongranberg.com/astar/docs/pathinterpolator.html) is not used by users, but a few may have used it in their own movement scripts. In that's the case for you, then you will need to make small modifications to your code to create a cursor representing the current point. * Removed support for local avoidance obstacles ( [RVOSquareObstacle](https://arongranberg.com/astar/docs/rvosquareobstacle.html) ). Local avoidance obstacles never worked particularly well and the performance was poor. Use regular graph updates to update the pathfinding graphs instead. * The [RVONavmesh](https://arongranberg.com/astar/docs/rvonavmesh.html) component has been deprecated. This is now handled automatically by enabling the [RVOSimulator.useNavmeshAsObstacle](https://arongranberg.com/astar/docs/rvosimulator.html#useNavmeshAsObstacle) option. * GridGraph.nodes now has the type GridNodeBase\[\] instead of GridNode\[\]. The same is true for the layered grid graph. In most cases everything should work as normal, however if you have been accessing GridNode specific methods or properties on a node you may need to cast the node to a GridNode (or LevelGridNode) to avoid compile errors. * The LayeredGridGraph now only supports 15 layers by default. This is to reduce memory usage for the common case and to reduce code complexity. If this causes issues for your workflow, please let me know in the forum. * Due to local avoidance now supporting non-planar worlds many internal coordinates have been changed from float2 to float3. If you have been using the RVOController script then you do not need to do anything, however if you have used the internal IAgent interface then you may have to change your code a bit to pass 3D coordiantes instead of 2D ones. * GraphModifier events and some callbacks on the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) object (e.g. OnGraphsUpdated) have changed semantics. Read below for more info. * OnPostUpdate no longer runs during scan. * Made GridGraph.neighbourGridOffsetsX and neighbourGridOffsetsZ to static readonly members since they data is constant. * Graph updates for grid graphs no longer call the GraphUpdateObject.Apply method, instead the GraphUpdateObject.ApplyJob method is called. If you have been inheriting from the GraphUpdateObject to make custom graph updates you may need to convert your code so that it works with Burst. * Fixed hexagon connection costs were sqrt(3/2)≈1.22 times too large. The connection costs are now approximately 1000\*the distance between the nodes, as it should be. For example if you have set the hexagon width to 1 then the cost to move between two adjacent hexagons is now 1000 instead of 1224 like it was before. For almost all users this will not affect anything, however it may improve pathfinding performance a bit. If you have been using penalties on your graph then you may have to divide them by 1.22 to get the same behavior. Similarly if you have been using the ConstantPath to get a set of nodes you may have to divide the maxGScore parameter by 1.22. * The AIPath and RichAI scripts no longer use the Update and FixedUpdate methods. Instead a separate script ( [BatchedEvents](https://arongranberg.com/astar/docs/batchedevents.html) ) is used which allows all components of a specific type to be processed at once. This is slightly faster and is also required for the [AIBase.rvoDensityBehavior](https://arongranberg.com/astar/docs/aibase.html#rvoDensityBehavior) implementation. If you have been overriding the Update or FixedUpdate methods you will need to change your code to instead override the OnUpdate method. * Local avoidance has hard collisions enabled by default. If this is not what you want you can disable this in the RVOSimulator component settings. See below for more details. * Changed [IAstarAI.endOfPath](https://arongranberg.com/astar/docs/iastarai.html#endOfPath) to return the agent's current position if the agent has no path, and no destination is set (instead of (+inf,+inf,+inf)). * **Changes** * The [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component will now initialize itself during early **OnEnable** instead of during early **Awake**. This makes it possible to set custom settings on the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component, such as the thread count, from a script when the game starts. Previously this was kinda tricky, since no user scripts would have been run before the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component initialization. * Removed [AstarPath.prioritizeGraphs](https://arongranberg.com/astar/docs/astarpath.html#prioritizeGraphs) . It was always a bit of a hack. Use [NNConstraint.graphMask](https://arongranberg.com/astar/docs/nnconstraint.html#graphMask) if you want to choose which graphs are searched. * Removed [AstarPath.fullGetNearestSearch](https://arongranberg.com/astar/docs/astarpath.html#fullGetNearestSearch) . It is now always treated as true. * Removed double buffering support from the local avoidance system. Double buffering was causing issues with newer features, and it didn't give that much benefit anyway (and caused agents to be less responsive). The system can already simulate up to 30000 agents at 60 fps, so the use cases were limited. * Renamed NNConstraint.Default to [NNConstraint.Walkable](https://arongranberg.com/astar/docs/nnconstraint.html#Walkable) for clarity. * Deprecated a lot of the older example scenes. They have been moved into the OldExamples folder. * Renamed GraphNode.ContainsConnection to [GraphNode.ContainsOutgoingConnection](https://arongranberg.com/astar/docs/graphnode/containsoutgoingconnection.html#ContainsOutgoingConnection) to distinguish incoming from outgoing connections. * Deprecated GraphNode.AddConnection and GraphNode.RemoveConnection. Use the static methods [GraphNode.Connect](https://arongranberg.com/astar/docs/graphnode/connect.html#Connect) and [GraphNode.Disconnect](https://arongranberg.com/astar/docs/graphnode/disconnect.html#Disconnect) instead. * Deprecated [GraphUpdateObject.trackChangedNodes](https://arongranberg.com/astar/docs/graphupdateobject.html#trackChangedNodes) . [AstarPath.Snapshot](https://arongranberg.com/astar/docs/astarpath/snapshot.html#Snapshot) will be the replacement for this. * Deprecated [GraphUpdateObject.RevertFromBackup](https://arongranberg.com/astar/docs/graphupdateobject/revertfrombackup.html#RevertFromBackup) . [AstarPath.Snapshot](https://arongranberg.com/astar/docs/astarpath/snapshot.html#Snapshot) will be the replacement for this. * Deprecated GridGraph.CalculateConnections(int,int). Use [GridGraph.RecalculateConnectionsInRegion](https://arongranberg.com/astar/docs/gridgraph/recalculateconnectionsinregion.html#RecalculateConnectionsInRegion) instead to batch multiple calls. This method still works, but the overhead of calling it will be significantly higher than in earlier versions. This new overhead comes from properly handling the new [GridGraph.maxStepUsesSlope](https://arongranberg.com/astar/docs/gridgraph.html#maxStepUsesSlope) option, and job scheduling overhead. If you are recalculating connections for a large number of nodes, you should use [GridGraph.RecalculateConnectionsInRegion](https://arongranberg.com/astar/docs/gridgraph/recalculateconnectionsinregion.html#RecalculateConnectionsInRegion) instead. The RecalculateConnectionsInRegion method scales better to larger node counts than CalculateConnections ever did. * Deprecated [XPath](https://arongranberg.com/astar/docs/xpath.html) . Use [ABPath](https://arongranberg.com/astar/docs/abpath.html) with an ending condition instead. * Removed Jump Point Search support for grid graphs. It was quite limited, and very few people seemed to use it. But it contributed a significant amount of code. * Removed GraphCollision.rayDirection. This option has never been exposed in the inspector and it's not that useful. * Deprecated [NavmeshBase.nearestSearchOnlyXZ](https://arongranberg.com/astar/docs/navmeshbase.html#nearestSearchOnlyXZ) . Use [NNConstraint.distanceMetric](https://arongranberg.com/astar/docs/nnconstraint.html#distanceMetric) instead. * Deprecated [NNConstraint.distanceXZ](https://arongranberg.com/astar/docs/nnconstraint.html#distanceXZ) . Use [NNConstraint.distanceMetric](https://arongranberg.com/astar/docs/nnconstraint.html#distanceMetric) instead. * Deprecated [NavGraph.GetNearestForce](https://arongranberg.com/astar/docs/navgraph/getnearestforce.html#GetNearestForce) . Use [NavGraph.GetNearest](https://arongranberg.com/astar/docs/navgraph/getnearest.html) instead, as it does the same thing now. * Deprecated the AIPath/RichAI.repathRate field. It has been replaced by the [AIBase.autoRepath.period](https://arongranberg.com/astar/docs/autorepathpolicy2.html#period) field. * Removed a lot of deprecated code. All of these have been deprecated for at least a few years. * Removed previously deprecated members of the NavGraph class: matrix, inverseMatrix, SetMatrix, RelocateNodes(Matrix4x4,Matrix4x4). * Removed previously deprecated method NavGraph.ScanGraph, use [NavGraph.Scan](https://arongranberg.com/astar/docs/navgraph/scan.html#Scan) instead. * Removed previously deprecated property RecastGraph.forcedBounds. * Removed previously deprecated method RecastGraph.ClosestPointOnNode (use node.ClosestPointOnNode instead). * Removed previously deprecated method RecastGraph.ContainsPoint (use node.ContainsPoint instead). * Removed previously deprecated method GridGraph.CheckConnection (use node.HasConnectionInDirection instead). * Removed previously deprecated method GridGraph.GetNodesInArea (use [GridGraph.GetNodesInRegion](https://arongranberg.com/astar/docs/gridgraph/getnodesinregion.html) instead). * Removed previously deprecated method overload GridGraph.CalculateConnections(int,int,GridNode). * Removed previously deprecated method GridGraph.UpdateNodePositionCollision. * Removed previously deprecated method GridGraph.UpdateSizeFromWidthDepth (use [GridGraph.SetDimensions](https://arongranberg.com/astar/docs/gridgraph/setdimensions.html#SetDimensions) instead). * Removed previously deprecated method GridGraph.GenerateMatrix (use [GridGraph.UpdateTransform](https://arongranberg.com/astar/docs/gridgraph/updatetransform.html#UpdateTransform) instead). * Removed previously deprecated method GridGraph.GetNodeConnection (use [GridNodeBase.GetNeighbourAlongDirection](https://arongranberg.com/astar/docs/gridnodebase/getneighbouralongdirection.html#GetNeighbourAlongDirection) instead). * Removed previously deprecated method GridGraph.HasNodeConnection (use [GridNodeBase.HasConnectionInDirection](https://arongranberg.com/astar/docs/gridnodebase/hasconnectionindirection.html#HasConnectionInDirection) instead). * Removed previously deprecated method GridGraph.SetNodeConnection (use [GridNode.SetConnectionInternal](https://arongranberg.com/astar/docs/gridnode/setconnectioninternal.html#SetConnectionInternal) instead). * Removed previously deprecated class LegacyAIPath, as it's been deprecated for about 6 years now. * Removed previously deprecated class LegacyRichAI, as it's been deprecated for about 6 years now. * Removed previously deprecated class LegacyRVOController, as it's been deprecated for about 6 years now. * Removed previously deprecated method Seeker.GetNewPath (use [ABPath.Construct](https://arongranberg.com/astar/docs/abpath/construct.html#Construct) instead). * Removed previously deprecated overload of Seeker.StartMultiTargetPath (use [Seeker.StartPath](https://arongranberg.com/astar/docs/seeker/startpath.html) instead). * Removed previously deprecated field AstarPath.astarData (use [AstarPath.data](https://arongranberg.com/astar/docs/astarpath.html#data) instead). * Removed previously deprecated field AstarPath.limitGraphUpdates (use [AstarPath.batchGraphUpdates](https://arongranberg.com/astar/docs/astarpath.html#batchGraphUpdates) instead). * Removed previously deprecated field AstarPath.maxGraphUpdateFreq (use [AstarPath.graphUpdateBatchingInterval](https://arongranberg.com/astar/docs/astarpath.html#graphUpdateBatchingInterval) instead). * Removed previously deprecated property AstarPath.IsAnyGraphUpdatesQueued (use [AstarPath.IsAnyGraphUpdateQueued](https://arongranberg.com/astar/docs/astarpath.html#IsAnyGraphUpdateQueued) instead). * Removed previously deprecated callback AstarPath.OnGraphsWillBeUpdated. * Removed previously deprecated callback AstarPath.OnGraphsWillBeUpdated2. * Removed previously deprecated method AstarPath.QueueWorkItemFloodFill. * Removed previously deprecated method AstarPath.EnsureValidFloodFill. * Removed previously deprecated method AstarPath.FloodFill. * Removed previously deprecated method AstarPath.FlushWorkItems(bool,bool) (use [AstarPath.FlushWorkItems()](https://arongranberg.com/astar/docs/astarpath/flushworkitems.html#FlushWorkItems) instead). * Removed previously deprecated method AstarPath.FlushThreadSafeCallbacks (use [AstarPath.FlushWorkItems()](https://arongranberg.com/astar/docs/astarpath/flushworkitems.html#FlushWorkItems) instead). * Removed previously deprecated method AstarPath.BlockUntilPathQueueBlocked (use [AstarPath.PausePathfinding](https://arongranberg.com/astar/docs/astarpath/pausepathfinding.html#PausePathfinding) instead). * Removed previously deprecated method AstarPath.WaitForPath (use [AstarPath.BlockUntilCalculated](https://arongranberg.com/astar/docs/astarpath/blockuntilcalculated.html#BlockUntilCalculated) instead). * Removed previously deprecated method AstarPath.RegisterSafeUpdate (use [AstarPath.AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html) instead). * Removed previously deprecated method GraphNode.RecalculateConnectionCosts. * Removed previously deprecated component TileHandlerHelper, as this is built-in to navmesh/recast graphs now. * [PointGraph.optimizeForSparseGraph](https://arongranberg.com/astar/docs/pointgraph.html#optimizeForSparseGraph) is now included in the free version too. This option makes scanning a large point graph much faster. * Changed some private fields in [AIPath](https://arongranberg.com/astar/docs/aipath.html) to be protected instead, to make it easier to subclass it. * Changed the signature of GraphNode.GetPortal to use out-parameters instead of output lists. The old signature will continue to work, but it is marked as deprecated. * Moved ProceduralGraphMover and DynamicObstacle out from the ExampleScenes folder to the Utilities folder. * Change: [LevelGridNode.HasAnyGridConnections](https://arongranberg.com/astar/docs/levelgridnode.html#HasAnyGridConnections) is now a property instead of a method. * Renamed GridGraph.maxClimb to the more descriptive name [Pathfinding.GridGraph.maxStepHeight](https://arongranberg.com/astar/docs/gridgraph.html#maxStepHeight) . * **Fixes** * Fixed the AIPath.velocity and RichAI.velocity properties being very jittery (and often completely incorrect) when a rigidbody was attached to the character. * Fixed linecasts on grid graphs would not add the start node to the **trace** parameter if the end node was the same as the start node. * Fixed enabling [AIPath.constrainInsideGraph](https://arongranberg.com/astar/docs/aipath.html#constrainInsideGraph) could cause the agent to be teleported to the world origin if it was too far away from any walkable nodes. * Fixed the AILerp component would recalculate the path every frame if the agent's position, the destination, and the destination of the last calculated path were all identical. * Fixed the [NavMeshGraph](https://arongranberg.com/astar/docs/navmeshgraph.html) would not work for some pretty bad meshes. * Fixed some deprecation warnings in newer versions of Unity. * Added [OffMeshLinks.GetNearest](https://arongranberg.com/astar/docs/offmeshlinks/getnearest.html#GetNearest) . * The navmesh graph will now warn if the input mesh contains duplicate triangle edges, instead of crashing. * Fixed [AstarPath.FlushGraphUpdates](https://arongranberg.com/astar/docs/astarpath/flushgraphupdates.html#FlushGraphUpdates) and [FlushWorkItems](https://arongranberg.com/astar/docs/astarpath/flushworkitems.html#FlushWorkItems) would not flush items if some were in progress, but none were queued. * Improved error handling for [RecastNavmeshModifier](https://arongranberg.com/astar/docs/recastnavmeshmodifier.html) when it is moved during runtime. * Fixed paths contained some internal fields which made it impossible to write custom path types. * Fixed some linecast edge cases on grid graphs in which the [GraphHitInfo](https://arongranberg.com/astar/docs/graphhitinfo.html) 's fields were not set correctly. * Fixed the recast graph's 'Snap bounds to scene' button could misalign the graph if the graph was rotated. * Fixed rotated [RecastGraph](https://arongranberg.com/astar/docs/recastgraph.html) s could in some cases end up with gaps between tiles because some meshes that should have been included in the tile were missed. * The [RVOController](https://arongranberg.com/astar/docs/rvocontroller.html) will now disable itself if the global [RVOSimulator](https://arongranberg.com/astar/docs/rvosimulator.html) is disabled. * Fixed GridGraph and LayerGridGraph not always using [GridGraph.newGridNodeDelegate](https://arongranberg.com/astar/docs/gridgraph.html#newGridNodeDelegate) when creating nodes. * Fixed editing [NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) components in a scene without an [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component would throw an exception. * Fixed "Some meshes were statically batched..." error message being logged multiple times when scanning a recast graph. Now it is limited to at most once per scan. * Fixed RVOExampleAgent could throw an exception if it tried to follow a path with length 1. * Fixed exception that could be thrown when using local avoidance and the navmesh had degenerate edges (could happen when using the [NavmeshAdd](https://arongranberg.com/astar/docs/navmeshadd.html) component). * Fixed graph updates on grid graphs sometimes updated a slightly larger number of nodes than strictly necessary. * Fixed the [FunnelModifier](https://arongranberg.com/astar/docs/funnelmodifier.html) could simplify the path incorrectly on rotated recast graphs. * Fixed setting [RichAI.rotation](https://arongranberg.com/astar/docs/richai.html#rotation) while the agent was stationary would rotate the agent, but it would immediately rotate back to the previous heading. * Fixed an exception could be thrown when using the [NavmeshClamp](https://arongranberg.com/astar/docs/navmeshclamp.html) script with multiple graphs. * Fixed the [RecastNavmeshModifier](https://arongranberg.com/astar/docs/recastnavmeshmodifier.html) component would sometimes still affect objects even if it was disabled. * Fixed [ProceduralGraphMover](https://arongranberg.com/astar/docs/proceduralgraphmover.html) not working with layered grid graphs. * Fixed the graphs would be rendered even when the scene view was in prefab isolation mode and you were viewing an unrelated prefab. * Improved error messages when trying to include a non-readable mesh in a recast graph scan. * Cleaned up some large audio files in the example scenes to reduce the package install size quite significantly. * Removed some \`.blend1\` (blender backup files) that had been accidentally included in the package. * Fixed some visual scaling bugs in the collision visualization code for the grid graph. * Worked around a null reference exception in Unity's ClearPreviewCache that could appear randomly from time to time. * Fixed RichAI always teleporting to the closest point on the navmesh when the script is enabled even if [AIBase.canMove](https://arongranberg.com/astar/docs/aibase.html#canMove) is false. * Fixed a crash when running on iOS. * Fixed AIPath/RichAI throwing exceptions when an RVOController on the same object was disabled. * Fixed paths could sometimes be cancelled without a reason if 'draw gizmos' was disabled on the Seeker component. * Fixed implementations of Object.Equals for Int3, Int2, IntRect, Connection and SimpleMovementPlane would throw an exception if compared to an object of a different type. * Fixed an exception could be thrown when resizing a grid graph to make it smaller. * Fixed RVOController.layer showing up as a layer mask instead of a single layer field. * Fixed a null reference exception which could happen in rare cases when using one-way links on point graphs. * Fixed graph updates not always picking up physics changes done during the same frame as the update if "Auto Sync Transforms" has been disabled in the Unity physics settings. * Fixed changing the scene and scanning a graph in the same frame may cause the graph to not pick up the latest scene changes if [Physics.autoSyncTransforms](https://docs.unity3d.com/ScriptReference/Physics-autoSyncTransforms.html) is disabled. * Fixed null reference exception when a navmesh/recast graph is marked as not being affected by navmesh cuts. * Fixed collider faces with the exact same y coordinate as the base of a grid graph would sometimes not get detected. * Fixed [AstarPath.OnGraphsUpdated](https://arongranberg.com/astar/docs/astarpath.html#OnGraphsUpdated) not being called after NavmeshCut updates. * Fixed GraphModifier.OnGraphsPreUpdate could be called multiple times per update when using navmesh cutting. * Fixed GraphModifier.OnGraphsPreUpdate could be called in the middle of a graph scan. Now graph scans will only send PreScan, PostScan and LatePostScan events. * Fixed weird undo/redo behaviour when editing graph settings. Previously some undo events would not be saved and sometimes you would have to press ctrl+z twice in order to undo a change. * 4.2.19 (2023-11-14) * The documentation now has a dropdown to allow you to choose between different versions of the package, and a notification if you are viewing a previous version. ![](https://arongranberg.com/astar/docs/images/changelog/documentation_version_dropdown.png) * Added a new tutorial: [Agent-Specific Pathfinding](https://arongranberg.com/astar/docs/traversal_provider.html) . * You can now set a custom traversal provider on the Seeker component, and it will be applied to all path requests. See [Seeker.traversalProvider](https://arongranberg.com/astar/docs/seeker.html#traversalProvider) . * Changed [Seeker.IsDone](https://arongranberg.com/astar/docs/seeker/isdone.html#IsDone) to return true from within the OnPathComplete callback. Previously it would always return false, which was confusing since the callback explicitly indicates that the path has been calculated. * Made the grid graph's collision visualization in the inspector green instead of blue. This is done to make the connection to colliders more clear. The color is also easier to see against the grey background. * The [RaycastModifier](https://arongranberg.com/astar/docs/raycastmodifier.html) now defaults to graph raycasting in the pro version of the package. * The transform tool for the GameObject with the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component is now hidden to reduce clutter, as each graph has its own transform tool instead. * [AutoRepathPolicy](https://arongranberg.com/astar/docs/autorepathpolicy.html) will now automatically randomly spread out path recalculations a bit to avoid many agents recalculating their paths at the same time. * Added [GraphMask.FromGraphIndex](https://arongranberg.com/astar/docs/graphmask/fromgraphindex.html#FromGraphIndex) . * Added an option for a custom edge filter in [GraphUtilities.GetContours](https://arongranberg.com/astar/docs/graphutilities/getcontours.html) . * Added [GridGraph.GetNeighbourDirections](https://arongranberg.com/astar/docs/gridgraph/getneighbourdirections.html#GetNeighbourDirections) . * Added [NavGraph.isScanned](https://arongranberg.com/astar/docs/navgraph.html#isScanned) . * Added [NavGraph.IsInsideBounds](https://arongranberg.com/astar/docs/navgraph/isinsidebounds.html#IsInsideBounds) . * Added [GraphNode.ContainsPoint](https://arongranberg.com/astar/docs/graphnode/containspoint.html) and [GraphNode.ContainsPointInGraphSpace](https://arongranberg.com/astar/docs/graphnode/containspointingraphspace.html#ContainsPointInGraphSpace) . * Added [GridGraph.AlignToTilemap](https://arongranberg.com/astar/docs/gridgraph/aligntotilemap.html#AlignToTilemap) . * Added [IAstarAI.endOfPath](https://arongranberg.com/astar/docs/iastarai.html#endOfPath) . * Added [GridNodeBase.HasConnectionsToAllAxisAlignedNeighbours](https://arongranberg.com/astar/docs/gridnodebase.html#HasConnectionsToAllAxisAlignedNeighbours) . * Added [GraphUpdateScene.GetGraphUpdate](https://arongranberg.com/astar/docs/graphupdatescene/getgraphupdate.html#GetGraphUpdate) . * Added [ABPath.cost](https://arongranberg.com/astar/docs/abpath.html#cost) for accessing the total cost of a calculated path. * Added a way to align a grid graph to a tilemap. Previously this has been quite tricky, especially for isometric and hexagonal tilemap layouts. ![](https://arongranberg.com/astar/docs/images/gridgraph/align_to_tilemap.png) * Added ASTAR\_LARGER\_GRIDS which can be set under the Optimizations tab to enable grid graphs larger than 1024x1024. * Changed how [GridGraph.aspectRatio](https://arongranberg.com/astar/docs/gridgraph.html#aspectRatio) works for isometric and hexagonal grid graphs. Now it works more intuitively to just make the nodes N times wider. Before it only behaved properly for rectangular grid graphs. * Deprecated NNConstraint.Default. Use the equivalent [NNConstraint.Walkable](https://arongranberg.com/astar/docs/nnconstraint.html#Walkable) property instead, as this name is more descriptive. * Deprecated [AIPath.OnTargetReached](https://arongranberg.com/astar/docs/aipath/ontargetreached.html#OnTargetReached) , [RichAI.OnTargetReached](https://arongranberg.com/astar/docs/richai/ontargetreached.html#OnTargetReached) , [AILerp.OnTargetReached](https://arongranberg.com/astar/docs/ailerp/ontargetreached.html#OnTargetReached) . You can use [IAstarAI.reachedDestination](https://arongranberg.com/astar/docs/iastarai.html#reachedDestination) or [IAstarAI.reachedEndOfPath](https://arongranberg.com/astar/docs/iastarai.html#reachedEndOfPath) instead. The OnTargetReached method will continue to work as before, but using it is discouraged. * Deprecated the AdvancedSmooth modifier. It never worked particularly well, and given that no one has asked a single support question about it the last 5 years or so, I don't think a lot of people use it. * Fixed [ai.SetPath](https://arongranberg.com/astar/docs/iastarai/setpath.html#SetPath) did not accept paths if you called it from the OnPathComplete callback for the path. * Fixed the first tag color in the inspector would sometimes be initialized to completely transparent. * Fixed [NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) s with custom meshes could calculate an incorrect bounding box, which could lead to it not updating some tiles, even if it was touching them. * Fixed [GraphUpdateScene.GetBounds](https://arongranberg.com/astar/docs/graphupdatescene/getbounds.html#GetBounds) sometimes incorrectly returning an empty bounding box if the **convex** option was enabled. * Fixed some cases where a recast graph would miss some connections between nodes in different tiles. Especially if the shared edge was long. * Fixed Navmesh Cutting Update Interval would not be serialized, and therefore always reset to 0 when the game started. * Fixed the grid graph's collision preview showing the side view when using 2D physics even though that's irrelevant for 2D. * Fixed an exception could in rare circumstances be thrown when using [ABPath.calculatePartial](https://arongranberg.com/astar/docs/abpath.html#calculatePartial) . * Fixed editor-only data would sometimes not be loaded from graphs, leading to some settings in the graph inspectors to be lost (e.g. if the grid graph's collision preview was open or closed). * Fixed [GraphNode.ContainsOutgoingConnection](https://arongranberg.com/astar/docs/graphnode/containsoutgoingconnection.html#ContainsOutgoingConnection) could throw an exception if the node had no connections at all. * Fixed calling [GraphUtilities.GetContours](https://arongranberg.com/astar/docs/graphutilities/getcontours.html) with a grid graph that had one-way connections could cause an infinite loop. Now an exception will be thrown if any one-way connections are found. This is reasonable because the contours of a grid graph are not really well-defined if any one-way connections exist. * Removed previously deprecated methods on the Path class: GetState, Log, LogError and ReleaseSilent. They have all been deprecated for over 5 years. * Removed previously deprecated methods on the AstarData class: GetGraphType(string), CreateGraph(string), AddGraph(string, and GetRaycastableGraphs. They have all been deprecated for over 5 years. * 4.2.18 (2022-11-08) * Added a documentation page on the architecture of the package: [Architecture overview](https://arongranberg.com/astar/docs/architecture.html) . * Added a tutorial on migrating from Unity's pathfinding to this package: [Migrating from Unity Navigation](https://arongranberg.com/astar/docs/migratingfromunity.html) . * Added a tutorial on how to deal with pathfinding in large worlds: [Large worlds](https://arongranberg.com/astar/docs/largeworlds.html) . * Nearest node queries on layered grid graphs are now significantly faster. * Improved performance of linecasts on grid graphs by approximately a factor of 2. * Improved accuracy of linecasts on grid graphs. In particular, many edge cases were previously undefined and were not consistently handled. Now linecasts which only touch corners of obstacles are always allowed, and also linecasts which go right on the border between walkable and unwalkable nodes. * Add [GridNodeBase.NormalizePoint](https://arongranberg.com/astar/docs/gridnodebase/normalizepoint.html#NormalizePoint) and [GridNodeBase.UnNormalizePoint](https://arongranberg.com/astar/docs/gridnodebase/unnormalizepoint.html#UnNormalizePoint) . * Various documentation improvements across the whole package. * The game view will now automatically repaint after a graph is scanned in the editor. Previously only the scene view was repainted. * Grid graphs and layered grid graphs now have support for [NNConstraint.distanceXZ](https://arongranberg.com/astar/docs/nnconstraint.html#distanceXZ) . This makes [AIPath.constrainInsideGraph](https://arongranberg.com/astar/docs/aipath.html#constrainInsideGraph) work a lot better for grid graphs which have slopes. * Changed the color of gizmos drawn for the [NavmeshAdd](https://arongranberg.com/astar/docs/navmeshadd.html) component from green to purple to avoid confusion with the [Seeker](https://arongranberg.com/astar/docs/seeker.html) s gizmos. * If you have a persistent (DontDestroyOnLoad) [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component while loading a new scene with an existing [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component, the newly loaded [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component will disable itself instead of logging an error and leaving both components in inconsistent states. This will make it easier to keep a single [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component around for the whole duration of the game. * A garbage collection will no longer be forced immediately after scanning graphs. Unity has decent support for incremental GC now, and it's best to rely on that instead. This may improve performance when scanning graphs. * Renamed AutoRepathPolicy.interval/maximumInterval to [AutoRepathPolicy.period](https://arongranberg.com/astar/docs/autorepathpolicy.html#period) /maximumPeriod since that's a more descriptive name. * Changed [AutoRepathPolicy](https://arongranberg.com/astar/docs/autorepathpolicy.html) to make it usable for custom movement scripts without having to implement the [IAstarAI](https://arongranberg.com/astar/docs/iastarai.html) interface. * Increased artificial limit for the maximum length of paths from 2048 to 16384. * [GridNodeBase.RemoveConnection](https://arongranberg.com/astar/docs/graphnode/removeconnection.html#RemoveConnection) now also works for grid connection, not just custom connections. * [GridNodeBase.AddConnection](https://arongranberg.com/astar/docs/graphnode/addconnection.html#AddConnection) will now remove an existing grid connection (if it exists) to the same node, before adding the new custom connection. Before, you could get two connections between the nodes instead of one, like you'd expect. * Using [IAstarAI.SetPath](https://arongranberg.com/astar/docs/iastarai/setpath.html#SetPath) will now set the destination of the movement script to the end point of the path by default. If you pass a [RandomPath](https://arongranberg.com/astar/docs/randompath.html) , [FleePath](https://arongranberg.com/astar/docs/fleepath.html) or [MultiTargetPath](https://arongranberg.com/astar/docs/multitargetpath.html) , the destination will be set once the path has been calculated since that's when it is first known. This makes properties like [IAstarAI.reachedDestination](https://arongranberg.com/astar/docs/iastarai.html#reachedDestination) and [IAstarAI.remainingDistance](https://arongranberg.com/astar/docs/iastarai.html#remainingDistance) work out of the box for those path types. * Created a property drawer for the [GraphMask](https://arongranberg.com/astar/docs/graphmask.html) struct. So now you can include GraphMask fields in your own scripts and they will show up nicely in the inspector. * Improved error checking in [FloodPath](https://arongranberg.com/astar/docs/floodpath.html) for if the start node was destroyed before the path calculation started. * Fixed saving or loading graphs could deadlock on WebGL since the zip library tired to use threads, which doesn't work on WebGL. * Fixed linecasts on grid graphs would not always return a hit if the start point or end point was outside the graph. * Fixed ExitGUIException could show up in the console sometimes when editing component properties. * Fixed floating point errors causing the [FunnelModifier](https://arongranberg.com/astar/docs/funnelmodifier.html) to simplify the path incorrectly in rare cases. * Fixed not being able to check for updates in Unity 2022.1+ because https must now be used for all web requests. * Fixed inheriting from scripts in this package (e.g. AIPath) and adding new fields, would not make those fields show up in the inspector unless you had a custom editor script too. Now all fields the editor scripts cannot handle will show up automatically. * Deprecated [AstarPath.prioritizeGraphs](https://arongranberg.com/astar/docs/astarpath.html#prioritizeGraphs) . * Deprecated some older linecast overloads for grid graphs. * Deprecated LevelGridNode.GetConnection in favor of [LevelGridNode.HasConnectionInDirection](https://arongranberg.com/astar/docs/levelgridnode/hasconnectionindirection.html#HasConnectionInDirection) . * 4.2.17 (2021-11-06) * Fixed RVO example scenes not working properly (regression introduced in 4.2.16). * 4.2.16 (2021-10-24) * Breaking changes * Changed when the AIPath movement script stops when [AIPath.whenCloseToDestination](https://arongranberg.com/astar/docs/aibase.html#whenCloseToDestination) is set to Stop. See below for more details. The new behavior is usually what you want. If you really want the old behavior then set`ai.whenCloseToDestination = CloseToDestinationMode.ContinueToExactDestination `and in a separate script run`ai.isStopped = ai.reachedEndOfPath `every frame. * The AIPath script will now clear the path it is following if a path calculation fails. See below for more details. * Changed the order of execution for the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) script to -10000. Previously the order of execution was left at the Unity default value which is very unpredictable. This may cause issues for you if you relied on Awake to be executed before the graphs were loaded and scanned. If you need full control over when the graphs are scanned it is recommended that you disable [scanOnStartup](https://arongranberg.com/astar/docs/astarpath.html#scanOnStartup) and instead call [AstarPath.Scan](https://arongranberg.com/astar/docs/astarpath/scan.html) manually when you want to scan the graphs. * Improvements * Added some helper visualizations for the collision settings for the grid graph. ![](https://arongranberg.com/astar/docs/images/changelog/grid_graph_collision_visualization.png) * Improved the way pages are grouped in the documentation to hopefully make it more intuitive. * Added [GridGraph.SetGridShape](https://arongranberg.com/astar/docs/gridgraph/setgridshape.html#SetGridShape) . * Added a new dynamic path recalculation mode to the movement scripts. This mode is smarter about when it recalculates paths. It will recalculate the path often when the destination changes a lot and much less frequently if the destination doesn't change much or if it is very far away. This can help improve both the responsiveness of your agents and the performance if you have many agents that do frequent path recalculations. Any existing agents will still use the old method of recalculating the path every N seconds, but you can change this in the inspector. New agents will by default use the new Dynamic mode. * Improved performance of the AIPath and RichAI inspectors a bit. * Improved the accuracy and performance of the RaycastModifier when thick raycasting is enabled. * The [ProceduralGridMover](https://arongranberg.com/astar/docs/proceduralgridmover.html) script now has an option for specifying which graph to update. * Added a filter parameter to graph linecast methods. This can be used to mark additional nodes as not being traversable by the linecast. See GridGraph.Linecast. * The [RaycastModifier](https://arongranberg.com/astar/docs/raycastmodifier.html) now respects which tags are traversable and any ITraversalProvider set on the path. * Added a setter for the rotation property of all movement scripts ( [IAstarAI.rotation](https://arongranberg.com/astar/docs/iastarai.html#rotation) ). * Exposed [AILerp.velocity](https://arongranberg.com/astar/docs/ailerp.html#velocity) . * Added a get/set property [GridGraph.is2D](https://arongranberg.com/astar/docs/gridgraph.html#is2D) which is equivalent to the inspector's "2D" toggle. * Added [GraphUpdateObject.stage](https://arongranberg.com/astar/docs/graphupdateobject.html#stage) which contains info about if a graph update has been applied or not. * Improved the DynamicObstacle to handle cases when graph updates take a very long time in a better way. * Improved the [NavmeshAdd](https://arongranberg.com/astar/docs/navmeshadd.html) component inspector. * Added a [NavmeshClipper.graphMask](https://arongranberg.com/astar/docs/navmeshclipper.html#graphMask) field to the [NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) and [NavmeshAdd](https://arongranberg.com/astar/docs/navmeshadd.html) components. * Changes * The AIPath/RichAI.canSearch field has been replaced by the [AIBase.autoRepath.mode](https://arongranberg.com/astar/docs/autorepathpolicy2.html#mode) field. For backwards compatibility setting canSearch to false will set the mode to Never and setting it to true will set the mode to EveryNSeconds. * The AIPath/RichAI.repathRate field has been replaced by the [AIBase.autoRepath.period](https://arongranberg.com/astar/docs/autorepathpolicy2.html#period) field. For backwards compatibility you can both read and write to the old name and it will work as before. Note that this field is not used for the new Dynamic path recalculation mode. * The AIPath script will now clear the path it is following if a path calculation fails. Previously it would continue following its previous path. This could lead to problems if the world had changed so that there was no longer a valid path to the target. The agent could then in some situations just continue trying to walk through obstacles instead of stopping. In pretty much all cases this change in behavior is what you want and will not cause any problems when upgrading. * Changed when the AIPath movement script stops when [AIPath.whenCloseToDestination](https://arongranberg.com/astar/docs/aibase.html#whenCloseToDestination) is set to Stop. Consider the case when the destination was slightly outside the navmesh and the path instead goes to the closest point it can reach. Previously it would stop up to [AIPath.endReachedDistance](https://arongranberg.com/astar/docs/aibase.html#endReachedDistance) units from the end of the path. This could lead to unexpected behavior since it may be the case that by just moving a bit closer to the end of the path it would end up within [AIPath.endReachedDistance](https://arongranberg.com/astar/docs/aibase.html#endReachedDistance) units from the destination. Essentially [AIPath.reachedDestination](https://arongranberg.com/astar/docs/aipath.html#reachedDestination) would remain false even though the agent could actually reach the destination by just moving a bit further. So this behavior has been changed so that it now only stops when it is within [AIPath.endReachedDistance](https://arongranberg.com/astar/docs/aibase.html#endReachedDistance) units from the destination, not the end of the path. * Made GridGraph.GetRectFromBounds public. * Right clicking fields in the inspector no longer shows the "Show in online documentation" context menu, instead the normal unity context menu is shown. The previous menu prevented things like resetting individual fields to their prefab values and similar things. * Changed some 'internal' access modifiers to 'public' or 'protected' on the Path class. This makes it easier to create custom path types. * Fixes * Fixed a bug which could very rarely cause some node connections between tiles in a recast graph to be missed, causing various subtle movement issues. * Fixed [AIPath.reachedEndOfPath](https://arongranberg.com/astar/docs/aipath.html#reachedEndOfPath) not always being reset to false when the component was disabled and then enabled again. * [GraphNode.ClosestPointOnNode](https://arongranberg.com/astar/docs/graphnode/closestpointonnode.html#ClosestPointOnNode) is now available for all node types instead of only being implemented for [GridNode](https://arongranberg.com/astar/docs/gridnode.html) and [MeshNode](https://arongranberg.com/astar/docs/meshnode.html) . * Fixed a case where the Seeker -> Start End Modifier -> Snapping to NodeConnection mode would not respect tags or [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) s. This could result in the path partially entering a node which should not be traversable by it. * Fixed a case where using the [ABPath.calculatePartial](https://arongranberg.com/astar/docs/abpath.html#calculatePartial) option together with Seeker->Start End Modifier->Snapping=ClosestOnNode would make the path seemingly ignore which tags were traversable in some cases. * Fixed clicking Apply in the Optimizations tab could log error messages about some build platforms not existing. * Fixed exception when using [MecanimBridge](https://arongranberg.com/astar/docs/mecanimbridge.html) with [RichAI](https://arongranberg.com/astar/docs/richai.html) . * Fixed [AIPath.reachedDestination](https://arongranberg.com/astar/docs/aipath.html#reachedDestination) would throw an exception if you tried to access it when the agent had no path. * Fixed calling \`AstarData.ClearGraphs\` and then immediately calling \`AstarData.AddGraph\` would result in an exception. * Fixed [UpdateGraphsNoBlock(GraphUpdateObject,GraphNode,GraphNode,bool)](https://arongranberg.com/astar/docs/graphupdateutilities/updategraphsnoblock.html#UpdateGraphsNoBlock2) could return incorrect results if there were already some pending graph updates. * Fixed grid graph would see 2D triggers as obstacles. Now all 2D colliders marked as triggers will be ignored by the grid graph. * Fixed a memory leak that could happen after switching scenes. Thanks nGenius for finding it. * Fixed RichAI always teleporting to the closest point on the navmesh when the script is enabled even if [RichAI.canMove](https://arongranberg.com/astar/docs/aibase.html#canMove) is false. * Fixed GraphUpdateScene not using the outline from an attached PolygonCollider2D properly. * Fixed some cases where graph updates with 2D colliders would not use the most up to date physics engine data. All graph updates are now preceeded by a call to Physics2D.SyncTransforms (in addition to Physics.SyncTransform which was already being called). * The RaycastModifier now respects graphMasks set on paths. Thanks brettkercher for reporting the bug. * Fixed linecasts on navmesh/recast graphs could fail when the start of the line was close to a steep slope. * Fixed linecasts on navmesh/recast graphs would incorrectly return no obstructions if for example used between two floors of a building that were not connected. * Fixed RichAI trying to traverse an off mesh link twice if the path's endpoint was also the endpoint of an off-mesh link. * Fixed a missing script in the turnbased example scene causing warnings when opening that scene. * Fixed warnings would be logged when first importing the package on recent version of Unity due to a change in how Unity imports fbx files. * Make DynamicObstacle call Physics.SyncTransforms to ensure it has the most up to date data for the collider. * Removed 'Upgrading serialized data ...' message as it was mostly just annoying. * Fixed GameObject references (like the PointGraph's Root field) would not get serialized properly if the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component was stored in a prefab. * Fixed some smaller memory memory leaks in the unity editor. * Fixed a bug which could cause a SynchronizationLockException to be thrown in some cases when the game was quit in a non-graceful way (e.g. when Unity exits play mode after recompiling scripts). * 4.2.15 (2020-03-30) * Added [ai.GetRemainingPath](https://arongranberg.com/astar/docs/iastarai/getremainingpath.html#GetRemainingPath) . * Fixed importing the package using the unity package manager would cause the A\* inspector to not be able to load since it couldn't find the editor resources folder. * Fixed the package would report the wrong version number. This could cause the "New Update Available" window to show up unnecessarily. * 4.2.14 (2020-03-23) * Fixed DynamicObstacle throwing an exception when scanning sometimes. This bug was introduced in 4.2.13. * 4.2.13 (2020-03-21) * Fixed paths could sometimes be cancelled without a reason if 'draw gizmos' was disabled on the Seeker component. Thanks Eran for reporting the bug. * Fixed DynamicObstacle logging an error about not having a collider attached even outside of play mode. * 4.2.12 (2020-02-20) * Fixed "Not allowed to access vertices on mesh" error which some users are seeing after upgrading to Unity 2019.3. * 4.2.11 (2019-11-28) * Fixed animations for the agent character were missing in the example scenes in some newer versions of Unity. This could cause exceptions to be thrown in some example scenes. * Removed some stray uses of the old and deprecated GUIText component. This could cause descriptions for some example scenes not to show up in newer versions of Unity. * 4.2.10 (2019-11-19) * Upgrade notes * This release is supported in Unity 2017.4 LTS and later. Support for earlier versions has been dropped (however it probably still works in all 2017.x releases). * The Unity WebPlayer target is no longer supported. This target was deprecated in Unity 5.4. * Known bugs * In some versions of Unity the spider bot in the example scenes may be missing its animations. This is due to a bug in how Unity upgrades scenes and is unfortunately tricky to fix for all Unity versions simultaneously. This does not affect any other part of the package. * Fixed a crash when scanning a graph on the WebGL platform and exception support is disabled. * 4.2.9 (2019-11-15) * Upgrade notes * This release is supported in Unity 2017.4 LTS and later. Support for earlier versions has been dropped (however it probably still works in all 2017.x releases). * The Unity WebPlayer target is no longer supported. This target was deprecated in Unity 5.4. * Added a visualization for which dimension of the hexagons that is being edited when using a hexagonal grid graph. ![](https://arongranberg.com/astar/docs/images/gridgraph/hexagon_dimension.png) * RichAI's Funnel Simplification now does a straight line check as the first thing it does. This can help improve both performance and the quality of the path. * Added a small helper window to the scene view when the A\* Inspector is open. I think this should work well with the dark Unity theme as well, but please start a thread in the support forum if something looks off. ![](https://arongranberg.com/astar/docs/images/changelog/scene_view_helper.png) * Using managed code stripping even up to the High level is now supported out of the box. * If an RVOController was attached to a GameObject with an AIPath/RichAI component during runtime after the movement script had been initialized then the movement script would previously possibly not find it. This is fixed now and the RVOController notifies the AIPath/RichAI script that it has been attached. * The [SetPath](https://arongranberg.com/astar/docs/iastarai/setpath.html#SetPath) method on all built-in movement scripts can now be passed a null parameter. This will clear the current path of the agent. In earlier versions this caused an exception to be thrown. * Fixed NavmeshBase.Linecast (used by RecastGraph and Navmesh linecast methods) would not fill the **trace** out parameter with the starting node in case the start point of the linecast was identical to the end point. * AIPath and RichAI now clear their paths when they are disabled. Not clearing the path has caused some issues when using object pooling and also some other unexpected behavior. If you want to just temporarily disable the movement then use the [canMove](https://arongranberg.com/astar/docs/iastarai.html#canMove) or [isStopped](https://arongranberg.com/astar/docs/iastarai.html#isStopped) properties. * Fixed RichAI.remainingDistance could refer to the previous path for one frame after a new path had been calculated. * Fixed AIPath and RichAI scripts sometimes starting with a height of 0.01 when creating a new component in the unity inspector. Now they start with a more reasonable height of 2.0. * The AIBase.usingGravity setter is now protected instead of private which helps when overriding some methods. * The "Show Surface" mode on recast and navmesh graphs is now enabled by default when creating a new graph. * The system no longer destroys itself in OnApplicationQuit and is instead always destroyed during OnDestroy. Using OnApplicationQuit could cause trouble when the quitting process was cancelled (e.g. using Application.wantsToQuit). * Fixed exceptions could be thrown in the editor if the project contains some assemblies that can for some reason not be read. Thanks joshcamas for reporting this. * Changed the automatic graph coloring limits code to ignore nodes that are unwalkable. This improves the contrast when some unwalkable nodes, that are not visible anyway, have very high penalties (or whatever other value you are visualizing in the scene view). * Fixed missing null checks in TriangleMeshNode.GetPortal and TriangleMeshNode.SharedEdge. * The RichAI inspector will now show a helpful warning if one tries to use it in a scene that does not contain a navmesh or recast graph. * [Pathfinding.GraphUtilities.GetContours](https://arongranberg.com/astar/docs/graphutilities/getcontours.html#GetContours) for grid graphs now simplifies the contour more consistently. Previously there could be one or two additional points where the algorithm started to traverse the contour. * 4.2.8 (2019-04-29) * Made it possible for nearest node queries on point graphs to find the closest connection instead of just the closest node. This will make it easier to use graphs when you have many long connections. See [Pathfinding.PointGraph.nearestNodeDistanceMode](https://arongranberg.com/astar/docs/pointgraph.html#nearestNodeDistanceMode) . * Improved the Seeker->StartEndModifier's Connection snapping mode. Now it will behave better if the path only moves along a single connection in the graph. * Fixed a crash when deploying for Nintendo Switch due to a Unity bug when setting thread names. Thanks ToastyStoemp for reporting this. * Fixed some compiler warnings in the ObjImporter class that would show up on some platforms. * Fixed GridGraph.CalculateConnectionsForCellAndNeighbours would throw an exception when called with the coordinates for a node on the border of the grid. Thanks davidpare for reporting this. * 4.2.7 (2019-04-05) * Significantly improved graph rendering performance for recast graphs when using a very large number of small tiles. * Fixed GridGraph.CountNodes throwing an exception when the graph is not scanned. Now it will return 0. * 4.2.6 (2019-03-23) * Fixed AIPath.reachedDestination and RichAI.reachedDestination only worked when the y coordinate of the agent was close to zero... which it of course was in all my tests. Sorry about this silly bug and the headache it may have caused. * Fixed loading a serialized navmesh graph when the source mesh no longer existed would cause the graph to be offset if a navmesh cut was later used to cut it. * 4.2.5 (2019-02-14) * Added a new documentation page for how to create and configure graphs during runtime. [Creating graphs during runtime](https://arongranberg.com/astar/docs/runtimegraphs.html) . * Added a new documentation page about editing point graph connections manually. [Editing graph connections manually](https://arongranberg.com/astar/docs/editinggraphs.html) . * Fixed exceptions could be thrown if the project contains some assemblies that can for some reason not be read. * Fixed the visualization for unwalkable nodes (red cubes) sometimes disappearing in newer versions of Unity (2018.2+ I think) due to a change in how Time.renderedFrameCount works. Thanks Kevin Jenkins for reporting this. * Fixed applying optimizations (under the Optimizations tab) could cause several error messages to be logged about unsupported platforms in Unity 2018.3 or newer. Thanks NoxMortem for reporting the issue. * Fixed AIPath throwing an exception if it was given a valid path that contained no nodes at all. * Made Path.GetTagPenalty public instead of internal. * Added [Pathfinding.ABPath.FakePath](https://arongranberg.com/astar/docs/abpath/fakepath.html#FakePath) . * Worked around a null reference exception bug when using IL2CPP and deploying for iPhone. This is caused by a bug in the IL2CPP compiler. * Fixed custom graph types could not be used if they were in another assembly. Thanks juskelis for reporting this and founderio for finding a fix. * 4.2.4 (2018-12-03) * Added an option for which dimension of the hexagon to adjust in the grid graph editor when using the hexagonal mode. This significantly helps with making a hexagonal graph line up with your other game elements as previously you might have had to manually calculate some complicated conversion factors in order to do this. * Fixed loading navmesh graphs from a file could be extremely slow if the graph had been saved with the source mesh field set to a mesh with an empty name and your project had a lot of things in its Resources folder. * Fixed a massive performance regression when using RVO together with IL2CPP and .net 4.6 due to changes in how the .net framework handles locking internally. * Made GraphNode.Destroy public again (it was made internal in 4.2) because without that, it is not possible to make custom graph types. * Made Path.PipelineState, Path.duration and Path.pathID public again (they were made internal in 4.2) because those properties are actually useful even for non-internal use. This also fixes some incompatibility issues with the Node Canvas integration package. Thanks jsaracev and Grofit for reporting this. * 4.2.3 (2018-11-07) * Fixed some compiler warnings in the free version on newer versions of Unity. * Fixed a bug which caused point graphs to interpret the nearest node distance limit as being 1/1000th the actual value in the free version of the package and in the pro version when not using the 'optimize for sparse graph' option. This bug caused the point graph example scene to not work in the free version of the package. * 4.2.2 (2018-10-25) * Fixed upgrading from an earlier 4.x version to 4.2 could cause compiler errors in some newer versions of Unity because the UnityPackage doesn't import the new directory structure correctly. * 4.2.1 (2018-10-23) * Fixed a bug which caused scanning navmesh graphs to throw an exception when using the free version of the package. Thanks Hunted for reporting the bug. * 4.2 (2018-10-17) * 4.1.17 through 4.1.26 were beta versions, all their changelogs have been merged into this one. * Upgrade notes * This release contains some breaking changes (primarily the pivot point change for characters that you can read about below). This will affect very few users, but I still recommend that you take a backup of your project before upgrading. * Since 4.1.23 the base of the character when using AIPath/RichAI is always at the pivot point of the Transform. This reduces code complexity and improves performance. Most users would already have had configured their characters that way, but in rare cases you may have to adjust your characters a bit (mostly just move them up or down a bit). * When changing some low level fields that can affect the connectivity of the graph such as [Pathfinding.MeshNode.connections](https://arongranberg.com/astar/docs/meshnode.html#connections) you must now call [Pathfinding.GraphNode.SetConnectivityDirty()](https://arongranberg.com/astar/docs/graphnode/setconnectivitydirty.html#SetConnectivityDirty) . The documentation for all the relevant fields mention this. Currently it only applies to the connection fields on the MeshNode, PointNode and GridNodeBase classes. All high level methods that modify the connectivity do this automatically. Most likely you do not have to change your code. * When updating the graph using a work item, it is no longer necessary to call the QueueFloodFill or FloodFill methods. Due to the hierarchical graph update mentioned below, this is all handled transparently behind the scenes. You should remove any calls to those deprecated methods as they will (for backwards compatibility reasons) force a full recalculation of the connected components which is much slower than what is likely necessary. * Improvements * Converted all comments to XML comments. This will drastically improve intellisense for most users as Doxygen style comments are not supported by that many editors. As the whole codebase has been converted using a script, there is a potential for errors in the translation. Please let me know if you find anything which looks odd or where the intellisense info could be improved. * Improved recast graph scanning speed by up to 60% in the unity editor on Mono2x. Surisingly this optimization doesn't seem to matter much for other compiler backends. This may cause minor changes to your navmesh. If this change causes bad navmeshes to be generated or if it reduces performance, please start a thread in the forum. * The RVOController and AIPath/RichAI scripts now take the scale of the object into account when using their respective height and radius fields. If you have an existing character with a non-unit scale the height and radius fields will automatically be updated to compensate for this scale. However if you are scaling characters during runtime, this may change their behaviour. * Added a new [GraphMask](https://arongranberg.com/astar/docs/graphmask.html) struct to represent a set of graphs. Previously graph masks have been represented using pure integers (e.g. in [Pathfinding.Seeker.graphMask](https://arongranberg.com/astar/docs/seeker.html#graphMask) and [Pathfinding.NNConstraint.graphMask](https://arongranberg.com/astar/docs/nnconstraint.html#graphMask) ). The new struct contains some nice helper methods like [Pathfinding.GraphMask.FromGraphName](https://arongranberg.com/astar/docs/graphmask/fromgraphname.html#FromGraphName) which has been requested by many users. * Added a new documentation page describing the inspector: [The A\* Inspector](https://arongranberg.com/astar/docs/inspector.html) . * Added a new documentation page with an overview of the different included movement scripts: [Movement scripts](https://arongranberg.com/astar/docs/movementscripts.html) . * Added a new property on all movement scripts called [reachedDestination](https://arongranberg.com/astar/docs/iastarai.html#reachedDestination) . The existing [reachedEndOfPath](https://arongranberg.com/astar/docs/iastarai.html#reachedEndOfPath) property has some quirks, which are very reasonable when considering how everything works, but are not very intuitive for new users and it can easily lead to quite brittle code. This new property will work as expected for most use cases. * Added a height and radius for the AIPath and RichAI movement scripts. This in turn deprecates the old Pathfinding.AIBase.centerOffset field as it is now implicitly height/2. If an RVOController is attached to the same GameObject, its height and radius will be driven by the movement script's values. The script will try to autodetect reasonable height and radius values from other attached components upon upgrading. * Improved look of all movement script inspectors by grouping the fields into different sections. Also added some validation to prevent invalid field values. * Added [Pathfinding.AstarData.GetNodes](https://arongranberg.com/astar/docs/astardata/getnodes.html#GetNodes) . * Optimized graph rendering a bit. In particular if multiple scene views/in game cameras are used. * The default graph rendering mode is now 'Solid Color' instead of 'Areas'. This new mode will render the graphs with a single color as the name implies. The Area coloring mode has turned out to sometimes be confusing for new users and it is not useful that often anyway. * Improved performance of small graph updates on large graphs by a very large amount. Previously when making a small update to a large graph, updating the connected components of the graph using a flood fill has been the thing which took the longest time by far. Using a new internal hierarchical graph it is now possible to update large graphs much faster. For example making a small update to a 1024\*1024 grid graph is on the order of 30 times faster and is now perfectly reasonable to do in real time (slightly depending on how the graph looks and its settings). The cost of the flood fill was previously offloaded to a separate thread, so it would not always be noticed in the Unity profiler, but it was there and [could affect the performance of the game in strange ways](http://forum.arongranberg.com/t/updategraphs-lag-spikes) . The performance of scanning a graph or updating the whole graph remains roughly the same. For more information about how this works, see [Pathfinding.HierarchicalGraph](https://arongranberg.com/astar/docs/hierarchicalgraph.html) . * Removed small allocation that was previously done for each calculated path on grid graphs. * [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) threads now show up in the Unity Profiler in the Timeline view when using a recent Unity version (2017.3 or higher). * Scanning layered grid graphs is now approximately 2.2x as fast. * Updating layered grid graphs is now approximately 1.5x as fast. * Scanning and updating layered grid graphs now allocates a lot less memory. * Added assembly definition (.asmdef) files to the package and restructured things a bit. This will help cut down on the compilation times in your project. See [https://docs.unity3d.com/Manual/ScriptCompilationAssemblyDefinitionFiles.html](https://docs.unity3d.com/Manual/ScriptCompilationAssemblyDefinitionFiles.html) for more info. * Improved performance of scanning and updating recast graphs, in particular with very large tiles. * Improved performance of get nearest queries on point graphs when not using [optimizeForSparseGraph](https://arongranberg.com/astar/docs/pointgraph.html#optimizeForSparseGraph) . * Reduced memory usage of local avoidance slightly. * All navmesh/recast graphs now support navmesh cutting out of the box and the TileHandlerHelper component is no longer necessary. If you have a TileHandlerHelper component in your scene you can safely delete it after upgrading. * AIPath/RichAI now has an option for disabling rotation completely. This was possible before as well, but the options you had to set were not entirely intuitive. The inspector has been restructured a bit to improve the ease of use. * Changes * Removed non-generic version of PathPool which has been deprecated since early 2016. * Removed various methods in the AstarMath and Polygon classes which have been deprecated since early 2016. * Removed a few other things that have been deprecated since early 2016. * Removed AstarPath.ScanLoop which has been deprecated since 2015. * Removed IntRect.Rotate and IntRect.Offset because they were not used by any part of the package. * Removed the mostly internal method GraphCollision.Raycast because it was not used by any code in the package. * Changed signature and behavior slightly of the mostly internal method [GraphCollision.CheckHeightAll](https://arongranberg.com/astar/docs/graphcollision/checkheightall.html#CheckHeightAll) . * Replaced LayerGridGraph.SampleCell with the new method LayerGridGraph.SampleHeights which does essentially the same thing, but in a more efficient way. * The rotationIn2D option for the built-in movement scripts has been renamed to [AIBase.orientation](https://arongranberg.com/astar/docs/aibase.html#orientation) and is now an enum. * Fixes * Replaced usage of the WWW class with the newer UnityWebRequest in the update checker to avoid a deprecation compiler warning in newer versions of Unity. * Fixed a bug in the A\* inspector that could cause the inspector to log errors and look weird in Unity 2018.3b5 and up. Thanks Aisit for reporting the bug. * Fixed a rare race condition that could cause exceptions in various parts of the code due to the StackPool class not being thread safe. Thanks nindim for reporting the issue. * Fixed applying optimizations (under the Optimizations tab) could cause several error messages to be logged about unsupported platforms in Unity 2018.2 or newer and in 2017.4. * Fixed trying to set a tag on a node to a value outside the valid range (0...32) could silently cause very weird behavior as other fields were affected by that. * Fixed minor allocation when calling [AstarPath.GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) without an NNConstraint. * Fixed a bug introduced in 4.1.22 which could cause a null reference exception to sometimes be thrown when visualizing graphs in the scene view. * Fixed [Pathfinding.Path.IsDone](https://arongranberg.com/astar/docs/path/isdone.html#IsDone) could due to a race condition return true a tiny amount of time before the path was actually calculated. * Fixed a bug introduced in 4.1.18 which caused various rotation settings to be hidden in the inspector for the RichAI component. * Fixed removing a movement script from the same component as an RVOController during runtime would not cause the RVOController to stop using the (now destroyed) movement script's position for local avoidance calculations. * Fixed the ObjectPlacer example script which is used in some example scenes would not always update the graph properly after destroying objects. In Unity object destruction is delayed until after the Update loop, but the script did not wait to update the graph until after the object had actually been destroyed. Thanks djzombie for reporting this. * Fixed recalculating a part of a recast graph using a graph update object would not expand the bounding box with the character radius to make sure that all tiles that could be affected by something inside the box were updated. * Worked around occational crashes when using RVO with the IL2CPP backend due to a bug in IL2CPP. * Fixed scanning a recast graph could throw an exception if there was a RecastNavmeshModifier component attached to a GameObject with a MeshFilter that had a null/missing mesh. Thanks ccm for finding the bug. * Fixed FloodPath throwing an exception when starting on a node that isn't connected to any other node. Thanks BulwarkStudios for finding the bug. * Fixed applying optimizations (under the Optimizations tab) could cause several error messages to be logged about unsupported platforms in Unity 2018.1 or newer. Thanks NFMonster for reporting the issue. * Rotation speed and acceleration are now decoupled for AIPath and RichAI. Previously the acceleration limited how quickly the agents could rotate due to how the math for [centripetal acceleration](https://en.wikipedia.org/wiki/Centripetal_force) works out. This was originally added in 4.1.11, but due to a typo the change was disabled. Now it is properly working. * Fixed GraphModifier.OnGraphsPostUpdate being called multiple times during a single update if multiple tiles were updated due to navmesh cutting. This can significantly improve performance if you are using many off-mesh links or you are using the RVONavmesh component. * Fixed an edge case bug which could cause get nearest node queries on a newly scanned point graph to return older destroyed nodes. * Fixed work items throwing exceptions could cause some internal data to get into an invalid state. * Fixed tree colliders would not be rasterized correctly when using the recast graph and the tree prefabs had been scaled. * Fixed not finding graph types and graph editors from other assemblies than the one which contains the pathfinding system (important when using asmdef files). * Fixed [AstarPath.FlushWorkItems](https://arongranberg.com/astar/docs/astarpath/flushworkitems.html#FlushWorkItems) always pausing the pathfinding threads even if no work items were queued. * Fixed loading navmesh graphs (and potentially in rare cases: recast graphs) from the cache or from a file could result in bad graph data which confused the funnel modifier which would create very zig-zaggy paths. If you have been experiencing this then just re-save your graphs/regenerate the cache after you have updated and then it should work as it should. Thanks Igor Aherne for reporting this. * 4.1.16 (2018-04-26) * Fixed PointNode.ContainsConnection could throw an exception if the node didn't have any connections. * Fixed AILerp's started out with a destination set to (0,0,0) instead of not having a destination set. So if you did not set a destination for it, it would try to move to the world origin. * 4.1.15 (2018-04-06) * Fixed RichAI.desiredVelocity always being zero. Thanks sukrit1234 for finding the bug. * Added some video examples to [AIPath.pickNextWaypointDist](https://arongranberg.com/astar/docs/aipath.html#pickNextWaypointDist) . * Fixed a bug introduced in 4.1.14 which caused scanning recast graphs in the Unity editor to fail with an error sometimes. * Fixed the position returned from querying the closest point on the graph to a point ([AstarPath.GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) ) on layered grid graphs would always be the node center, not the closest point on the node's surface. Thanks Kevin\_Jenkins for reporting this. This caused among other things the ClosestOnNode option for the Seeker's StartEndModifier to be identical to the SnapToNode option. * Fixed RVOController.velocity being zero when the game was paused (Time.timeScale = 0). * 4.1.14 (2018-03-06) * Fixed [Pathfinding.GridNode.ClosestPointOnNode](https://arongranberg.com/astar/docs/gridnodebase/closestpointonnode.html#ClosestPointOnNode) being completely broken. Thanks Ivan for reporting this. This was used internally in some cases when pathfinding on grid graphs. So this fixes a few cases of strange pathfinding results too. * It is now possible to use pathfinding from editor scripts. See [Pathfinding from editor scripts](https://arongranberg.com/astar/docs/editormode.html) . * 4.1.13 (2018-03-06) * Fixed LayerGridGraph.GetNode not performing out of bounds checks. * Exposed a public method [PointGraph.ConnectNodes](https://arongranberg.com/astar/docs/pointgraph/connectnodes.html#ConnectNodes) which can be useful if you are creating a graph from scratch using e.g PointGraph.AddNode. * Improved the [Multiple agent types](https://arongranberg.com/astar/docs/multipleagenttypes.html) tutorial. * Improved the [Writing a movement script](https://arongranberg.com/astar/docs/custom_movement_script.html) tutorial, among other things it can now also be followed if you are creating a 2D game. The movement script that you write has also been improved. * Improved how the RichAI movement script keeps track of the node it is on. It should now be more stable in some cases, especially when the ground's y-coordinate lines up badly with the y-coordinate of the navmesh. * Added an [option](https://arongranberg.com/astar/docs/aipath.html#constrainInsideGraph) to AIPath for constraining the agent to be inside the traversable surface of the graph at all times. I think it should work everywhere without any issues, but please post in the forum if anything seems to break. * Fixed the proper fonts were not imported in the documentation html, so for many browsers it fell back to some other less pretty font. * 4.1.12 (2018-02-27) * Fixed right clicking on array elements in the Unity inspector would bring up the 'Show in online documentation' context menu instead of the Unity built-in context menu (which is very useful). * Navmesh assets used in the navmesh graph no longer have to be at the root of the Resources folder, they can be in any subfolder to the Resources folder. * 4.1.11 (2018-02-22) * You can now set which graphs an agent should use directly on the Seeker component instead of having to do it through code. ![](https://arongranberg.com/astar/docs/images/multiple_agents/seeker.png) * Added tutorial for how to deal with agents of different sizes: [Multiple agent types](https://arongranberg.com/astar/docs/multipleagenttypes.html) . * Fixed scanning recast graphs could in rare cases throw an exception due to a multithreading race condition. Thanks emrys90 for reporting the bug. * Fixed a regression in 4.0.6 which caused position based penalty to stop working for layered grid graphs. Thanks DougW for reporting the bug. * Rotation speed and acceleration are now decoupled for AIPath and RichAI. Previously the acceleration limited how quickly the agents could rotate due to how the math for [centripetal acceleration](https://en.wikipedia.org/wiki/Centripetal_force) works out. * Acceleration can now be set to a custom value on the AIPath class. It defaults to a 'Default' mode which calculates an acceleration such that the agent reaches its top speed in about 0.4 seconds. This is the same behaviour that was hardcoded in earlier versions. * Fixed a bug in [GraphUtilities.GetContours](https://arongranberg.com/astar/docs/graphutilities/getcontours.html#GetContours) for grid graphs when the nodes parameter was explicitly passed as non null that could cause some contours not to be generated. Thanks andrewBeers for reporting the bug. * Improved documentation for [StartEndModifier.Exactness](https://arongranberg.com/astar/docs/startendmodifier.html#Exactness) . * 4.1.10 (2018-01-21) * 4.1.0 through 4.1.9 were beta versions, all their changelogs have been merged into this one. * Upgrade notes * Fixed the AIPath script with rotationIn2D would rotate so that the Z axis pointed in the -Z direction instead of as is common for Unity 2D objects: to point in the +Z direction. * ALL classes are now inside the [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) namespace to reduce potential naming collisions with other packages. Make sure you have "using Pathfinding;" at the top of your scripts. Previously most scripts have been inside the [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) namespace, but not all of them. The exception is the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) script to avoid breaking too much existing code (and it has a very distinctive name so name collisions are not likely). * Since the API for several movement scripts have been unified (see below), many members of the movement scripts have been deprecated. Your code should continue to work exactly as before (except bugs of course, but if some other behaviour is broken, please start a thread in the forum) but you may get deprecation warnings. In most cases the changes should be very easy to make as the visible changes mostly consist of renames. * A method called [SetPath](https://arongranberg.com/astar/docs/iastarai/setpath.html#SetPath) has been added to all movement scripts. This replaces some hacks you could achieve by calling the OnPathComplete method on the movement scripts from other scripts. If you have been doing that you should now call SetPath instead. * Paths calculated with a heuristic scale greater than 1 (the default is 1) might be slightly less optimal compared to before. See below for more information. * The StartEndModifier's raycasting options are now only used if the 'Original' snapping option is used as that's the only one it makes sense for. * The RaycastModifier has changed a bit, so your paths might look slightly different, however in all but very rare cases it should be at least as good as in previous versions. * Linecast methods will now assign the [Pathfinding.GraphHitInfo.node](https://arongranberg.com/astar/docs/graphhitinfo.html#node) field with the last node that was traversed in case no obstacle was hit, previously it was always null. * Multithreading is now enabled by default (1 thread). This may affect you if you have been adding the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component during runtime using a script, though the change is most likely positive. * The DynamicObstacle component will now properly update the graph when the object is deactivated since the object just disappeared and shouldn't block the graph anymore. Previously it only did this if the object was destroyed, not if it was deactivated. * If you have written a custom graph type you may have to change the access modifier on some methods. For example the ScanInternal method has been changed from being public to being protected. * Some internal methods on graphs have been hidden. They should never have been used by user code but in case you have done that anyway you will have to access them using the IGraphInternals or IUpdatableGraph interface now. * Removed some compatibility code for Seekers for when upgrading from version 3.6.7 and earlier (released about 2 years ago). If you are upgrading from a version that old then the 'Valid Tags' field on the Seeker component may get reset to the default value. If you did not use that field then you will not have to do anything. * AIPath now rotates towards actual movement direction when RVO is used. * Improvements * Improved pathfinding performance by around 8% for grid graphs, possibly more for other graph types. This involved removing a special case for when the pathfinding heuristic is not [admissable](https://en.wikipedia.org/wiki/Admissible_heuristic) (in short, when A\* Inspector -> Settings -> Heuristic Scale was greater than 1). Now paths calculated with the heuristic scale greater than 1 might be slightly less optimal compared to before. If this is important I suggest you reduce the heuristic scale to compensate. Note that as before: a heuristic scale of 1 is the default and if it is greater than 1 then the calculated paths may no longer be the shortest possible ones. * Improved overall pathfinding performance by an additional 10-12% by heavily optimizing some core algorithms. * Improved performance of querying for the closest node to a point when using the PointGraph and [optimizeForSparseGraph](https://arongranberg.com/astar/docs/pointgraph.html#optimizeForSparseGraph) . The improvements are around 7%. * Unified the API for the included movement scripts (AIPath, RichAI, AILerp) and added a large number of nice properties and functionality. * The [IAstarAI](https://arongranberg.com/astar/docs/iastarai.html) interface can now be used with all movement scripts. * To make it easier to migrate from Unity's navmesh system, this interface has been designed to be similar to Unity's NavmeshAgent API. * The interface has several nice properties like: [remainingDistance](https://arongranberg.com/astar/docs/iastarai.html#remainingDistance) , [reachedEndOfPath](https://arongranberg.com/astar/docs/iastarai.html#reachedEndOfPath) , [pathPending](https://arongranberg.com/astar/docs/iastarai.html#pathPending) , [steeringTarget](https://arongranberg.com/astar/docs/iastarai.html#steeringTarget) , [isStopped](https://arongranberg.com/astar/docs/iastarai.html#isStopped) , [destination](https://arongranberg.com/astar/docs/iastarai.html#destination) , and many more. * You no longer need to set the destination of an agent using a Transform object, instead you can simply set the [destination](https://arongranberg.com/astar/docs/iastarai.html#destination) property. Note that when you upgrade, a new AIDestinationSetter component will be automatically created which has a 'target' field. So your existing code will continue to work. * Improved behavior when AIPath/RichAI characters move down slopes. Previously the way gravity was handled could sometimes lead to a 'bouncing' behavior unless the gravity was very high. Old behavior on the left, new behavior on the right. * Improved the grid graph inspector by adding preconfigured modes for different node shapes: square grids, isometric grids and hexagons. This also reduces clutter in the inspector since irrelevant options can be hidden. ![](https://arongranberg.com/astar/docs/images/changelog/grid_shape.png) * For 2D grid graphs the inspector will now show a single rotation value instead of a full 3D rotation which makes it a lot easier to configure. * Improved the performance of the [RaycastModifier](https://arongranberg.com/astar/docs/raycastmodifier.html) significantly. Common speedups on grid graphs range from 2x to 10x. * The RaycastModifier now has a [quality enum](https://arongranberg.com/astar/docs/raycastmodifier.html#Quality) . The higher quality options use a new algorithm that is about the same performance (or slightly slower) compared to the RaycastModifier in previous versions however it often manages to simplify the path a lot more. The quality of the previous RaycastModifier with default settings corresponds to somewhere between the Low and Medium qualities. * Improved support for HiDPI (retina) screens as well as improved visual coherency for some icons. ![](https://arongranberg.com/astar/docs/images/changelog/retina_icons.png) * Improved the 'eye' icon for when a graph's gizmos are disabled to make it easier to spot. * Added [GridGraph.CalculateConnectionsForCellAndNeighbours](https://arongranberg.com/astar/docs/gridgraph/calculateconnectionsforcellandn.html#CalculateConnectionsForCellAndNeighbours) . * AIPath now works with point graphs in 2D as well (assuming the 'rotate in 2D' checkbox is enabled). * Improved the performance of the RVONavmesh component when used together with navmesh cutting, especially when many navmesh cuts are moving at the same time. * A warning is now displayed in the editor if one tries to use both the AIDestinationSetter and Patrol components on an agent at the same time. * Improved linecasts on recast/navmesh graphs. They are now more accurate (there were some edge cases that previously could cause it to fail) and faster. Performance has been improved by by around 3x for longer linecasts and 1.4x for shorter ones. * Linecast methods will now assign the [Pathfinding.GraphHitInfo.node](https://arongranberg.com/astar/docs/graphhitinfo.html#node) field with the last node that was traversed in case no obstacle was hit. * Linecast on graphs now set the hit point to the endpoint of the line if no obstacle was hit. Previously the endpoint would be set to Vector3.zero. Thanks borluse for suggesting this. * Multithreading is now enabled by default (1 thread). * The DynamicObstacle component now works with 2D colliders. * Clicking on the graph name in the inspector will no longer focus the name text field. To edit the graph name you will now have to click the Edit/Pen button to the right of the graph name. Previously it was easy to focus the text field by mistake when you actually wanted to show the graph settings. ![](https://arongranberg.com/astar/docs/images/changelog/edit_icon.png) * Reduced memory usage of the PointGraph when using [optimizeForSparseGraph](https://arongranberg.com/astar/docs/pointgraph.html#optimizeForSparseGraph) . * Improved the StartEndModifier inspector slightly. * The Seeker inspector now has support for multi-editing. * The AIPath and RichAI scripts now rotate to face the direction they are actually moving with when using local avoidance (RVO) instead of always facing the direction they want to move with. At very low speeds they fall back to looking the direction they want to move with to avoid jitter. * Improved the Seeker inspector. Unified the UI for setting tag penalties and determining if a tag should be traversable. ![](https://arongranberg.com/astar/docs/images/changelog/seeker_tags.png) * Reduced string allocations for error messages when paths fail. * Added support for 2D physics to the [Pathfinding.RaycastModifier](https://arongranberg.com/astar/docs/raycastmodifier.html) component. * Improved performance of GraphUpdateObjects with updatePhysics=false on rotated navmesh/recast graphs. * Improved the inspector for AILerp. * RVO obstacles can now be visualized by enabling the 'Draw Obstacles' checkbox on the RVOSimulator component. ![](https://arongranberg.com/astar/docs/images/changelog/rvo_navmesh_obstacle.png) * Reduced allocations in the funnel modifier. * Added a 'filter' parameter to [PathUtilities.BFS](https://arongranberg.com/astar/docs/pathutilities/bfs.html#BFS) and [PathUtilities.GetReachableNodes](https://arongranberg.com/astar/docs/pathutilities/getreachablenodes.html#GetReachableNodes) . * Added a method called [SetPath](https://arongranberg.com/astar/docs/iastarai/setpath.html#SetPath) to all movement scripts. * Added [GraphNode.Graph](https://arongranberg.com/astar/docs/graphnode.html#Graph) . * Added [Pathfinding.MeshNode.ContainsPoint(Vector3)](https://arongranberg.com/astar/docs/graphnode/containspoint.html#ContainsPoint) in addition to the already existing MeshNode.ContainsPoint(Int3). * Added [Pathfinding.MeshNode.ContainsPointInGraphSpace](https://arongranberg.com/astar/docs/graphnode/containspointingraphspace.html#ContainsPointInGraphSpace) . * Added [Pathfinding.TriangleMeshNode.GetVerticesInGraphSpace](https://arongranberg.com/astar/docs/trianglemeshnode/getverticesingraphspace.html#GetVerticesInGraphSpace) . * Added Pathfinding.AstarData.FindGraph(predicate). * Added Pathfinding.AstarData.FindGraphWhichInheritsFrom(type). * Added a new class [GraphUtilities](https://arongranberg.com/astar/docs/graphutilities.html) which has some utilities for extracting contours of graphs. * Added a new method Linecast(GridNodeBase,GridNodeBase) to the GridGraph class which is much faster than the normal Linecast methods. * Added [GridGraph.GetNode(int,int)](https://arongranberg.com/astar/docs/gridgraph/getnode.html#GetNode) . * Added MeshNode.AddConnection(node,cost,edge) in addition to the already existing AddConnection(node,cost) method. * Added a [Pathfinding.NavMeshGraph.recalculateNormals](https://arongranberg.com/astar/docs/navmeshgraph.html#recalculateNormals) setting to the navmesh graph for using the original mesh normals. This is useful for spherical/curved worlds. * Documentation * Added a documentation page on error messages: [Error messages](https://arongranberg.com/astar/docs/errormessages.html) . * Added a tutorial on how to create a wandering AI: [Wandering AI Tutorial](https://arongranberg.com/astar/docs/wander.html) . * Added tutorial on bitmasks: [Bitmask Tutorial](https://arongranberg.com/astar/docs/bitmasks.html) . * You can now right-click on most fields in the Unity Inspector to bring up a link to the online documentation. ![](https://arongranberg.com/astar/docs/images/inspector_doc_links.png) * Various other documentation improvements and fixes. * Changes * Height or collision testing for grid graphs now never hits triggers, regardless of the Unity Physics setting 'Queries Hit Triggers' which has previously controlled this. * Seeker.StartPath will no longer overwrite the path's graphMask unless it was explicitly passed as a parameter to the StartPath method. * The built in movement scripts no longer uses a coroutine for scheduling path recalculations. This shouldn't have any impact for you unless you have been modifying those scripts. * Replaced the MineBotAI script that has been used in the tutorials with MineBotAnimation. The new script does not inherit from AIPath so in the example scenes there is now one AIPath component and one MineBotAnimation script on each unit. * Removed prompt to make the package support UnityScript which would show up the first time you used the package in a new project. Few people use UnityScript nowadays so that prompt was mostly annoying. UnityScript support can still be enabled.. * If deserialization fails, the graph data will no longer be stored in a backup byte array to be able to be recovered later. This was not very useful, but more importantly if the graph data was very large (several megabytes) then Unity's Undo system would choke on it and essentially freeze the Unity editor. * The StartEndModifier's raycasting options are now only used if the 'Original' snapping option is used as that's the only one it makes sense for. * The RaycastModifier.subdivideEveryIter field has been removed, this is now always enabled except for the lowest quality setting. * The RaycastModifier.iterations field has been removed. The number of iterations is now controlled by the quality field. Unfortunately this setting cannot be directly mapped to a quality value, so if you are upgrading all RaycastModifier components will use the quality Medium after the upgrade. * The default value for [RVOController.lockWhenNotMoving](https://arongranberg.com/astar/docs/rvocontroller.html#lockWhenNotMoving) is now false. * Tiles are now enabled by default on recast graphs. * Modifiers now register/unregister themselves with the Seeker component during OnEnable/OnDisable instead of Awake/OnDestroy. If you have written any custom modifiers which defines those methods you may have to add the 'override' modifier to those methods and call base.OnEnable/OnDisable. * When paths fail this is now always logged as a warning in the Unity console instead of a normal log message. * Node connections now store which edge of the node shape that is used for that node. This is used for navmesh/recast graphs. * The [RVOController.velocity](https://arongranberg.com/astar/docs/rvocontroller.html#velocity) property can now be assigned to and that has the same effect as calling ForceSetVelocity. * Deprecated the RVOController.ForceSetVelocity method. You should use the velocity property instead. * All graphs now explicitly implement the IUpdatableGraph interface. This is done to hide those methods (which should not be used directly) and thereby reduce confusion about which methods should be used to update graphs. * Hid several internal methods behind the IGraphInternals interface to reduce clutter in the documentation and IntelliSense suggestions. * Removed NavGraph.UnloadGizmoMeshes because it was not used for anything. * Since 4.0 individual graphs can be scanned using [AstarPath.Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) . The older NavGraph.Scan method now redirects to that method which is more robust. This may cause slight changes in behavior, however the recommendation in the documentation has always been to use [AstarPath.Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) anyway so I do not expect many to have used the NavGraph.Scan method. * Deprecated the NavGraph.ScanGraph method since it just does the same thing as NavGraph.Scan. * Deprecated the internal methods Path.LogError and Path.Log. * Added the new internal method Path.FailWithError which replaces LogError and Log. * Made the AIPath.TrySearchPath method private, it should never have been public to begin with. * Fixes * Fixed AIPath/RichAI throwing exceptions in the Unity Editor when drawing gizmos if the game starts while they are enabled in a disabled gameObject. * Fixed some typos in the documentation for PathUtilities.BFS and PathUtilities.GetReachableNodes. * For some point graph settings, path requests to points that could not be reached would fail completely instead of going to the closest node that it could reach. Thanks BYELIK for reporting this bug. If you for some reason have been relying on the old buggy behavior you can emulate it by setting A\* Inspector -> Settings -> Max Nearest Node Distance to a very low value. * Fixed connection costs were assumed to be equal in both directions for bidirectional connections. * Fixed a compiler error when building for UWP/HoloLens. * Fixed some cases where circles used for debugging could have a much lower resolution than intended (Pathfinding.Util.Draw.CircleXZ). * Fixed RVO agents which were locked but some script sent it movement commands would cause the RVO system to think it was moving even though it was actually stationary, causing some odd behavior. Now locked agents are always treated as stationary. * Fixed RVO obstacles generated from graph borders (using the RVONavmesh component) could be incorrect if a tiled recast graph and navmesh cutting was used. The bug resulted in an RVO obstacle around the tile that was most recently updated by a navmesh cut even where there should be no obstacle. * Fixed the RVONavmesh component could throw an exception in some cases when using tiled recast graphs. * Fixed a regression in some 4.0.x version where setting [RVOController.velocity](https://arongranberg.com/astar/docs/rvocontroller.html#velocity) to make the agent's movement externally controlled would not work properly (the system would always think the agent had a velocity of zero). * Fixed the RichAI movement script could sometimes get stuck on the border between two tiles. (due to a possibility of division by zero that would cause its velocity to become NaN). * Fixed AIPath/RichAI movement not working properly with rigidbodies in Unity 2017.3+ when the new physics setting "Auto Sync Transforms" was disabled. Thanks DougW for reporting this and coming up with a fix. * Fixed a few cases where [RichAI](https://arongranberg.com/astar/docs/richai.html) would automatically recalculate its path even though [canSearch](https://arongranberg.com/astar/docs/richai.html#canSearch) was disabled. * Fixed some compiler warnings when using Unity 2017.3 or later. * Fixed graphical artifacts in the graph visualization line drawing code which could show up at very large coordinate values or steep viewing angles. Differential calculus can be really useful sometimes. * Fixed the [MultiTargetPathExample.cs](https://arongranberg.com/astar/docs/multitargetpathexamplecs.html) . * Fixed the width/depth fields in the recast graph inspector causing warnings to be logged (introduced in 4.1.7). Thanks NoxMortem for reporting this. * Fixed the [Pathfinding.GraphHitInfo.tangentOrigin](https://arongranberg.com/astar/docs/graphhitinfo.html#tangentOrigin) field was offset by half a node when using linecasting on grid graphs. * Fixed the AIPath script with rotationIn2D would rotate so that the Z axis pointed in the -Z direction instead of as is common for Unity 2D objects: to point in the +Z direction. * Fixed the AILerp script with rotationIn2D would rotate incorrectly if it started out with the Z axis pointed in the -Z direction. * Clamp recast graph bounding box size to be non-zero on all axes. * The DynamicObstacle component will now properly update the graph when the object is deactivated since the object just disappeared and shouldn't block the graph anymore. Previously it only did this if the object was destroyed, not if it was deactivated. * Fixed [AILerp](https://arongranberg.com/astar/docs/ailerp.html) ceasing to work properly if one of the paths it tries to calculate fails. * Fixed the [FunnelModifier](https://arongranberg.com/astar/docs/funnelmodifier.html) could yield a zero length path in some rare circumstances when using custom node links. This could lead to an exception in some of the movement scripts. Thanks DougW for reporting the bug. * Fixed calling Seeker.CancelCurrentPathRequest could in some cases cause an exception to be thrown due to multithreading race conditions. * Fixed a multithreading race condition which could cause a path canceled by Seeker.CancelCurrentPathRequest to not actually be canceled. * Fixed a rare ArrayOutOfBoundsException when using the FunnelModifier with the 'unwrap' option enabled. * Fixed Seeker -> Start End Modifier could not be expanded in the Unity inspector. Thanks Dee\_Lucky for reporting this. * Fixed a few compatiblity bugs relating to AIPath/RichAI that were introduced in 4.1.0. * Fixed funnel modifier could sometimes fail if the agent started exactly on the border between two nodes. * Fixed another bug which could cause the funnel modifier to produce incorrect results (it was checking for colinearity of points in 2D instead of in 3D). * Fixed the funnel modifier would sometimes clip a corner near the end of the path. * Fixed ProceduralGraphMover would not detect user defined graphs that were subclasses of the GridGraph class. Thanks viveleroi for reporting this. * Fixed enabling and disabling a AIPath or RichAI component a very large number of times could potentially have a negative performance impact. * Fixed AIPath/RichAI would continue searching for paths even when the component had been disabled. * MeshNode.ContainsPoint now supports rotated graphs properly. MeshNode is used in navmesh and recast graphs. * Fixed Linecast for navmesh and recast graphs not working for rotated graphs. * Fixed RVONavmesh component not working properly with grid graphs that had height differences. * Fixed 2D RVO agents sometimes ignoring obstacles. * Fixed RVONavmesh not removing the obstacles it had created when the component was disabled. * Fixed RaycastModifier could miss obstacles when thick raycasting was used due to Unity's Physics.SphereCast method not reporting hits very close to the start of the raycast. * In the free version the inspector for RaycastModifier now displays a warning if graph raycasting is enabled since for all built-in graphs raycasts are only supported in the pro version. * Fixed some cases where the funnel modifier would produce incorrect results. * Fixed typo in a private method in the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) class. Renamed the UpdateGraphsInteral method to UpdateGraphsInternal. * Fixed AIPath.remainingDistance and AIPath.targetReached could be incorrect for 1 frame when a new path had just been calculated (introduced in a previous beta release). * 4.0.11 (2017-09-09) * Fixed paths would ignore the ITraversalProvider (used for the turn based utilities) on the first node of the path, resulting in successful paths where they should have failed. * Fixed BlockManager.BlockMode.AllExceptSelector could often produce incorrect results. Thanks Cquels for spotting the bug. * Fixed various bugs related to destroying/adding graphs that could cause exceptions. Thanks DougW for reporting this. * Fixed destroying a grid graph would not correctly clear all custom connections. Thanks DougW for reporting this. * Fixed the MultiTargetPath did not reset all fields to their default values when using path pooling. * Added some additional error validation in the MultiTargetPath class. * Fixed scanning a recast graph that was not using tiles using Unity 2017.1 or later on Windows could block indefinitely. Thanks David Drummond and ceebeee for reporting this. * Improved compatibility with Nintendo Switch. Thanks Noogy for the help. * Fixed GraphUpdateScene would not handle the GameObject's scale properly which could cause it to not update some nodes. * Fixed a regression in 4.0 which could cause the error to be omitted from log messages when paths failed. * Fixed several bugs relating to [Pathfinding.NNConstraint.distanceXZ](https://arongranberg.com/astar/docs/nnconstraint.html#distanceXZ) and [Pathfinding.NavmeshBase.nearestSearchOnlyXZ](https://arongranberg.com/astar/docs/navmeshbase.html#nearestSearchOnlyXZ) . Thanks koirat for reporting this. * Fixed scanning a graph that threw an error would prevent any future scans. Thanks Baste for reporting this. * Added a new get started video tutorial. See [Get Started Guide](https://arongranberg.com/astar/docs/getstarted.html) . * The PointGraph.nodeCount property is now protected instead of private, which fixes some compatibility issues. * Improved compatibility with Unity 2017.1, esp. when using the experimental .Net 4.6 target. Thanks Scott\_Richmond for reporting the issues. * Fixed DynamicObstacle trying to update the graphs even when outside of play mode. * Fixed runtime error when targeting the Windows Store. Thanks cedtat for reporting the bug. * Fixed compilation error when targeting the Windows Store. Introduced in 4.0.3. Thanks cedtat for reporting the bug. * 4.0.10 (2017-05-01) * Fixed compiler errors in the free version because the [ManualRVOAgent.cs](https://arongranberg.com/astar/docs/%3Cundefined%3E) script being included by mistake. Thanks hummerbummer for reporting the issue. * Fixed Unity's scene view picking being blocked by graph gizmos. Thanks Scott\_Richmond for reporting the bug. * 4.0.9 (2017-04-28) * Significantly improved performance and reduced allocations when recalculating indivudal recast tiles during runtime and there are terrains in the scene. * Fixed the GraphUpdateScene inspector showing a warning for one frame after the 'convex' field has been changed. * Fixed a few compiler warnings in Unity 5.6. Thanks TotalXep for reporting the issue. * Fixed graph drawing could generate large amounts of garbage due to a missing GetHashCode override which causes Mono to have to allocate some dummy objects. * Fixed graph gizmo lines could be rendered incorrectly on Unity 5.6 on mac and possibly on Windows too. * 4.0.8 (2017-04-28) * Added rotationIn2D to the AIPath script. It makes it possible to use the Y axis as the forward axis of the character which is useful for 2D games. * Exposed the GridGraph.LayerCount property which works for both grid graphs and layered grid graphs (for grid graphs it always returns 1). * Made the LayerGridGraph.layerCount field internal to discourage its use outside the LayerGridGraph class. * Fixed exception when destroying some graph types (introduced in 4.0.6). Thanks unfalco for reporting the bug. * Fixed exception in GridGraph.GetNodesInRegion when being called with an invalid rectangle or a rectangle or bounds object that was completely outside the graph. Thanks WillG for finding the bug. * Fixed AIPath/RichAI not rotating to the correct direction if they started in a rotation such that the forward axis was perpendicular to the movement plane. * 4.0.7 (2017-04-27) * Fixed 2D example scenes had their grids rotated by (90,0,0) instead of (-90,0,0). It doesn't matter for those scenes, but the (-90,0,0) leads to more intuitive axis rotations for most use cases. Thanks GeloMan for noticing this. * Renamed AISimpleLerp to AILerp in the component menu as the documentation only refers to it by the name 'AILerp'. * Added a new documentation page and video tutorial ([Pathfinding in 2D](https://arongranberg.com/astar/docs/pathfinding2d.html) ) showing how to configure pathfinding in 2D games. * 4.0.6 (2017-04-21) * Fixed creating a RichAI and in the same frame setting the target and calling UpdatePath would always result in that path being canceled. * Fixed a race condition which meant that if you called RichAI.UpdatePath, AILerp.SearchPath or AIPath.SearchPath during the same frame that the agent was created then the callback for that path would sometimes be missed and the AI would wait indefinitely for it. This could cause the agents to sometimes never start moving. * Fixed adding a new graph while graph updates were running at the same time could potentially cause errors. * Added NavGraph.exists which will become false when a graph has been destroyed. * Fixed TileHandlerHelper could throw exceptions if the graph it was tracking was destroyed. * Fixed TileHandlerHelper not detecting new NavmeshCut or NavmeshAdd components that were created before the TileHandlerHelper component was created or when it was disabled. * TileHandlerHelper no longer logs an error if it is created before a recast/navmesh graph exists in the scene and when one is created the TileHandlerHelper will automatically detect it and start to update it. * Fixed TileHandlerHelper could throw exceptions if the graph it was tracking changed dimensions. * Fixed recast graphs would always rasterize capsule colliders as if they had their 'direction' setting set to 'Y-axis'. Thanks emrys90 for reporting the bug. * The package now contains a 'documentation.html' file which contains an offline version of the 'Get Started' tutorial. * 4.0.5 (2017-04-18) * Improved compatibility with Opsive's Behavior Designer - Movement Pack ([https://www.assetstore.unity3d.com/en/#!/content/16853](https://www.assetstore.unity3d.com/en/#!/content/16853) ). * The 4.0 update combined with the Movement Pack caused some compiler errors previously. * 4.0.4 (2017-04-17) * Fixed the funnel modifier not working if 'Add Points' on the Seeker's Start End Modifier was enabled. Thanks Blaze\_Barclay for reporting it. * Fixed code typo in the [Writing Modifiers](https://arongranberg.com/astar/docs/writemodifiers.html) tutorial as well as made a few smaller improvements to it. * Fixed some cases where the LegacyRVOController would not behave like the RVOController before version 4.0. * Fixed LegacyAIPath not using the same custom inspector as the AIPath component. * 4.0.3 (2017-04-16) * Improved code style and improved documentation for some classes. * Reduced memory allocations a bit when using the NavmeshAdd component. * Fixed graph types not necessarily being initialized when scanning the graph outside of play mode. * Fixed LayerGridGraph not reporting scanning progress properly. This caused it to not work well with ScanAsync and when scanning the graph in the editor the progress bar would only update once the whole graph had been scanned. * Removed the DebugUtility class which was only used for development when debugging the recast graph. * 4.0.2 (2017-04-16) * Fixed a minor bug in the update checker. * Deduplicated code for drawing circles and other shapes using Debug.Draw\* or Gizmos.Draw\* and moved this code to a new class Pathfinding.Util.Draw. * 4.0.1 (2017-04-15) * Improved how AIPath and RichAI work with rigidbodies. * Added option for gravity to AIPath. * Removed the RichAI.raycastingForGroundPlacement field as it is automatically enabled now if any gravity is used. * AIPath and RichAI now inherit from the same base class [Pathfinding.AIBase](https://arongranberg.com/astar/docs/aibase.html) . * 4.0 (2017-04-10) * Upgrade Notes * This release contains some significant changes. **It is strongly recommended that you back up your project before upgrading**. * If you get errors immediately after upgrading, try to delete the AstarPathfindingProject folder and import the package again. Sometimes UnityPackages will leave old files which can cause issues. * Moved some things to inside the [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) namespace to avoid naming collisions with other packages. Make sure you have the line 'using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) ;' at the top of your scripts. Some example scripts have been moved to the Pathfinding.Examples namespace. * The RVOController component no longer handles movement as it turned out that was a bad idea. Having multiple components that handled movement (e.g RichAI and RVOController) didn't turn out well and it was very hard to configure the settings so that it worked well. The RVOController now exposes the CalculateMovementDelta method which allows other scripts to ask it how the local avoidance system thinks the character should move during this frame. If you use the RichAI or AIPath components for movement, everything should work straight away. If you use a custom movement script you may need to change your code to use the CalculateMovementDelta method for movement. Some settings may need to be tweaked, but hopefully it should not be too hard. * Node connections are now represented using an array of structs (of type [Connection](https://arongranberg.com/astar/docs/connection.html) ) instead of one array for target nodes and one array for costs. * When upgrading an existing project legacy versions of the RVOController, RichAI, AIPath and GraphUpdateScene components will be used for compatibility reasons. You will have to click a button in the inspector to upgrade them to the latest versions. I have tried to make sure that the movement scripts behave the same as they did before version 4.0, but it is possible that there are some minor differences. If you have used a custom movement script which inherits from AIPath or RichAI then the legacy components cannot be used automatically, instead the new versions will be used from the start. * New Features And Improvements * Local Avoidance * The RVO system has been cleaned up a lot. * Agents will now always avoid walls and obstacles even if that would put them on a collision course with another agent. This helps with a previous problem of agents being able to be pushed into walls and obstacles (note that RVONavmesh or RVOSquareObstacle still need to be used). * The RVOSimulator can now be configured for XZ space or XY space (2D). * The RVOController no longer handles movement itself as this turned out to be a really bad idea (see upgrade notes section). * The RVOController can now be used to stop at a target much more precisely than before using the SetTarget method. * Agents are now [biased slightly](https://arongranberg.com/astar/docs/rvosimulator.html#symmetryBreakingBias) towards passing other agents on the right side, this helps resolve some situations with a lot of symmetry much faster. * All fuzzy and hard to adjust parameters from the [RVOSimulator](https://arongranberg.com/astar/docs/rvosimulator.html) component have been removed. It should now be much easier to configure. * The RichAI movement script now works a lot better with the RVOController. Previously the movement could be drastically different when the RVOController was used and local avoidance didn't work well when the agent was at the edge of the navmesh. * Improved gizmos for the RVOController. * Added RVOController.ForceSetVelocity to use when you want agents to avoid a player (or otherwise externally controlled) character. * RVO agents can now have different priorities, lower priority agents will avoid higher priority agents more. * The neighbour distance field is now automatically calculated. This makes it easier to configure the agents and it will also improve performance slightly when the agents are moving slowly (for example in very crowded scenarios). * Added support for grid graphs to [RVONavmesh](https://arongranberg.com/astar/docs/rvonavmesh.html) . * Added a new example scene for RVO in 2D * General * Huge increase in the performance of graph gizmos. This was accomplished by bypassing the Unity Gizmos and creating a custom gizmo rendererer that is able to retain the gizmo meshes instead of recreating them every frame (as well as using a lot fewer draw calls than Unity Gizmos). Therefore the graphs usually only need to check if the nodes have changed, and only if they have changed they will rebuild the gizmo meshes. **This may cause graph updates to seem like they introduce more lag than they actually do** since a graph update will also trigger a gizmo rebuild. So make sure to always profile with gizmos disabled. For a 1000\*1000 graph, which previously almost froze the editor, the time per frame went from over 4200 ms to around 90 ms when no nodes had changed. * Improved the style of graph gizmos. A solid surface is now rendered instead of only the connections between the nodes. The previous mode of rendering only connections is of course still available. ![](https://arongranberg.com/astar/docs/images/3vs4/gizmos.png) * Added a new example scene showing how to configure hexagon graphs. * Added gizmos for hexagon graphs (grid graphs with certain settings). ![](https://arongranberg.com/astar/docs/images/3vs4/hexagon_thin.png) * Implemented async scanning. [AstarPath.active.ScanAsync](https://arongranberg.com/astar/docs/astarpath/scanasync.html#ScanAsync) is an IEnumerable that can be iterated over several frames so that e.g a progress bar can be shown while calculating the graphs. Note that this does not guarantee a good framerate, but at least you can show a progress bar. * Improved behaviour of the AIPath movement script. * AIPath now works in the XY plane as well. In fact it works with any graph rotation. The Z axis is always the forward axis for the agent, so for 2D games with sprites you may have to attach the sprite to a child object which is rotated for it to show up correctly. * Previously the slowdownDistance had to be smaller than the forwardLook field otherwise the character could slow down even when it had not reached the end of the path. * The agent should stop much more precisely at the end of the path now. * The agent now rotates with a fixed angular speed instead of a varying one as this is often more realistic. * Reduced the likelihood of the agent spinning around when it reaches the end of the path. * It no longer uses the forwardLook variable. It was very tricky to set correctly, now the pickNextWaypointDist variable is used for everything instead and generally this should give you smoother movement. * Improved behaviour of the [RichAI](https://arongranberg.com/astar/docs/richai.html) movement script. * The agent should stop much more precisely at the end of the path now. * Reduced the likelihood of the agent spinning around when it reaches the end of the path. * Scanning the graph using [AstarPath.Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) will now profile the various parts of the graph scanning process using the Unity profiler (Profiler.BeginSample and Profiler.EndSample). * [DynamicObstacle](https://arongranberg.com/astar/docs/dynamicobstacle.html) will now update the graph immediately if an object with that component is created during runtime instead of waiting until it was moved for the first time. * [GraphUpdateScene](https://arongranberg.com/astar/docs/graphupdatescene.html) and [GraphUpdateShape](https://arongranberg.com/astar/docs/graphupdateshape.html) can now handle rotated graphs a lot better. The rotation of the object the GraphUpdateScene component is attached to determines the 'up' direction for the shape and thus which points will be considered to be inside the shape. The world space option had to be removed from GraphUpdateScene because it didn't really work with rotated graphs. The lockToY option for GraphUpdateScene has also been removed because it wasn't very useful and after this change it would only have had an impact in rare cases. * Improved [GraphUpdateScene](https://arongranberg.com/astar/docs/graphupdatescene.html) editor. When editing the points in the scene view it now shows helper lines to indicate where a new point is going to be added and which other points it will connect to as well as several other minor improvements. * [GraphUpdateScene](https://arongranberg.com/astar/docs/graphupdatescene.html) now supports using the bounds from 2D colliders and the shape from PolygonCollider2D. * Added opaqueness slider for the gizmos under Inspector -> Settings -> Colors. * Added [Path.BlockUntilCalculated](https://arongranberg.com/astar/docs/path/blockuntilcalculated.html#BlockUntilCalculated) which is identical to [AstarPath.BlockUntilCalculated](https://arongranberg.com/astar/docs/astarpath/blockuntilcalculated.html#BlockUntilCalculated) . * Added Seeker.CancelCurrentPathRequest. * Added [NavGraph.GetNodes(System.Action)](https://arongranberg.com/astar/docs/navgraph/getnodes.html#GetNodes) which calls a delegate with each node in the graph. Previously NavGraph.GetNodes(GraphNodeDelegateCancelable) existed which did the same thing but required the delegate to return true if it wanted the graph to continue calling it with more nodes. It turns out this functionality was very rarely needed. * Individual graphs can now be scanned using [AstarPath.Scan(NavGraph)](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) and other related overloads. * Improved [priority queue](https://arongranberg.com/astar/docs/binaryheap.html) performance. On average results in about a 2% overall pathfinding performance increase. * ObjectPool now requires a ref parameter when calling Release with an object to help prevent silly bugs. * 'Min Area Size' has been removed. The edge cases are now handled automatically. * Added ObjectPoolSimple as a generic object pool (ObjectPool also exists, but for that T must implement IAstarPooledObject). * [RaycastModifier](https://arongranberg.com/astar/docs/raycastmodifier.html) now supports multi editing. * Added [GraphNode.RandomPointOnSurface](https://arongranberg.com/astar/docs/graphnode/randompointonsurface.html#RandomPointOnSurface) . * Added [GraphNode.SurfaceArea](https://arongranberg.com/astar/docs/graphnode/surfacearea.html#SurfaceArea) . * Int2 and [Int3](https://arongranberg.com/astar/docs/int3.html) now implement IEquatable for slightly better performance and fewer allocations in some places. * [LocalSpaceRichAI](https://arongranberg.com/astar/docs/localspacerichai.html) can now be used with any rotation (even things like moving on an object that is upside down). * The [funnel modifier](https://arongranberg.com/astar/docs/funnelmodifier.html) can now handle arbitrary graphs (even graphs in the 2D plane) if the new unwrap option is enabled. * The [funnel modifier](https://arongranberg.com/astar/docs/funnelmodifier.html) can split the resulting path at each portal if the new [splitAtEveryPortal](https://arongranberg.com/astar/docs/funnelmodifier.html#splitAtEveryPortal) option is enabled. * Recast/Navmesh Graphs * Recast graph scanning is now multithreaded which can improve scan times significantly. * Recast graph scanning now handles large worlds with lots of objects better. This can improve scan times significantly. * Improved performance of nearest node queries for Recast/navmesh graphs. * Editing navmesh cut properties in the inspector now forces updates to happen immediately which makes editing easier. * Long edges in recast graphs are now split at tile borders as well as at obstacle borders. This can in particular help on terrain maps where the tile borders do not follow the elevation that well so the max edge length can be reduced to allow the border to follow the elevation of the terrain better. * Recast graphs can now be rotated arbitrarily. * Navmesh cutting still works! * The RichAI script currently does not support movement on rotated graphs, but the AIPath script does. * Improved performance of navmesh cutting for large worlds with many tiles and NavmeshAdd components. * Navmesh graphs and recast graphs now share the same base code which means that navmesh graphs now support everything that previously only recast graphs could be used for, for example navmesh cutting. * The NavmeshCut inspector now shows a warning if no TileHandlerHelper component is present in the scene. A TileHandlerHelper component is necessary for the NavmeshCuts to update the graphs. * Recast graphs now use less memory due to the BBTree class now using around 70% less memory per node. * Recast graphs now allocate slightly less memory when recalculating tiles or scanning the graph. * Cell height on Recast graphs is now automatically set to a good value. * Navmesh cutting is now a bit better at using object pooling to avoid allocations. * TileHandlerHelper now updates the tiles properly when one or multiple tiles on the recast graph are recalculated due to a graph update or because it was rescanned. * Navmesh cutting now uses more pooling to reduce allocations slightly. * Improved performance of loading and updating (using navmesh cutting) recast tiles with a large number of nodes. * Grid Graphs * Added LevelGridNode.XCoordinateInGrid, LevelGridNode.ZCoordinateInGrid, LevelGridNode.LayerCoordinateInGrid. * Added GridGraph.GetNodesInRegion(IntRect). Also works for layered grid graphs. * Layered grid graphs now have support for 'Erosion Uses Tags'. * Added GridGraph.CalculateConnections(GridNodeBase) which can be used for both grid graphs and layered grid graphs. * Grid graphs can now draw the surface and outline of the graph instead of just the connections between the nodes. The inspector now contains several toggles that can be used to switch between the different rendering modes. * The ProceduralGraphMover component now works with LayerGridGraph as well. * Added GridGraph.RecalculateCell(x,y) which works both for grid graphs and layered grid graphs. This replaces the UpdateNodePositionCollision method and that method is now deprecated. * Improved GridGraph.RelocateNodes which is now a lot more resilient against floating point errors. * Added dimetric (60°) to the list of default values for the isometric angle field on grid graphs. * Changing the width/depth of a grid graph will now keep the current pivot point at the same position instead of always keeping the bottom left corner fixed. (the pivot point can be changed to the center/bottom left/top left/top right/bottom right right next to the position field in the grid graph inspector) * Improved fluidity and stability when resizing a grid graph in the scene view. It now snaps to full node increments in size. * Grid graphs now display a faint grid pattern in the scene view even when the graph is not scanned to make it easier to position and resize the graph. * Improved styling of some help boxes in the grid graph inspector when using the dark UI skin. * The size of the unwalkable node gizmo (red cube) on grid graphs is now based on the node size to avoid the gizmos being much larger or much smaller than the nodes. * Implemented [special case for paths on grid graphs](https://arongranberg.com/astar/docs/abpath/endpointgridgraphspecialcase.html#EndPointGridGraphSpecialCase) so that if you request a path to an unwalkable node with several walkable nodes around it, it will now not pick the closest walkable node to the requested target point and find a path to that but it will find the shortest path which goes to any of the walkable nodes around the unwalkable node. [Before](https://arongranberg.com/astar/docs/images/abpath_grid_not_special.gif) , [After](https://arongranberg.com/astar/docs/images/abpath_grid_special.gif) . This is a special case of the MultiTargetPath, for more complicated configurations of targets the multi target path needs to be used to be able to handle it correctly. * Changes * Node connections are now represented using an array of structs (of type Connection) instead of one array for target nodes and one array for costs. * When scanning a graph in the editor, the progress bar is not displayed until at least 200 ms has passed. Since displaying the progress bar is pretty slow, this makes scanning small graphs feel more snappy. * GridGraph and LayerGridGraph classes now have a 'transform' field instead of a matrix and inverseMatrix fields. The GraphTransform class also has various other nice utilities. * Moved mesh collecting code for Recast graphs to a separate class to improve readability. * Refactored out large parts of the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) class to separate smaller classes to improve readability and increase encapsulation. * AstarPath.RegisterSafeUpdate is now implemented using WorkItems. This yields a slightly different behavior (previously callbacks added using RegisterSafeUpdate would always be executed before work items), but that should rarely be something that you would depend on. * Replaced AstarPath.BlockUntilPathQueueBlocked with the more robust [AstarPath.PausePathfinding](https://arongranberg.com/astar/docs/astarpath/pausepathfinding.html#PausePathfinding) method. * The default radius, height and center for RVOControllers is now 0.5, 2 and 1 respectively. * To reduce confusion. The second area color is now a greenish color instead of a red one. The red color would often be mistaken as indicating unwalkable nodes instead of simply a different connected component. Hopefully green will be a more neutral color. * Renamed AstarPath.astarData to [AstarPath.data](https://arongranberg.com/astar/docs/astarpath.html#data) . * Renamed NavmeshCut.useRotation and NavmeshAdd.useRotation to useRotationAndScale (since they have always affected scale too). * Renamed GridGraph.GenerateMatrix to GridGraph.UpdateTransform to be consistent with recast/navmesh graphs. The GenerateMatrix method is now deprecated. * Renamed AstarPath.WaitForPath to [AstarPath.BlockUntilCalculated](https://arongranberg.com/astar/docs/astarpath/blockuntilcalculated.html#BlockUntilCalculated) . * Renamed GridNode.GetConnectionInternal to HasConnectionInDirection. * Renamed NNInfo.clampedPosition to NNInfo.position. * Renamed GridGraph.GetNodesInArea to GetNodesInRegion to avoid confusing the word 'area' for what is used to indicate different connected components in graphs. * Renamed AIPath.turningSpeed to [rotationSpeed](https://arongranberg.com/astar/docs/aipath.html#rotationSpeed) . * Deprecated Seeker.GetNewPath. * Deprecated NavGraph.matrix, NavGraph.inverseMatrix, NavGraph.SetMatrix and NavGraph.RelocateNodes(Matrix4x4,Matrix4x4). They have been replaced with a single transform field only available on some graph types as well as a few other overloads of teh RelocateNodes method. * Changed the signature of NavGraph.GetNodes(GraphNodeDelegateCancelable) to the equivalent NavGraph.GetNodes(System.Func). * Replaced all instances of GraphNodeDelegate with the equivalent type System.Action. * Made a large number of previously public methods internal to reduce confusion about which methods one should use in a class and make the documentation easier to read. In particular the Path class has had its set of public methods reduced a lot. * Made AstarData.AddGraph(NavGraph) private. Scripts should use AstarData.AddGraph(System.Type) instead. * Moved internal fields of NNInfo into a new NNInfoInternal struct to make the API easier to use. Previously NNInfo contained some internal fields, but now they are only in NNInfoInternal. * Moved GetNeighbourAlongDirection to GridNodeBase and made it public. * An overload of the GridGraph.CalculateConnections method has been made non-static. * LayerGridGraph.LinkedLevelNode and LayerGridGraph.LinkedLevelCell are now private classes since they are only used by the LayerGridGraph. * MonoModifier.OnDestroy is now a virtual function. * [AstarPath.IsUsingMultithreading](https://arongranberg.com/astar/docs/astarpath.html#IsUsingMultithreading) and NumbParallelThreads have been made non-static. * [AstarPath.inGameDebugPath](https://arongranberg.com/astar/docs/astarpath.html#inGameDebugPath) is now private. * [AstarPath.lastScanTime](https://arongranberg.com/astar/docs/astarpath.html#lastScanTime) is now read only. * Removed the 'climb axis' field from grid graphs. The axis is now automatically set to the graph's UP direction (which is the only direction that makes sense and all other directions can be transformed to this one anyway). * Removed the 'worldSpace' parameter from RecastGraph.ReplaceTile, it is no longer possible to supply world space vertices to that method since graph space vertices are required for some things. * Removed BBTree.QueryCircle and BBTree.Query since they were not used anywhere. * Removed the Path.searchIterations field because it wasn't very useful even as debug information. * Removed the Path.maxFrameTime field because it was not used. * Removed the Path.callTime property because it was not used. * Removed the ABPath.startHint, ABPath.endHint fields because they were not used. * Removed the ABPath.recalcStartEndCosts field because it was not used. * Removed the RecursiveBinary and RecursiveTrinary modes for RichAI.funnelSimplification because the Iterative mode was usually the best and fastest anyway (also the other two modes had a rare bug where they could get cought in infinite loops). * Removed the Polygon.Subdivide method because it was not used anywhere. * Removed the NavGraph.Awake method because it was not used for anything. * Removed ASTAR\_OPTIMIZE\_POOLING from Optimization tab. It is now always enabled in standalone builds and always disabled in the Unity editor. * Removed various unused Recast code. * Removed support for forcing the inspector skin to be dark or light. The value provided by EditorGUIUtility.isProSkin is always used now. * Removed multiplication operator for Int3 with a Vector3 because it is a nonstandard operation on vectors (and it is not that useful). * Removed the since long deprecated example script AIFollow. * Removed the AdaptiveSampling algorithm for local avoidance. Only GradientDescent is used now. * Removed empty PostProcess method in NavMeshGraph. * Fixes * Fixed RichAI and AIPath trying to use CharacterControllers even if the CharacterController component was disabled. * Fixed rotated recast/navmesh graphs would ensure each node's vertices were laid out clockwise in XZ space instead of in graph space which could cause parts of the graph to become disconnected from the rest. * Fixed a bug where graphs could fail to be deserialized correctly if the graph list contained a null element * Fixed a bug where the json serializer could emit True/False instead of true/false which is the proper json formatting. * Fixed LayerGridGraphs' "max climb" setting not working properly with rotated graphs. * Fixed LayerGridGraphs' "character height" setting not working properly with rotated graphs. * Fixed LayerGridGraphs assuming there were no obstacles nearby if no ground was found. * Fixed DynamicObstacle getting caught in an infinite loop if there was no [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component in the scene when it was created. Thanks MeiChen for finding the bug. * Fixed NodeLink2 deserialization causing exceptions if the node hadn't linked to anything when it was serialized. Thanks Skalev for finding the bug. * Fixed the AlternativePath modifier could crash the pathfinding threads if it logged a warning since it used the Debug.Log(message,object) overload which can only be used from the Unity thread. * Fixed an issue where layer mask fields in graph editors would show 'Nothing' if they only included layers which had no name set. * Fixed potential memory leak. Paths in the path pool would still store the callback which is called when the path has been calculated which that means it would implicitly hold a reference to the object which had the method that would be called. Thanks sehee for pointing this out. * Fixed GridNode.ClosestPointOnNode could sometimes return the wrong y coordinate relative to the graph (in particular when the graph was rotated) and the y coordinate would not snap to the node's surface. * Fixed AstarData.AddGraph would fill \*all\* empty slots in the graph array with the graph instead of just the first. Thanks bitwise for finding the bug. * Improved compatibility with Unity 5.5 which was need due to the newly introduced UnityEngine.Profiling namespace. * Fixed graph updates on LayeredGridGraphs not respecting GraphUpdateObject.resetPenaltyOnPhysics. * Fixed potential memory leak when calling RecalculateCell on a layered grid graph. * LevelGridNode.ContainsConnection now reports correct values (previously it would only check non-grid connections). * Fixed not being able to deserialize settings saved with some old versions of the A\* [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) Project. * Tweaked ListPool to avoid returning lists with a very large capacity when a small one was requested as this could cause performance problems since Clear is O(n) where n is the capacity (not the size of the list). * Fixed GraphUpdateScene causing 'The Grid Graph is not scanned, cannot update area' to be logged when exiting play mode. * Fixed scanning a recast graph could in very rare circumstances throw a 'You are trying to pool a list twice' exception due to a multithreading race condition. * Fixed recast/navmesh graphs could return the wrong node as the closest one in rare cases, especially near tile borders. * Fixed another case of recast/navmesh graphs in rare cases returning the wrong node as the closest one. * Fixed gizmo drawing with 'Show Search Tree' enabled sometimes right after graph updates drawing nodes outside the search tree as if they were included in it due to leftover data from graph updates. * Fixed navmesh and recast graphs would unnecessarily be serialized by Unity which would slow down the inspector slightly. * Fixed AstarEnumFlagDrawer not working with private fields that used the \[SerializeField\] attribute. This does not impact anything that the A\* [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) Project used, but some users are using the AstarEnumFlagDrawer for other fields in their projects. Thanks Skalev for the patch. * Clicking 'Apply' in the Optimizations tab will now always refresh the UI instead of assuming that a recompilation will happen (it will not happen if only defines for other platforms than the current one were modified). * Fixed not being able to multi-edit RVOSquareObstacle components. * Fixed GridNode.ClearConnections(true) not removing all reversed connections and could sometimes remove the wrong ones. * Fixed TileHandlerHelper regularly checking for if an update needs to be done even if TileHandlerHelper.updateInterval was negative even though the documentation specifies that it should not do that (it only disabled updates when updateInterval = -1). * Fixed PathUtilities.GetPointsAroundPointWorld and PathUtilities.GetPointsAroundPoint returning incorrect results sometimes. * Fixed Path.immediateCallback not being reset to null when using path pooling. * TileHandlerHelper will now work even if Scan On Awake in A\* Inspector -> Settings is false and you are scanning the graph later. * Fixed AstarWorkItem.init could be called multiple times. * Fixed some documentation typos. * Fixed colliders being included twice in the recast rasterization if the GameObject had a RecastNavmeshModifier attached to it which effectively made RecastNavmeshModifier not work well at all with colliders. * Fixed inspector for RecastNavmeshModifier not updating if changes were done to the fields by a script or when an undo or redo was done. * Fixed SimpleSmoothModifier custom editor would sometimes set all instances of a field to the same value when editing multiple objects at the same time. * Fixed division by zero when the TimeScale was zero in the AstarDebugger class. Thanks Booil Jung for reporting the issue. * Various other small fixes in the AstarDebugger class. * Fixed division by zero when generating a recast graph and the cell size was much larger than the bounds of the graph. * Fixed the recast graph data structures could be invalid while a graph update was running in a separate thread. This could cause API calls like [AstarPath.GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) to throw exceptions. Now the affected tiles are recalculated in a separate thread and then the updates are applied to the existing graph in the Unity thread. * Fixed some cases where the AlternativePath modifier would apply penalties incorrectly and possibly crash the pathfinding thread. * Fixed IAgent.NeighbourCount would sometimes not be reset to 0 when the agent was locked and thus takes into account no other agents. * Fixed RVO threads would sometimes not be terminated which could lead to memory leaks if switching scenes a lot. * Fixed GridGraph.GetNearest and NavGraph.GetNearest not handling constraint=null. * Internal changes * These are changes to the internals of the system and will most likely not have any significant externally visible effects. * Removed some wrapper methods for the heap in the PathHandler class since they were just unnecessary. Exposed the heap field as readonly instead. * Renamed BinaryHeapM to BinaryHeap. * Renamed ExtraMesh to RasterizationMesh. * Refactored TileHandler.CutPoly to reduce code messiness and also fixed some edge case bugs. * Documentation * Among other things: improved the [Writing Graph Generators](https://arongranberg.com/astar/docs/writinggraphgenerators.html) guide (among other things it no longer uses hard to understand calculations to get the index of each node). * 3.8.8.1 (2017-01-12) * Fixes * Fixed the 'Optimization' tab sometimes logging errors when clicking Apply on Unity 5.4 and higher. * More UWP fixes (pro version only). * 3.8.8 (2017-01-11) * Fixes * Fixed errors when deploying for the Universal Windows Platform (UWP). This includes the Hololens platform. * It is no longer necessary to use the compiler directive ASTAR\_NO\_ZIP when deploying for UWP. zipping will be handled by the System.IO.Compression.ZipArchive class on those platforms (ZipArchive is not available on other platforms). If you have previously enabled ASTAR\_NO\_ZIP it will stay enabled to ensure compatibility. * Changed some comments from the '/\*\*<' format to '/\*\*' since Monodevelop shows the wrong docs when using the '/\*\*<' format. * 3.8.7 (2016-11-26) * Fixes * Improved compatibility with Unity 5.5 which was needed due to the newly introduced UnityEngine.Profiling namespace. * 3.8.6 (2016-10-31) * Upgrade Notes * Note that a few features and some fixes that have been available in the beta releases are not included in this version because they were either not ready to be released or depended on other changes that were not ready. * Dropped support for Unity 5.1. * Moved some things to inside the [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) namespace to avoid naming collisions with other packages. Make sure you have the line 'using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) ;' at the top of your scripts. * Seeker.StartMultiTargetPath will now also set the enabledTags and tagPenalties fields on the path. Similar to what StartPath has done. This has been the intended behaviour from the start, but bugs happen. See [http://forum.arongranberg.com/t/multitargetpath-doesnt-support-tag-constraints/2561/3](http://forum.arongranberg.com/t/multitargetpath-doesnt-support-tag-constraints/2561/3) * The JsonFx library is no longer used, so the Pathfinding.JsonFx.dll file in the plugins folder may be removed to reduce the build size a bit. UnityPackages cannot delete files, so you have to delete it manually. * RecastGraph.UpdateArea (along with a few other functions) is now explicitly implemented for the IUpdatableGraph interface as it is usually a bad idea to try to call those methods directly (use [AstarPath.UpdateGraphs](https://arongranberg.com/astar/docs/astarpath/updategraphs.html#UpdateGraphs3) instead). * [AstarPath.FlushWorkItems](https://arongranberg.com/astar/docs/astarpath/flushworkitems.html#FlushWorkItems) previously had pretty bad default values for the optional parameters. By default it would not necessarily complete all work items, it would just complete those that took a single frame. This is pretty much never what you actually want so to avoid confusion the default value has been changed. * New Features and Improvements * The JsonFx library is no longer used. Instead a very tiny json serializer and deserializer has been written. In addition to reducing code size and being slightly faster, it also means that users using Windows Phone no longer have to use the ASTAR\_NO\_JSON compiler directive. I do not have access to a windows phone however, so I have not tested to build it for that platform. If any issues arise I would appreciate if you post them in the forum. * Improved inspector for NavmeshCut. * NodeLink2 can now be used even when using cached startup or when loading serialized data in other ways just as long as the NodeLink2 components are still in the scene. * LevelGridNode now has support for custom non-grid connections (just like GridNode has). * Added GridNode.XCoordinateInGrid and GridNode.ZCoordinateInGrid. * Improved documentation for GraphUpdateShape a bit. * Changes * Removed EditorUtilities.GetMd5Hash since it was not used anywhere. * Deprecated TileHandler.GetTileType and TileHandler.GetTileTypeCount. * Seeker.StartPath now properly handles MultiTargetPath objects as well. * Seeker.StartMultiTargetPath is now deprecated. Note that it will now also set the enabledTags and tagPenalties fields on the path. Similar to what StartPath has done. * Removed GridGraph.bounds since it was not used or set anywhere. * GraphNode.AddConnection will now throw an ArgumentNullException if you try to call it with a null target node. * Made PointGraph.AddChildren and PointGraph.CountChildren protected since it makes no sense for them to be called by other scripts. * Changed how the 'Save & Load' tab looks to make it easier to use. * Renamed 'Path Debug Mode' to 'Graph Coloring' and 'Path Log Mode' to 'Path Logging' in the inspector. * RecastGraph.UpdateArea (along with a few other functions) is now explicitly implemented for the IUpdatableGraph interface as it is usually a bad idea to try to call those methods directly (use [AstarPath.UpdateGraphs](https://arongranberg.com/astar/docs/astarpath/updategraphs.html#UpdateGraphs3) instead). * Removed ConnectionType enum since it was not used anywhere. * Removed NodeDelegate and GetNextTargetDelegate since they were not used anywhere. * Fixes * Fixed TinyJson not using culture invariant float parsing and printing. This could cause deserialization errors on systems that formatted floats differently. * Fixed the EndingCondition example script. * Fixed speed being multiplied by Time.deltaTime in the AI script in the get started tutorial when it shouldn't have been. * Fixed FunnelModifier could for some very short paths return a straight line even though a corner should have been inserted. * Fixed typo. 'Descent' (as in 'Gradient Descent') was spelled as 'Decent' in some cases. Thanks Brad Grimm for finding the typo. * Fixed some documentation typos. * Fixed some edge cases in RandomPath and FleePath where a node outside the valid range of G scores could be picked in some cases (when it was not necessary to do so). * Fixed editor scripts in some cases changing the editor gui styles instead of copying them which could result in headers in unrelated places in the Unity UI had the wrong sizes. Thanks HP for reporting the bug. * Fixed NavmeshCut causing errors when cutting the navmesh if it was rotated upside down or scaled with a negative scale. * Fixed TriangleMeshNode.ClosestPointOnNodeXZ could sometimes return the wrong point (still on the node surface however). This could lead to characters (esp. when using the RichAI component) teleporting in rare cases. Thanks LordCecil for reporting the bug. * Fixed GridNodes not serializing custom connections. * Fixed nodes could potentially get incorrect graph indices assigned when additive loading was used. * Added proper error message when trying to call RecastGraph.ReplaceTile with a vertex count higher than the upper limit. * Known Bugs * Calling GetNearest when a recast graph is currently being updated on another thread may in some cases result in a null reference exception being thrown. This does not impact navmesh cutting. This bug has been present (but not discovered) in previous releases as well. * Calling GetNearest on point graphs with 'optimizeForSparseGraph' enabled may in some edge cases return the wrong node as being the closest one. It will not be widely off target though and the issue is pretty rare, so for real world use cases it should be fine. This bug has been present (but not discovered) in previous releases as well. * 3.8.3 through 3.8.5 were beta versions * 3.8.2 (2016-02-29) * Improvements * DynamicObstacle now handles rotation and scaling better. * Reduced allocations due to coroutines in DynamicObstacle. * Fixes * Fixed AstarPath.limitGraphUpdates not working properly most of the time. In order to keep the most common behaviour after the upgrade, the value of this field will be reset to false when upgrading. * Fixed DynamicObstacle not setting the correct bounds at start, so the first move of an object with the DynamicObstacle component could leave some nodes unwalkable even though they should not be. Thanks Dima for reporting the bug. * Fixed DynamicObstacle stopping to work after the GameObject it is attached to is deactivated and then activated again. * Fixed RVOController not working after reloading the scene due to the C# '??' operator not being equivalent to checking for '== null' (it doesn't use Unity's special comparison check). Thanks Khan-amil for reporting the bug. * Fixed typo in documentation for ProceduralGraphMover.floodFill. * Changes * Renamed 'Max Update Frequency' to 'Max Update Interval' in the editor since it has the unit \[second\], not \[1/second\]. * Renamed AstarPath.limitGraphUpdates to [AstarPath.batchGraphUpdates](https://arongranberg.com/astar/docs/astarpath.html#batchGraphUpdates) and AstarPath.maxGraphUpdateFreq to [AstarPath.graphUpdateBatchingInterval](https://arongranberg.com/astar/docs/astarpath.html#graphUpdateBatchingInterval) . Hopefully these new names are more descriptive. The documentation for the fields has also been improved slightly. * 3.8.1 (2016-02-17) * Improvements * The tag visualization mode for graphs can now use the custom list of colors that can be configured in the inspector. Thanks Arakade for the patch. * Fixes * Recast graphs now handle meshes and colliders with negative scales correctly. Thanks bvance and peted for reporting it. * Fixed GridGraphEditor throwing exceptions when a user had created a custom grid graph class which inherits from GridGraph. * Fixed Seeker.postProcessPath not being called properly. Instead it would throw an exception if the postProcessPath delegate was set to a non-null value. Thanks CodeSpeaker for finding the bug. * 3.8 (2016-02-16) * The last version released on the Unity Asset Store was 3.7, so if you are upgrading from that version check out the release notes for 3.7.1 through 3.7.5 as well. * Breaking Changes * For the few users that have written their own Path Modifiers. The 'source' parameter to the Apply method has been removed from the IPathModifier interface. You will need to remove that parameter from your modifiers as well. * Modifier priorities have been removed and the priorities are now set to sensible hard coded values since at least for the included modifiers there really is only one ordering that makes sense (hopefully there is no use case I have forgotten). This may affect your paths if you have used some other modifier order. Hopefully this change will reduce confusion for new users. * New Features and Improvements * Added NodeConnection mode to the StartEndModifier on the Seeker component. This mode will snap the start/end point to a point on the connections of the start/end node. Similar to the Interpolate mode, but more often does what you actually want. * SimpleSmoothModifier now has support for multi editing. * Added a new movement script called AILerp which uses linear interpolation to follow the path. This is good for games which want the agent to follow the path exactly and not use any physics like behaviour. This movement script works in both 2D and 3D. * Added a new 2D example scene which uses the new AILerp movement script. * All scripts now have a [HelpURLAttribute](http://docs.unity3d.com/ScriptReference/HelpURLAttribute.html) so the documentation button at the top left corner of every script inspector now links directly to the documentation. * Recast graphs can now draw the surface of a navmesh in the scene view instead of only the node outlines. Enable it by checking the 'Show mesh surface' toggle in the inspector. Drawing the surface instead of the node outlines is usually faster since it does not use Unity Gizmos which have to rebuild the mesh every frame. * Improved GUI for the tag mask field on the Seeker. * All code is now consistently formatted, utilising the excellent Uncrustify tool. * Added animated gifs to the [Recast graph](https://arongranberg.com/astar/docs/recastgraph.html#cellSize) documentation showing how some parameters change the resulting navmesh. If users like this, I will probably follow up and add similar gifs for variables in other classes. ![](https://arongranberg.com/astar/docs/images/recast/character_radius.gif) * Fixes * Fixed objects in recast graphs being rasterized with an 0.5 voxel offset. Note that this will change how your navmesh is rasterized (but usually for the better), so you may want to make sure it still looks good. * Fixed graph updates to navmesh and recast graphs not checking against the y coordinate of the bounding box properly (introduced in 3.7.5). * Fixed potential bug when loading graphs from a file and one or more of the graphs were null. * Fixed invalid data being saved when calling AstarSerializer.SerializeGraphs with an array that was not equal to the AstarData.graphs array. The AstarSerializer is mostly used internally (and internally it is always called with the AstarData.graphs array). Thanks munkman for reporting this. * Fixed incorrect documentation for GridNode.NodeInGridIndex. Thanks mfjk for reporting it! * Fixed typo in a recast graph log message (where -> were). Thanks bigdaddio for reporting it! * Fixed not making sure the file is writable before writing graph cache files (Perforce could sometimes make it read-only). Thanks Jørgen Tjernø for the patch. * Fixed RVOController always using FindObjectOfType during Awake, causing performance issues in large scenes. Thanks Jørgen Tjernø for the patch. * Removed QuadtreeGraph, AstarParallel, NavMeshRenderer and NavmeshController from the released version. These were internal dev files but due to typos they had been included in the release. It will also automatically refresh itself if the graph has been rescanned with a different number of tiles. * Fixed SimpleSmoothModifier not always including the exact start point of the path. * Fixed ASTAR\_GRID\_NO\_CUSTOM\_CONNECTIONS being stripped out of the final build, so that entry in the Optimizations tab didn't actually do anything. * Fixed performance issue with path pooling. If many paths were being calculated and pooled, the performance could be severely reduced unless ASTAR\_OPTIMIZE\_POOLING was enabled (which it was not by default). * Fixed 3 compiler warnings about using some deprecated Unity methods. * Changes * Recast graphs' 'Snap To Scene' button now snaps to the whole scene instead of the objects that intersect the bounds that are already set. This has been a widely requested change. Thanks Jørgen Tjernø for the patch. * Moved various AstarMath functions to the new class VectorMath and renamed some of them to reduce confusion. * Removed various AstarMath functions because they were either not used or they already exist in e.g Mathf or System.Math. DistancePointSegment2, ComputeVertexHash, Hermite, MapToRange, FormatBytes, MagnitudeXZ, Repeat, Abs, Min, Max, Sign, Clamp, Clamp01, Lerp, RoundToInt. * PathEndingCondition (used with XPath) is now abstract since it doesn't really make any sense to use the default implementation (always returns true). * A 'Recyle' method is no longer required on path classes (reduced boilerplate). * Removed old IFunnelGraph interface since it was not used by anything. * Removed old ConvexMeshNode class since it was not used by anything. * Removed old script NavmeshController since it has been disabled since a few versions. * Removed Int3.DivBy2, Int3.unsafeSqrMagnitude and Int3.NormalizeTo since they were not used anywere. * Removed Int2.sqrMagnitude, Int2.Dot since they were not used anywhere and are prone to overflow (use sqrMagnitudeLong/DotLong instead) * Deprecated Int2.Rotate since it was not used anywhere. * Deprecated Int3.worldMagnitude since it was not used anywhere. * 3.7.5 (2015-10-05) * Breaking changes * Graph updates to navmesh and recast graphs now also check that the nodes are contained in the supplied bounding box on the Y axis. If the bounds you have been using were very short along the Y axis, you may have to change them so that they cover the nodes they should update. * Improvements * Added GridNode.ClosestPointOnNode. * Optimized GridGraph.CalculateConnections by approximately 20%. This means slightly faster scans and graph updates. * Changes * Graph updates to navmesh and recast graphs now also check that the nodes are contained in the supplied bounding box on the Y axis. If the bounds you have been using were very short along the Y axis, you may have to change them so that they cover the nodes they should update. * Fixes * Fixed stack overflow exception when a pivot root with no children was assigned in the heuristic optimization settings. * Fixed scanning in the editor could sometimes throw exceptions on new versions of Unity. Exceptions contained the message "Trying to initialize a node when it is not safe to initialize any node". This happened because Unity changed the EditorGUIUtility.DisplayProgressBar function to also call OnSceneGUI and OnDrawGizmos and that interfered with the scanning. * Fixed paths could be returned with invalid nodes if the path was calculated right before a call to [AstarPath.Scan()](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) was done. This could result in the funnel modifier becoming really confused and returning a straight line to the target instead of avoiding obstacles. * Fixed sometimes not being able to use the Optimizations tab on newer versions of Unity. * 3.7.4 (2015-09-13) * Changes * AIPath now uses the cached transform field in all cases for slightly better performance. * Fixes * Fixed recast/navmesh graphs could in rare cases think that a point on the navmesh was in fact not on the navmesh which could cause odd paths and agents teleporting short distances. * Documentation Fixes * Fixed the Seeker class not appearing in the documentation due to a bug in Doxygen (documentation generator). * 3.7.3 (2015-08-18) * Fixed GridGraph->Unwalkable When No Ground used the negated value (true meant false and false meant true). This bug was introduced in 3.7 when some code was refactored. Thanks DrowningMonkeys for reporting it. * 3.7.2 (2015-08-06) * Fixed penalties not working on navmesh based graphs (navmesh graphs and recast graphs) due to incorrectly configured compiler directives. * Removed undocumented compiler directive ASTAR\_CONSTANT\_PENALTY and replaced with ASTAR\_NO\_TRAVERSAL\_COST which can strip out code handling penalties to get slightly better pathfinding performance (still not documented though as it is not really a big performance boost). * 3.7.1 (2015-08-01) * Removed a few cases where exceptions where needed to better support WebGL when exception handling is disabled. * Fixed MultiTargetPath could return the wrong path if the target of the path was the same as the start point. * Fixed MultiTargetPath could sometimes throw exceptions when using more than one pathfinding thread. * MultiTargetPath will now set path and vectorPath to the shortest path even if pathsForAll is true. * The log output for MultiTargetPath now contains the length (in nodes) of the shortest path. * Fixed RecastGraph throwing exceptions when trying to rasterize trees with missing (null) prefabs. Now they will simply be ignored. * Removed RecastGraph.bbTree since it was not used for anything (bbTrees are stored inside each tile since a few versions) * Improved performance of loading and updating large recast graph tiles (improved performance of internal AABB tree). * Removed support for the compiler directive ASTAR\_OLD\_BBTREE. * 3.7 (2015-07-22) * The last version that was released on the Unity Asset Store was version 3.6 so if you are upgrading from that version also check out the release notes for 3.6.1 through 3.6.7. * Upgrade notes * ProceduralGraphMover.updateDistance is now in nodes instead of world units since this value is a lot less world scale dependant. So the defaults should fit more cases. You may have to adjust it slightly. * Some old parts of the API that has been marked as deprecated long ago have been removed (see below). Some other unused parts of the API that mostly lead to confusion have been removed as well. * Improvements * Rewrote several documentation pages to try to explain concepts better and fixed some old code. * [Accessing graph data](https://arongranberg.com/astar/docs/accessingdata.html) * [Graph Updates during Runtime](https://arongranberg.com/astar/docs/graphupdates.html) * [Writing Graph Generators](https://arongranberg.com/astar/docs/writinggraphgenerators.html) * [Pathfinding.NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) * And some other smaller changes. * Added an overload of [Pathfinding.PathUtilities.IsPathPossible](https://arongranberg.com/astar/docs/pathutilities/ispathpossible.html#IsPathPossible3) which takes a tag mask. * [XPath](https://arongranberg.com/astar/docs/xpath.html) now works again. * The ProceduralGraphMover component now supports rotated graphs (and all other ways you can transform it, e.g isometric angle and aspect ratio). * Rewrote GridGraph.Linecast to be more accurate and more performant. Previously it used a sampling approach which could cut corners of obstacles slightly and was pretty inefficient. * Linted lots of files to remove trailing whitespace, fix imports, use 'var' when relevant and various other small tweaks. * Added AstarData.layerGridGraph shortcut. * Fixes * Fixed compilation errors for Windows Store. The errors mentioned ThreadPriority and VolatileRead. * Fixed LayerGridGraph.GetNearest sometimes returning the wrong node inside a cell (e.g sometimes it would always return the node with the highest y coordinate). This did not happen when the node size was close to 1 and the grid was positioned close to the origin. Which it of course was in all my tests (tests are improved now). * Fixed GridGraph.Linecast always returning false (no obstacles) when the start point and end point was the same. Now it returns true (obstacle) if the start point was inside an obstacle which makes more sense. * Linecasts on layered grid graphs now use the same implementation as the normal grid graph. This fixed a TON of bugs. If you relied on the old (buggy) behaviour you might have to change your algorithms a bit. It will now report more accurate hit information as well. * Fixed documentation on LayerGridGraph.Linecast saying that it would return false if there was an obstacle in the way when in fact exactly the opposite was true. * Fixed inspector GUI throwing exceptions when two or more grid graphs or layered grid graphs were visible and thickRaycast was enabled on only one of them. * Fixed a few options only relevant for grid graphs were visible in the layered grid graph inspector as well. * Fixed GridGraph.CheckConnection returned the wrong result when neighbours was Four and dir was less than 4. * All compiler directives in the Optimizations tab are now tested during the package build phase. So hopefully none of them should give compiler errors now. * Improved accuracy of intellisense. * Fixed the editor sometimes incorrectly comparing versions which could cause the 'New Update' window to appear even though no new version was available. * Changes * Removed code only necessary for compatibility with Unity 4.5 and lower. * Removed a lot of internal unused old code. * Renamed GridGraph.GetNodePosition to GridGraph.GraphPointToWorld to avoid confusion. * Renamed 3rd party plugin license files to prevent the Unity Asset Store from detecting those as the license for the whole package. * Changed Seeker.traversableTags to be a simple int instead of a class. * GridNode and LevelGridNode now inherit from a shared base class called GridNodeBase. * Removed support for the compiler directive ConfigureTagsAsMultiple since it was not supported by the whole codebase and it was pretty old. * Marked a few methods in AstarData as deprecated since they used strings instead of types. If string to type conversion is needed it should be done elsewhere. * Removed some methods which have been marked as obsolete for a very long time. * AstarData.GetNode * PathModifier and MonoModifier.ApplyOriginal * Some old variants of PathModifier.Apply * GridGeneratorEditor.ResourcesField * Int3.safeMagnitude and safeSqrMagnitude * GraphUpdateUtilities.IsPathPossible (this has been since long been moved to the PathUtilities class) * All constructors on path classes. The static Construct method should be used instead since that can handle path pooling. * GraphNode.Position, walkable, tags, graphIndex. These had small changes made to their names (if they use upper- or lowercase letters) a long time ago. (for better or for worse, but I want to avoid changing the names now again to avoid breaking peoples' code) * GridNode.GetIndex. * Removed the Node class which has been marked as obsolete a very long time. This class has been renamed to GraphNode to avoid name conflicts. * Removed LocalAvoidanceMover which has been marked as obsolete a very long time. The RVO system has replaced it. * Removed Seeker.ModifierPass.PostProcessOriginal since it was not used. This also caused Seeker.postProcessOriginalPath to be removed. * Removed support for ASTAR\_MORE\_PATH\_IDS because it wasn't really useful, it only increased the memory usage. * Removed Path.height, radius, turnRadius, walkabilityMask and speed since they were dummy variables that have not been used and are better implemented using inheritance anyway. This is also done to reduce confusion for users. * Removed the old local avoidance system which has long since been marked as obsolete and replaced by the RVO based system. * 3.6.7 (2015-06-08) * Fixes * Fixed a race condition when OnPathPreSearch and OnPathPostSearch were called. When the AlternativePath modifier was used, this could cause the pathfinding threads to crash with a null reference exception. * 3.6.6 (2015-05-27) * Improvements * Point Graphs are now supported when using ASTAR\_NO\_JSON. * The Optimizations tab now modifies the player settings instead of changing the source files. This is more stable and your settings are now preserved even when you upgrade the system. * The Optimizations tab now works regardless of the directory you have installed the package in. Hopefully the whole project is now directory agnostic, but you never know. * Changes * Switched out OnVoidDelegate for System.Action. You might get a compiler error because of this (for the few that use it) but then just rename your delegate to System.Action. * Fixes * Fixed recast graphs not saving all fields when using ASTAR\_NO\_JSON. * 3.6.5 (2015-05-19) * Fixes * Fixed recast graphs generating odd navmeshes on non-square terrains. * Fixed serialization sometimes failing with the error 'Argument cannot be null' when ASTAR\_NO\_JSON was enabled. * The 'Walkable Climb' setting on recast graphs is now clamped to be at most equal to 'Walkable Height' because otherwise the navmesh generation can fail in some rare cases. * Changes * Recast graphs now show unwalkable nodes with a red outline instead of their normal colors. * 3.6.4 (2015-04-19) * Fixes * Improved compatibility with WIIU and other big-endian platforms. * 3.6.3 (2015-04-19) * Fixes * Fixed RVONavmesh not adding obstacles correctly (they were added added, but all agents ignored them). * 3.6.2 (2015-04-14) * Fixes * Fixed null reference exception in the PointGraph OnDrawGizmos method. * Fixed a few example scene errors in Unity 5. * 3.6.1 (2015-04-06) * Upgrade notes: * The behaviour of NavGraph.RelocateNodes has changed. The oldMatrix was previously treated as the newMatrix and vice versa so you might need to switch the order of your parameters if you are calling it. * Highlights: * Works in WebGL/IL2CPP (Unity 5.0.0p3). At least according to my limited tests. * Implemented RelocateNodes for recast graphs (however it cannot be used on tiled recast graphs). * Added support for hexagon graphs. Enable it by changing the 'Connections' field on a grid graph to 'Six'. * Fixed AstarData.DeserializeGraphsAdditive (thanks tmcsweeney). * Fixed pathfinding threads sometimes not terminating correctly. This would show up as a 'Could not terminate pathfinding thread...' error message. * Added a version of GridGraph.RelocateNodes which takes grid settings instead of a matrix for ease of use. * Changes: * Removed NavGraph.SafeOnDestroy * Removed GridGraph.scans because it is a pretty useless variable. * Removed NavGraph.CreateNodes (and overriden methods) since they were not used. * Made GridGraph.RemoveGridGraphFromStatic private. * Removed NavMeshGraph.DeserializeMeshNodes since it was not used. * Made Seeker.lastCompletedVectorPath, lastCompletedNodePath, OnPathComplete, OnMultiPathComplete, OnPartialPathComplete private since they really shouldn't be used by other scripts. * Removed Seeker.saveGetNearestHints, Seeker.startHint, Seeker.endHint, Seeker.DelayPathStart since they were not used. * Removed unused methods of little use: AstarData.GuidToIndex and AstarData.GuidToGraph. * Removed RecastGraph.vertices and RecastGraph.vectorVertices since they were obsolete and not used. * Removed some old Unity 4.3 and Unity 3 compatibility code. * Recast graphs' 'Snap to scene' button now takes into account the layer mask and the tag mask when snapping, it now also checks terrains and colliders instead of just meshes (thanks Kieran). * Fixes: * Fixed RecastGraph bounds gizmos could sometimes be drawn with the wrong color. * Fixed a rare data race which would cause an exception with the message 'Trying to initialize a node when it is not safe to initialize any nodes' to be thrown * Tweaked Undo behaviour, should be more stable now. * Fixed grid graph editor changing the center field very little every frame (floating point errors) causing an excessive amount of undo items to be created. * Reduced unecessary dirtying of the scene (thanks Ben Hymers). * Fixed RVOCoreSimulator.WallThickness (thanks tmcsweeney). * Fixed recast graph not properly checking for the case where an object had a MeshFilter but no Renderer (thanks 3rinJax). * Fixed disabling ASTAR\_RECAST\_ARRAY\_BASED\_LINKED\_LIST (now ASTAR\_RECAST\_CLASS\_BASED\_LINKED\_LIST) would cause compiler errors. * Fixed recast graphs could sometimes voxelize the world incorrectly and the resulting navmesh would have artifacts. * Fixed graphMask code having been removed from the free version in some cases due to old code which treated it as a pro only feature. * Improved compatibility with Xbox One. * Fixed RVOController layer field not working when multiple agents were selected. * Fixed grid nodes not being able to have custom connections in the free version. * Fixed runtime error on PS4. * 3.6 (2015-02-02) * Upgrade notes: * Cache data for faster startup is now stored in a separate file. This reduces the huge lag some users have been experiencing since Unity changed their Undo system. You will need to open the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) components which used cached startup, go to the save and load tab and press a button labeled "Transfer cache data to a separate file". * Highlights: * Added support for the Jump Point Search algorithm on grid graphs (pro only). The JPS algorithm can be used to speed up pathfinding on grid graphs \*without any penalties or tag weights applied\* (it only works on uniformly weighted graphs). It can be several times faster than normal A\*. It works best on open areas. * Added support for heuristic optimizations (pro only). This can be applied on any static graph, i.e any graph which does not change. It requires a rather slow preprocessing step so graph updates will be really slow when using this. However when the preprocessing is done, it can speed up pathfinding with an order of magnitude. It works especially well in mazes with lots of options and dead ends. Combined with JPS (mentioned above) I have seen it perform up to 20x better than regular A\* with no heuristic optimizations. * Added PointNode.gameObject which will contain the GameObject each node was created from. * Added support for RVO obstacles. It is by no means perfect at this point, but at least it works. * Undo works reasonably well again. It took a lot of time working around weird Unity behaviours. For example Unity seems to send undo events when dragging items to object fields (why? no idea). * Dragging meshes to the NavmeshGraph.SourceMesh field works again. See fix about undo above. * Extended the max number of possible areas (connected components) to 2^17 = 131072 up from 2^10 = 1024. No memory usage increase, just shuffling bits around. Deprecated compiler directive ASTAR\_MORE\_AREAS * Extended the max number of graphs in the inspector to 256 up from 4 or 32 depending on settings. No memory usage increase, just shuffling bits around. I still don't recommend that you actually use this many graphs. * Added RecastTileUpdate and RecastTileUpdateHandler scripts for easier recast tile updating with good performance. * When using A\* Inspector -> Settings -> Debug -> Path Debug Mode = {G,F,H,Penalties} you previously had to set the limits for what should be displayed as "red" in the scene view yourself, this is now optionally automatically calculated. The UI for it has also been improved. * Improvements: * Added penaltyAnglePower to Grid Graph -> Extra -> Penalty from Angle. This can be used to increase the penalty even more for large angles than for small angles (more than it already does, that is). * ASTAR\_NO\_JSON now works for recast graphs as well. * Added custom inspector for RecastNavmeshModifier, hopefully it will not be as confusing anymore. * Changes: * FleePath now has a default flee strength of 1 to avoid confusion when the FleePath doesn't seem to flee from anything. * Removed some irrelevant defines from the Optimizations tab. * IAgent.Position cannot be changed anymore, instead use the Teleport and SetYPosition methods. * Exposed GraphUpdateObject.changedNodes. * Deprecated the threadSafe paremeter on RegisterSafeUpdate, it is always treated as true now. * The default value for AstarPath.minAreaSize is now 0 since the number of areas (connected component) indices has been greatly increased (see highlights). * Tweaked ProceduralWorld script (used for the "Procedural" example scene) to reduce FPS drops. * Fixes: * [AstarPath.FlushGraphUpdates](https://arongranberg.com/astar/docs/astarpath/flushgraphupdates.html#FlushGraphUpdates) will now complete all graph updates instead of just making sure they have started. In addition to avoiding confusion, this fixes a rare null reference exception which could happen when using the GraphUpdateUtilities.UpdateGraphsNoBlock method. * Fixed some cases where updating recast graphs could throw exceptions. (message begun with "No Voxelizer object. UpdateAreaInit...") * Fixed typo in RVOSimulator. desiredSimulatonFPS -> desiredSimulationFPS. * RVO agents move smoother now (previously their velocity could change widely depending on the fps, the average velocity was correct however) * Fixed an exception which could, with some graph settings, be thrown when deserializing on iPhone when bytecode stripping was enabled. * Fixed a NullReferenceException in MultiTargetPath which was thrown if the path debug mode was set to "Heavy". * Fixed PathUtilies.BFS always returning zero nodes (thanks Ajveach). * Made reverting GraphUpdateObjects work. The GraphUpdateUtilities.UpdateGraphsNoBlock was also fixed by this change. * Fixed compile error with monodevelop. * Fixed a bug which caused scanning to fail if more than one NavmeshGraph existed. * Fixed the lightweight local avoidance example scene which didn't work previously. * Fixed SimpleSmoothModifier not exposing Roundness Factor in the editor for the Curved Nonuniform mode. * Fixed an exception when updating RecastGraphs and using RelevantGraphSurfaces and multithreading. * Fixed exceptions caused by starting paths from other threads than the Unity thread. * Fixed an infinite loop/out of memory exception that could occur sometimes when graph updates were being done at the start of the game (I hate multithreading race conditions). * Fixed the Optimizations tab not working when JS Support was enabled. * Fixed graph updating not working on navmesh graphs (it was broken before due to a missing line of code). * Fixed some misspelled words in the documentation. * Removed some unused and/or redundant variables. * Fixed a case where graphs added using code might not always be configured correctly (and would throw exceptions when scanning). * Improved Windows Store compatibility. * Fixed a typo in the GridGraph which could cause compilation to fail when building for Windows Phone or Windows Store (thanks MariuszP) * Lots of code cleanups and comments added to various scripts. * Fixed some cases where MonoDevelop would pick up the wrong documention for fields since it doesn't support all features that Doxygen supports. * Fixed a bug which caused the points field on GraphUpdateScene to sometimes not be editable. * Fixed a bug which could cause RVO agents not to move if the fps was low and Interpolation and Double Buffering was used. * Set the execution order for RVOController and RVOSimulator to make sure that other scripts will get the latest position in their Update method. * Fixed a bug which could cause some nearest point on line methods in AstarMath to return NaN. This could happen when Seeker->Start End Modifier->StartPoint and EndPoint was set to Interpolate. * Fixed a runtime error on PS Vita. * Fixed an index out of range exception which could occur when scanning LayeredGridGraphs. * Fixed an index out of range exception which could occur when drawing gizmos for a LayeredGridGraph. * Fixed a bug which could cause ProduralGridMover to update the graph every frame regardless of if the target moved or not (thanks Makak for finding the bug). * Fixed a number of warnings in Unity 5. * 3.5.9.7 (3.6 beta 6, 2015-01-28) * 3.5.9.6 (3.6 beta 5, 2015-01-28) * 3.5.9.5 (3.6 beta 4, 2015-01-27) * 3.5.9.1 (3.6 beta 3, 2014-10-14) * 3.5.9 (3.6 beta 2, 2014-10-13) * 3.5.8 (3.6 beta 1) * See release notes for 3.6 * 3.5.2 (2013-09-01) (tiny bugfix and small feature release) * Added isometric angle option for grid graphs to help with isometric 2D games. * Fixed a bug with the RVOAgent class which caused the LightweightRVO example scene to not work as intended (no agents were avoiding each other). * Fixed some documentation typos. * Fixed some compilations errors some people were having with other compilers than Unity's. * 3.5.1 (2014-06-15) * Added avoidance masks to local avoidance. Each agent now has a layer and each agent can specify which layers it will avoid. * 3.5 (2014-06-12) * Added back local avoidance!! The new system uses a sampling based algorithm instead of a geometric one. The API is almost exactly the same so if you used the previous system this will be a drop in replacement. As for performance, it is roughly the same, maybe slightly worse in high density situations and slightly better in less dense situations. It can handle several thousand agents on an i7 processor. Obstacles are not yet supported, but they will be added in a future update. * Binary heap switched out for a 4-ary heap. This improves pathfinding performances by about 5%. * Optimized scanning of navmesh graphs (not the recast graphs) Large meshes should be much faster to scan now. * Optimized BBTree (nearest node lookup for navmesh/recast graphs, pro version only) Nearest node queries on navmesh/recast graphs should be slightly faster now. * Minor updates to the documentation, esp. to the GraphNode class. * 3.4.0.7 * Vuforia test build * 3.4.0.6 * Fixed an issue where serialization could on some machines sometimes cause an exception to get thrown. * Fixed an issue where the recast graph would not rasterize terrains properly near the edges of it. * Added PathUtilities.BFS. * Added PathUtilities.GetPointsAroundPointWorld. * 3.4.0.5 * Added offline documentation (Documentation.zip) * Misc fixes for namespace conflicts people have been having. This should improve compatibility with other packages. You might need to delete the AstarPathfindingProject folder and reimport the package for everything to work. * 3.4.0.4 * Removed RVOSimulatorEditor from the free version, it was causing compiler errors. * Made PointGraph.nodes public. * 3.4.0.3 * Removed Local Avoidance due to licensing issues. Agents will fall back to not avoiding each other. I am working to get the local avoidance back as soon as possible. * 3.4.0.2 * Unity Asset Store forced me to increase version number. * 3.4.0.1 * Fixed an ArrayIndexOutOfBounds exception which could be thrown by the ProceduralGraphMover script in the Procedural example scene if the target was moved too quickly. * The project no longer references assets from the Standard Assets folder (the package on the Unity Asset Store did so by mistake before). * 3.4 * Fixed a null reference exception when scanning recast graphs and rasterizing colliders. * Removed duplicate clipper\_library.dll which was causing compiler errors. * Support for 2D Physics collision testing when using Grid Graphs. * Better warnings when using odd settings for Grid Graphs. * Minor cleanups. * Queued graph updates are no longer being performed when the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) object is destroyed, this just took time. * Fixed a bug introduced in 3.3.11 which forced grid graphs to be square in Unity versions earlier than 4.3. * Fixed a null reference in BBTree ( used by RecastGraph). * Fixed NavmeshGraph not rebuilding BBTree on cached start (causing performance issues on larger graphs). * Includes all changes from the beta releases below * Beta 3.3.14 ( available for everyone! ) * All dlls are now in namespaces (e.g Pathfinding.Ionic.Zip instead of just Ionic.Zip ) to avoid conflicts with other packages. * Most scripts are now in namespaces to avoid conflicts with other packages. * GridNodes now support custom connections. * Cleanups, preparing for release. * Reverted to using an Int3 for GraphNode.position instead of an abstract Position property, the tiny memory gains were not worth it. * Beta 3.3.13 ( 4.3 compatible only ) * Fixed an issue where deleting a NavmeshCut component would not update the underlaying graph. * Better update checking. * Beta 3.3.12 ( 4.3 compatible only ) * Fixed an infinite loop which could happen when scanning graphs during runtime ( not the first scan ). * NodeLink component is now working correctly. * Added options for optimizations to the PointGraph. * Improved TileHandler and navmesh cutting. * Fixed rare bug which could mess up navmeshes when using navmesh cutting. * Beta 3.3.11 ( 4.3 compatible only ) * Fixed update checking. A bug has caused update checking not to run unless you had been running a previous version in which the bug did not exist. I am not sure how long this bug has been here, but potentially for a very long time. * Added an update notification window which pops up when there is a new version of the A\* [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) Project. * Lots of UI fixes for Unity 4.3 * Lots of other UI fixes and imprements. * Fixed gravity for RichAI. * Fixed Undo for Unity 4.3 * Added a new example scene showing a procedural environment. * Beta 3.3.10 * Removed RecastGraph.includeOutOfBounds. * Fixed a few bugs when updating Layered Grid Graphs causing incorrect connections to be created, and valid ones to be left out. * Fixed a null reference bug when removing RVO agents. * Fixed memory leaks when deserializing graphs or reloading scenes. * Beta 3.3.9 * Added new tutorial page about recast graphs. * Recast Graph: Fixed a bug which could cause vertical surfaces to be ignored. * Removed support for C++ Recast. * Fixed rare bug which could mess up navmeshes when using navmesh cutting. * Improved TileHandler and navmesh cutting. * GraphModifiers now take O(n) (linear) time to destroy at end of game instead of O(n^2) (quadratic). * RecastGraph now has a toggle for using tiles or not. * Added RelevantGraphSurface which can be used with RecastGraphs to prune away non-relevant surfaces. * Removed RecastGraph.accurateNearestNode since it was not used anymore. * Added RecastGraph.nearestSearchOnlyXZ. * RecastGraph now has support for removing small areas. * Added toggle to show or hide connections between nodes on a recast graph. * PointNode has some graph searching methods overloaded specially. This increases performance and reduces alloacations when searching point graphs. * Reduced allocations when searching on RecastGraph. * Reduced allocations in RichAI and RichPath. Everything is pooled now, so for most requests no allocations will be done. * Reduced allocations in general by using "yield return null" instead of "yield return 0" * Fixed teleport for local avoidance agents. Previously moving an agent from one position to another could cause it to interpolate between those two positions for a brief amount of time instead of staying at the second position. * Beta 3.3.8 * Nicer RichAI gizmo colors. * Fixed RichAI not using raycast when no path has been calculated. * Beta 3.3.7 * Fixed stack overflow exception in RichPath * Fixed RichPath could sometimes generate invalid paths * Added gizmos to RichAI * Beta 3.3.6 * Fixed node positions being off by half a node size. GetNearest node queries on grid graphs would be slightly inexact. * Fixed grid graph updating could get messed up when using erosion. * ... among other things, see below * Beta 3.3.5 and 3.3.6 * Highlights * Rewritten graph nodes. Nodes can now be created more easily (less overhead when creating nodes). * Graphs may use their custom optimized memory structure for storing nodes. * Performance improvements for scanning recast graphs. * Added a whole new AI script. RichAI (and the class RichPath for some things): This script is intended for navmesh based graphs and has features such as: * Guarantees that the character stays on the navmesh * Minor deviations from the path can be fixed without a path recalculation. * Very exact stop at endpoint (seriously, precision with something like 7 decimals). No more circling around the target point as with AIPath. * Does not use path modifiers at all (for good reasons). It has an internal funnel modifier however. * Simple wall avoidance to avoid too much wall hugging. * Basic support for off-mesh links (see example scene). * Improved randomness for RandomPath and FleePath, all nodes considered now have an equal chance of being selected. * Recast now has support for tiles. This enabled much larger worlds to be rasterized (without OutOfMemory errors) and allows for dynamic graph updates. Still slow, but much faster than a complete recalculation of the graph. * Navmesh Cutting can now be done on recast graphs. This is a kind of (relatively) cheap graph updating which punches a hole in the navmesh to make place for obstacles. So it only supports removing geometry, not adding it (like bridges). This update is comparitively fast, and it makes real time navmesh updating possible. See video: [http://youtu.be/qXi5qhhGNIw](http://youtu.be/qXi5qhhGNIw) . * Added RecastNavmeshModifier which can be attached to any GameObject to include that object in recast rasterization. It exposes more options and is also faster for graph updates with logarithmic lookup complexity instead of linear (good for larger worlds when doing graph updating). * Reintroducing special connection costs for start and end nodes. Before multithreading was introduced, pathfinding on navmesh graphs could recalculate the connection costs for the start and end nodes to take into account that the start point is not actually exactly at the start node's position (triangles are usually quite a larger than the player/npc/whatever). This didn't work with multithreading however and could mess up pathfinding, so it was removed. Now it has been reintroduced, working with multithreading! This means more accurate paths on navmeshes. * Added several methods to pick random points (e.g for group movement) to Pathfinding.PathUtlitilies. * Added RadiusModifier. A new modifier which can offset the path based on the character radius. Intended for navmesh graphs which are not shrinked by the character radius at start but can be used for other purposes as well. * Improved GraphUpdateScene gizmos. Convex gizmos are now correctly placed. It also shows a bounding box when selected (not showing this has confused a lot of people). * AIPath has gotten some cleanups. Among other things it now behaves correctly when disabled and then enabled again making it easy to pool and reuse (should that need arise). * Funnel modifier on grid graphs will create wider funnels for diagonals which results in nicer paths. * If an exception is thrown during pathfinding, the program does no longer hang at quit. * Split Automatic thread count into Automatic High Load and Automatic Low Load. The former one using a higher number of thread. * Thread count used is now shown in the editor. * GridGraph now supports ClosestOnNode (StartEndModifier) properly. SnapToNode gives the previous behaviour on GridGraphs (they were identical before). * New example scene Door2 which uses the NavmeshCut component. * Fixes * Fixed spelling error in GridGraph.uniformWidthDepthGrid. * Erosion radius (character radius, recast graphs) could become half of what it really should be in many cases. * RecastGraph will not rasterize triggers. * Fixed recast not being able to handle multiple terrains. * Fixed recast generating an incorrect mesh for terrains in some cases (not the whole terrain was included). * Linecast on many graph types had incorrect descriptions saying that the function returns true when the line does not intersect any obstacles, it is actually the other way around. Descriptions corrected. * The list of nodes returned by a ConstantPath is now guaranteed to have no duplicates. * Many recast constants are now proper constants instead of static variables. * Fixed bug in GridNode.RemoveGridGraph which caused graphs not being cleaned up correctly. Could cause problems later on. * Fixed an ArgumentOutOfRange exception in ListPool class. * RelocateNodes on NavMeshGraph now correctly recalculates connection costs and rebuilds the internal query tree (thanks peted on the forums). * Much better member documentation for RVOController. * Exposed MaxNeighbours from IAgent to RVOController. * Fixed AstarData.UpdateShortcuts not being called when caching was enabled. This caused graph shortcuts such as AstarPath.astarData.gridGraph not being set when loaded from a cache. * RVOCoreSimulator/RVOSimulator now cleans up the worker threads correctly. * Tiled recast graphs can now be serialized. * Changes * Renamed Modifier class to PathModifier to avoid naming conflicts with user scripts and other packages. * Cleaned up recast, put inside namespace and split into multiple files. * ListPool and friends are now threadsafe. * Removed Polygon.Dot since the Vector3 class already contains such a method. * The Scan functions now use callbacks for progress info instead of IEnumerators. Graphs can now output progress info as well. * Added [Pathfinding.NavGraph.CountNodes](https://arongranberg.com/astar/docs/navgraph/countnodes.html#CountNodes) function. * Removed GraphHitInfo.success field since it was not used. * GraphUpdateScene will now fall back to collider.bounds or renderer.bounds (depending on what is available) if no points are defined for the shape. * [AstarPath.StartPath](https://arongranberg.com/astar/docs/astarpath/startpath.html#StartPath) now has an option to put the path in the front of the queue to prioritize its calculation over other paths. * Time.fixedDeltaTime by Time.deltaTime in AIPath.RotateTowards() to work with both FixedUpdate and Update. (Thanks Pat\_AfterMoon) You might have to configure the turn speed variable after updating since the actual rotation speed might have changed a bit depending on your settings. * Fixed maxNeighbourDistance not being used correctly by the RVOController script. It would stay at the default value. If you have had trouble getting local avoidance working on world with a large scale, this could have been the problem. (Thanks to Edgar Sun for providing a reproducible example case) * Graphs loaded using DeserializeGraphsAdditive will get their graphIndex variables on the nodes set to the correct values. (thanks peted for noticing the bug). * Fixed a null reference exception in MultiTargetPath (thanks Dave for informing me about the bug). * GraphUpdateScene.useWorldSpace is now false per default. * If no log output is disabled and we are not running in the editor, log output will be discarded as early as possible for performance. Even though in theory log output could be enabled between writing to internal log strings and deciding if log output should be written. * NavGraph.inverseMatrix is now a field, not a property (for performance). All writes to matrix should be through the SetMatrix method. * StartEndModifier now uses ClosestOnNode for both startPoint and endPoint by default. * Known bugs * Linecasting on graphs is broken at the moment. (working for recast/navmesh graph atm. Except in very special cases) * RVONavmesh does not work with tiled recast graphs. * 3.2.5.1 * Fixes * Pooling of paths had been accidentally disabled in AIPath. * 3.2.5 * Changes * Added support for serializing dictionaries with integer keys via a Json Converter. * If drawGizmos is disabled on the seeker, paths will be recycled instantly. This will show up so that if you had a seeker with drawGizmos=false, and then enable drawGizmos, it will not draw gizmos until the next path request is issued. * Fixes * Fixed UNITY\_4\_0 preprocesor directives which were indented for UNITY 4 and not only 4.0. Now they will be enabled for all 4.x versions of unity instead of only 4.0. * Fixed a path pool leak in the Seeker which could cause paths not to be released if a seeker was destroyed. * When using a non-positive maxDistance for point graphs less processing power will be used. * Removed unused 'recyclePaths' variable in the AIPath class. * NullReferenceException could occur if the Pathfinding.Node.connections array was null. * Fixed NullReferenceException which could occur sometimes when using a MultiTargetPath (Issue #16) * Changed Ctrl to Alt when recalcing path continously in the Path Types example scene to avoid clearing the points for the MultiTargetPath at the same time (it was also using Ctrl). * Fixed strange looking movement artifacts during the first few frames when using RVO and interpolation was enabled. * AlternativePath modifier will no longer cause underflows if penalties have been reset during the time it was active. It will now only log a warning message and zero the penalty. * Added [Pathfinding.GraphUpdateObject.resetPenaltyOnPhysics](https://arongranberg.com/astar/docs/graphupdateobject.html#resetPenaltyOnPhysics) (and similar in GraphUpdateScene) to force grid graphs not to reset penalties when updating graphs. * Fixed a bug which could cause pathfinding to crash if using the preprocessor directive ASTAR\_NoTagPenalty. * Fixed a case where StartEndModifier.exactEndPoint would incorrectly be used instead of exactStartPoint. * AlternativePath modifier now correctly resets penalties if it is destroyed. * 3.2.4.1 * Unity Asset Store guys complained about the wrong key image. I had to update the version number to submit again. * 3.2.4 * Highlights * RecastGraph can now rasterize colliders as well! * RecastGraph can rasterize colliders added to trees on unity terrains! * RecastGraph will use Graphics.DrawMeshNow functions in Unity 4 instead of creating a dummy GameObject. This will remove the annoying "cleaning up leaked mesh object" debug message which unity would log sometimes. The debug mesh is now also only visible in the Scene View when the A\* object is selected as that seemed most logical to me (don't like this? post something in the forum saying you want a toggle for it and I will implement one). * GraphUpdateObject now has a [toggle](https://arongranberg.com/astar/docs/graphupdateobject.html#updateErosion) specifying if erosion (on grid graphs) should be recalculated after applying the guo. This enables one to add walkable nodes which should have been made unwalkable by erosion. * Made it a bit easier (and added more correct documentation) to add custom graph types when building for iPhone with Fast But No Exceptions (see iPhone page). * Changes * RecastGraph now only rasterizes enabled MeshRenderers. Previously even disabled ones would be included. * Renamed RecastGraph.includeTerrain to RecastGraph.rasterizeTerrain to better match other variable naming. * Fixes * AIPath now resumes path calculation when the component or GameObject has been disabled and then reenabled. * 3.2.3 (free version mostly) * Fixes * A UNITY\_IPHONE directive was not included in the free version. This caused compilation errors when building for iPhone. * Changes * Some documentation updates * 3.2.2 * Changes * Max Slope in grid graphs is now relative to the graph's up direction instead of world up (makes more sense I hope) * Note * Update really too small to be an update by itself, but I was updating the build scripts I use for the project and had to upload a new version because of technical reasons. * 3.2.1 * Fixes * Fixed bug which caused compiler errors on build (player, not in editor). * Version number was by mistake set to 3.1 instead of 3.2 in the previous version. * 3.2 * Highlights * A complete Local Avoidance system is now included in the pro version! * Almost every allocation can now be pooled. Which means a drastically lower allocation rate (GC get's called less often). * Initial node penalty per graph can now be set. Custom graph types implementing CreateNodes must update their implementations to properly assign this value. * GraphUpdateScene has now many more tools and options which can be used. * Added [Pathfinding.PathUtilities](https://arongranberg.com/astar/docs/pathutilities.html) which contains some usefull functions for working with paths and nodes. * Added Pathfinding.Node.GetConnections to enable easy getting of all connections of a node. The Node.connections array does not include custom connections which for example grid graphs use. * Seeker.PostProcess function was added for easy postprocessing of paths calculated without a seeker. * AstarPath.WaitForPath. Wait (block) until a specific path has been calculated. * Path.WaitForPath. Wait using a coroutine until a specific path has been calculated. * LayeredGridGraph now has support for up to 65535 layers (theoretically, but don't try it as you would probably run out of memory) * Recast graph generation is now up to twice as fast! * Fixed some UI glitches in Unity 4. * Debugger component has more features and a slightly better layout. * Fixes * Fixed a bug which caused the SimpleSmoothModifier with uniformSegmentLength enabled to skip points sometimes. * Fixed a bug where importing graphs additively which had the same GUID as a graph already loaded could cause bugs in the inspector. * Fixed a bug where updating a GridGraph loaded from file would throw a NullReferenceException. * Fixed a bug which could cause error messages for paths not to be logged * Fixed a number of small bugs related to updating grid graphs (especially when using erosion as well). * Overflows could occur in some navmesh/polygon math related functions when working with Int3s. This was because the precision of them had recently been increased. Further down the line this could cause incorrect answers to GetNearest queries. Fixed by casting to long when necessary. * Navmesh2.shader defined "Cull Off" twice. * [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) threads are now background threads. This will prevent them from blocking the process to terminate if they of some reason are still alive (hopefully at least). * When really high penalties are applied (which could be underflowed negative penalties) a warning message is logged. Really high penalties (close to max uint value) can otherwise cause overflows and in some cases infinity loops because of that. * ClosestPointOnTriangle is now spelled correctly. * MineBotAI now uses Update instead of FixedUpdate. * Use Dark Skin option is now exposed again since it could be incorrectly set sometimes. Now you can force it to light or dark, or set it to auto. * Fixed recast graph bug when using multiple terrains. Previously only one terrain would be used. * Fixed some UI glitches in Unity 4. * Changes * Removed Pathfinding.NNInfo.priority. * Removed Pathfinding.NearestNodePriority. * Conversions between NNInfo and Node are now explicit to comply with the rule of "if information might be lost: use explicit casts". * NNInfo is now a struct. * GraphHitInfo is now a struct. * Path.vectorPath and Path.path are now List and List respectively. This is done to enable pooling of resources more efficiently. * Added Pathfinding.Node.RecalculateConnectionCosts. * Moved IsPathPossible from GraphUpdateUtilities to PathUtilities. * Pathfinding.Path.processed was replaced with Pathfinding.Path.state. The new variable will have much more information about where the path is in the pathfinding pipeline. * **Paths should not be created with constructors anymore, instead use the PathPool class and then call some Setup() method** * When the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) object is destroyed, calculated paths in the return queue are not returned with errors anymore, but just returned. * Removed depracated methods AstarPath.AddToPathPool, RecyclePath, GetFromPathPool. * Bugs * C++ Version of Recast does not work on Windows. * GraphUpdateScene does in some cases not draw correctly positioned gizmos. * Starting two webplayers and closing down the first might cause the other one's pathfinding threads to crash (unity bug?) (confirmed on osx) * 3.1.4 (iOS fixes) * Fixes * More fixes for the iOS platform. * The "JsonFx.Json.dll" file is now correctly named. * Changes * Removed unused code from DotNetZip which reduced the size of it with about 20 KB. * 3.1.3 (free version only) * Fixes * Some of the fixes which were said to have been made in 3.1.2 were actually not included in the free version of the project. Sorry about that. * Also includes a new JsonFx and Ionic.Zip dll. This should make it possible to build with the .Net 2.0 Subset again see: [http://www.arongranberg.com/forums/topic/ios-problem/page/1/](http://www.arongranberg.com/forums/topic/ios-problem/page/1/) * 3.1.2 (small bugfix release) * Fixes * Fixed a bug which caused builds for iPhone to fail. * Fixed a bug which caused runtime errors on the iPhone platform. * Fixed a bug which caused huge lag in the editor for some users when using grid graphs. * ListGraphs are now correctly loaded as PointGraphs when loading data from older versions of the system. * Changes * Moved JsonFx into the namespace Pathfinding.Serialization.JsonFx to avoid conflicts with users own JsonFx libraries (if they used JsonFx). * Known bugs * Recast graph does not work when using static batching on any objects included. * 3.1.1 (small bugfix release) * Fixes * Fixed a bug which would cause [Pathfinding.GraphUpdateUtilities.UpdateGraphsNoBlock](https://arongranberg.com/astar/docs/graphupdateutilities/updategraphsnoblock.html#UpdateGraphsNoBlock2) to throw an exception when using multithreading * Fixed a bug which caused an error to be logged and no pathfinding working when not using multithreading in the free version of the project * Fixed some example scene bugs due to downgrading the project from Unity 3.5 to Unity 3.4 * 3.1 * Fixed bug which caused LayerMask fields (GridGraph inspector for example) to behave weirdly for custom layers on Unity 3.5 and up. * The color setting "Node Connection" now actually sets the colors of the node connections when no other information should be shown using the connection colors or when no data is available. * Put the Int3 class in a separate file. * Casting between Int3 and Vector3 is no longer implicit. This follows the rule of "if information might be lost: use explicit casts". * Renamed ListGraph to PointGraph. "ListGraph" has previously been used for historical reasons. PointGraph is a more suitable name. * Graph can now have names in the editor (just click the name in the graph list) * Graph Gizmos can now be selectively shown or hidden per graph (small "eye" icon to the right of the graph's name) * Added GraphUpdateUtilities with many useful functions for updating graphs. * Erosion for grid graphs can now use tags instead of walkability * Fixed a bug where using One Way links could in some cases result in a NullReferenceException being thrown. * Vector3 fields in the graph editors now look a bit better in Unity 3.5+. EditorGUILayout.Vector3Field didn't show the XYZ labels in a good way (no idea why) * GridGraph.useRaycastNormal is now enabled only if the Max Slope is less than 90 degrees. Previously it was a manual setting. * The keyboard shortcut to scan all graphs does now also work even when the graphs are not deserialized yet (which happens a lot in the editor) * Added NodeLink script, which can be attached to GameObjects to add manual links. This system will eventually replace the links system in the A\* editor. * Added keyboard shortcuts for adding and removing links. See Menubar -> Edit -> [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) Note Some features are restricted to Unity 3.5 and newer because of technical limitations in earlier versions (especially multi-object editing related features). * 3.1 beta (version number 3.0.9.9 in Unity due to technical limitations of the System.Versions class) * Multithreading is now enabled in the free version of the A\* [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) Project! * Better support for graph updates called during e.g OnPostScan. * PathID is now used as a short everywhere in the project * G,H and penalty is now used as unsigned integers everywhere in the project instead of signed integers. * There is now only one tag per node (if not the #define ConfigureTagsAsMultiple is set). * Fixed a bug which could make connections between graphs invalid when loading from file (would also log annoying error messages). * Erosion (GridGraph) can now be used even when updating the graph during runtime. * Fixed a bug where the GridGraph could return null from it's GetNearestForce calls which ended up later throwing a NullReferenceException. * FunnelModifier no longer warns if any graph in the path does not implement the IFunnelGraph interface (i.e have no support for the funnel algorithm) and instead falls back to add node positions to the path. * Added a new graph type : LayerGridGraph which works like a GridGraph, but has support for multiple layers of nodes (e.g multiple floors in a building). * ScanOnStartup is now exposed in the editor. * Separated temporary path data and connectivity data. * Rewritten multithreading. You can now run any number of threads in parallel. * To avoid possible infinite loops, paths are no longer returned with just an error when requested at times they should not (e.g right when destroying the pathfinding object) * Cleaned up code in [AstarPath.cs](https://arongranberg.com/astar/docs/%3Cundefined%3E) , members are now structured and many obsolete members have been removed. * Rewritten serialization. Now uses Json for settings along with a small part hardcoded binary data (for performance and memory). This is a lot more stable and will be more forwards and backwards compatible. Data is now saved as zip files(in memory, but can be saved to file) which means you can actually edit them by hand if you want! * Added dependency JsonFx (modified for smaller code size and better compatibility). * Added dependency DotNetZip (reduced version and a bit modified) for zip compression. * Graph types wanting to serialize members must add the JsonOptIn attribute to the class and JsonMember to any members to serialize (in the JsonFx.Json namespace) * Graph types wanting to serialize a bit more data (custom), will have to override some new functions from the NavGraph class to do that instead of the old serialization functions. * Changed from using System.Guid to a custom written Guid implementation placed in [Pathfinding.Util.Guid](https://arongranberg.com/astar/docs/guid.html) . This was done to improve compabitility with iOS and other platforms. Previously it could crash when trying to create one because System.Guid was not included in the runtime. * Renamed callback AstarPath.OnSafeNodeUpdate to AstarPath.OnSafeCallback (also added AstarPath.OnThreadSafeCallback) * MultiTargetPath would throw NullReferenceException if no valid start node was found, fixed now. * Binary heaps are now automatically expanded if needed, no annoying warning messages. * Fixed a bug where grid graphs would not update the correct area (using GraphUpdateObject) if it was rotated. * Node position precision increased from 100 steps per world unit to 1000 steps per world unit (if 1 world unit = 1m, that is mm precision). This also means that all costs and penalties in graphs will need to be multiplied by 10 to match the new scale. It also means the max range of node positions is reduced a bit... but it is still quite large (about 2 150 000 world units in either direction, that should be enough). * If Unity 3.5 is used, the EditorGUIUtility.isProSkin field is used to toggle between light and dark skin. * Added LayeredGridGraph which works almost the same as grid graphs, but support multiple layers of nodes. * Note Dropped Unity 3.3 support. **Known Bugs:** The C++ version of Recast does not work on Windows * Documentation Update * Changed from FixedUpdate to Update in the Get Started Guide. CharacterController.SimpleMove should not be called more than once per frame, so this might have lowered performance when using many agents, sorry about this typo. * 3.0.9 * The List Graph's "raycast" variable is now serialized correctly, so it will be saved. * List graphs do not generate connections from nodes to themselves anymore (yielding slightly faster searches) * List graphs previously calculated cost values for connections which were very low (they should have been 100 times larger), this can have caused searches which were not very accurate on small scales since the values were rounded to the nearest integer. * Added Pathfinding.Path.recalcStartEndCosts to specify if the start and end nodes connection costs should be recalculated when searching to reflect small differences between the node's position and the actual used start point. It is on by default but if you change node connection costs you might want to switch it off to get more accurate paths. * Fixed a compile time warning in the free version from referecing obsolete variables in the project. * Added AstarPath.threadTimeoutFrames which specifies how long the pathfinding thread will wait for new work to turn up before aborting (due to request). This variable is not exposed in the inspector yet. * Fixed typo, either there are eight (8) or four (4) max connections per node in a GridGraph, never six (6). * AlternativePath will no longer cause errors when using multithreading! * Added [Pathfinding.ConstantPath](https://arongranberg.com/astar/docs/constantpath.html) , a path type which finds all nodes in a specific distance (cost) from a start node. * Added [Pathfinding.FloodPath](https://arongranberg.com/astar/docs/floodpath.html) and [Pathfinding.FloodPathTracer](https://arongranberg.com/astar/docs/floodpathtracer.html) as an extreamly fast way to generate paths to a single point in for example TD games. * Fixed a bug in MultiTargetPath which could make it extreamly slow to process. It would not use much CPU power, but it could take half a second for it to complete due to excessive yielding * Fixed a bug in FleePath, it now returns the correct path. It had previously sometimes returned the last node searched, but which was not necessarily the best end node (though it was often close) * Using #defines, the pathfinder can now be better profiled (see Optimizations tab -> Profile Astar) * Added example scene Path Types (mainly useful for A\* Pro users, so I have only included it for them) * Added many more tooltips in the editor * Fixed a bug which would double the Y coordinate of nodes in grid graphs when loading from saved data (or caching startup) * Graph saving to file will now work better for users of the Free version, I had forgot to include a segment of code for Grid Graphs (sorry about that) * Some other bugfixes * 3.0.8.2 * Fixed a critical bug which could render the A\* inspector unusable on Windows due to problems with backslashes and forward slashes in paths. * 3.0.8.1 * Fixed critical crash bug. When building, a preprocessor-directive had messed up serialization so the game would probably crash from an OutOfMemoryException. * 3.0.8 * Graph saving to file is now exposed for users of the Free version * Fixed a bug where penalties added using a GraphUpdateObject would be overriden if updatePhysics was turned on in the GraphUpdateObject * Fixed a bug where list graphs could ignore some children nodes, especially common if the hierarchy was deep * Fixed the case where empty messages would spam the log (instead of spamming somewhat meaningful messages) when path logging was set to Only Errors * Changed the NNConstraint used as default when calling NavGraph.GetNearest from NNConstraint.Walkable to NNConstraint.None, this is now the same as the default for [AstarPath.GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) . * You can now set the size of the red cubes shown in place of unwalkable nodes (Settings–>Show Unwalkable Nodes–>Size) * Dynamic search of where the EditorAssets folder is, so now you can place it anywhere in the project. * Minor A\* inspector enhancements. * Fixed a very rare bug which could, when using multithreading cause the pathfinding thread not to start after it has been terminated due to a long delay * Modifiers can now be enabled or disabled in the editor * Added custom inspector for the Simple Smooth Modifier. Hopefully it will now be easier to use (or at least get the hang on which fields you should change). * Added AIFollow.canSearch to disable or enable searching for paths due to popular request. * Added AIFollow.canMove to disable or enable moving due to popular request. * Changed behaviour of AIFollow.Stop, it will now set AIFollow.canSearch and AIFollow.canMove to false thus making it completely stop and stop searching for paths. * Removed Path.customData since it is a much better solution to create a new path class which inherits from Path. * Seeker.StartPath is now implemented with overloads instead of optional parameters to simplify usage for Javascript users * Added Curved Nonuniform spline as a smoothing option for the Simple Smooth modifier. * Added Pathfinding.WillBlockPath as function for checking if a GraphUpdateObject would block pathfinding between two nodes (useful in TD games). * Unity References (GameObject's, Transforms and similar) are now serialized in another way, hopefully this will make it more stable as people have been having problems with the previous one, especially on the iPhone. * Added shortcuts to specific types of graphs, AstarData.navmesh, AstarData.gridGraph, AstarData.listGraph * **Known Bugs:** The C++ version of Recast does not work on Windows * 3.0.7 * Grid Graphs can now be scaled to allow non-square nodes, good for isometric games. * Added more options for custom links. For example individual nodes or connections can be either enabled or disabled. And penalty can be added to individual nodes * Placed the Scan keyboard shortcut code in a different place, hopefully it will work more often now * Disabled GUILayout in the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) script for a possible small speed boost * Some debug variables (such as AstarPath.PathsCompleted) are now only updated if the ProfileAstar define is enabled * DynamicObstacle will now update nodes correctly when the object is destroyed * Unwalkable nodes no longer shows when Show Graphs is not toggled * Removed Path.multithreaded since it was not used * Removed Path.preCallback since it was obsolate * Added [Pathfinding.XPath](https://arongranberg.com/astar/docs/xpath.html) as a more customizable path * Added example of how to use MultiTargetPaths to the documentation as it was seriously lacking info on that area * The viewing mesh scaling for recast graphs is now correct also for the C# version * The StartEndModifier now changes the path length to 2 for correct applying if a path length of 1 was passed. * The progressbar is now removed even if an exception was thrown during scanning * Two new example scenes have been added, one for list graphs which includes sample links, and another one for recast graphs * Reverted back to manually setting the dark skin option, since it didn't work in all cases, however if a dark skin is detected, the user will be asked if he/she wants to enable the dark skin * Added gizmos for the AIFollow script which shows the current waypoint and a circle around it illustrating the distance required for it to be considered "reached". * The C# version of Recast does now use Character Radius instead of Erosion Radius (world units instead of voxels) * Fixed an IndexOutOfRange exception which could occur when saving a graph with no nodes to file * **Known Bugs:** The C++ version of Recast does not work on Windows * 3.0.6 * Added support for a C++ version of Recast which means faster scanning times and more features (though almost no are available at the moment since I haven't added support for them yet). * Removed the overload AstarData.AddGraph (string type, NavGraph graph) since it was obsolete. AstarData.AddGraph ([Pathfinding.NavGraph](https://arongranberg.com/astar/docs/navgraph.html) ) should be used now. * Fixed a few bugs in the FunnelModifier which could cause it to return invalid paths * A reference image can now be generated for the Use Texture option for Grid Graphs * Fixed an editor bug with graphs which had no editors * Graphs with no editors now show up in the Add New Graph list to show that they have been found, but they cannot be used * Deleted the **graphIndex** parameter in the [Pathfinding.NavGraph.Scan](https://arongranberg.com/astar/docs/navgraph/scan.html#Scan) function. If you need to use it in your graph's Scan function, get it using [Pathfinding.AstarData.GetGraphIndex](https://arongranberg.com/astar/docs/astardata/getgraphindex.html#GetGraphIndex) * Javascript support! At last you can use Js code with the A\* [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) Project! Go to A\* Inspector–>Settings–>Editor–>Enable Js Support to enable it * The Dark Skin is now automatically used if the rest of Unity uses the dark skin(hopefully) * Fixed a bug which could cause Unity to crash when using multithreading and creating a new [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) object during runtime * 3.0.5 * [List Graphs](https://arongranberg.com/astar/docs/pointgraph.html) now support UpdateGraphs. This means that they for example can be used with the DynamicObstacle script. * List Graphs can now gather nodes based on GameObject tags instead of all nodes as childs of a specific GameObject. * List Graphs can now search recursively for childs to the 'root' GameObject instead of just searching through the top-level children. * Added custom area colors which can be edited in the inspector (A\* inspector –> Settings –> Color Settings –> Custom Area Colors) * Fixed a NullReference bug which could occur when loading a Unity Reference with the AstarSerializer. * Fixed some bugs with the FleePath and RandomPath which could cause the StartEndModifier to assign the wrong endpoint to the path. * Documentation is now more clear on what is A\* [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) Project Pro only features. * [Pathfinding.NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) now has a variable to constrain which graphs to search (A\* Pro only). This is also available for [Pathfinding.GraphUpdateObject](https://arongranberg.com/astar/docs/graphupdateobject.html) which now have a field for an NNConstraint where it can constrain which graphs to update. * StartPath calls on the Seeker can now take a parameter specifying which graphs to search for close nodes on (A\* Pro only) * Added the delegate [AstarPath.OnAwakeSettings](https://arongranberg.com/astar/docs/astarpath.html#OnAwakeSettings) which is called as the first thing in the Awake function, can be used to set up settings. * Pathfinding.UserConnection.doOverrideCost is now serialized correctly. This represents the toggle to the right of the "Cost" field when editing a link. * Fixed some bugs with the RecastGraph when spans were partially out-of-bounds, this could generate seemingly random holes in the mesh * 3.0.4 (only pro version affected) * Added a Dark Skin for Unity Pro users (though it is available to Unity Free users too, even though it doesn't look very good). It can be enabled through A\* Inspector –> Settings –> Editor Settings –> Use Dark Skin * Added option to include or not include out of bounds voxels (Y axis below the graph only) for Recast graphs. * 3.0.3 (only pro version affected) * Fixed a NullReferenceException caused by Voxelize.cs which could surface if there were MeshFilters with no Renderers on GameObjects (Only Pro version affected) * 3.0.2 * Textures can now be used to add penalty, height or change walkability of a Grid Graph (A\* Pro only) * Slope can now be used to add penalty to nodes * Height (Y position) can now be usd to add penalty to nodes * Prioritized graphs can be used to enable prioritizing some graphs before others when they are overlapping * Several bug fixes * Included a new [DynamicObstacle.cs](https://arongranberg.com/astar/docs/%3Cundefined%3E) script which can be attached to any obstacle with a collider and it will update grids around it to account for changed position * 3.0.1 * Fixed Unity 3.3 compability * 3.0 * Rewrote the system from scratch * Funnel modifier * Easier to extend the system * x. releases are major rewrites or updates to the system. * .x releases are quite big feature updates * ..x releases are the most common updates, fix bugs, add some features etc. * ...x releases are quickfixes, most common when there was a really bad bug which needed fixing ASAP. --- # Architecture overview - A* Pathfinding Project Architecture overview ===================== An overview of how the package is structured. Here you will learn how various parts of the package fit together. Overview -------- There are several different parts of the package. Broadly, they can be grouped into: * Movement scripts, which tell the agent how to move and where it should move (see [Movement scripts](https://arongranberg.com/astar/docs/movementscripts.html) ). * Graphs, which describe where an agent can move (see [Graph Types](https://arongranberg.com/astar/docs/graphtypes.html) ). * Temporary obstacles, which cut holes in the navmesh or update it in other ways (see [Graph Updates during Runtime](https://arongranberg.com/astar/docs/graphupdates.html) ). * Off-mesh links, which allow an agent to move or jump between otherwise disconnected parts of the navmesh (see [NodeLink2](https://arongranberg.com/astar/docs/nodelink2.html) ). * Path modifiers, which post-process paths to, for example, smooth them (see [Using Modifiers](https://arongranberg.com/astar/docs/modifiers2.html) ). What you will primarily interact with is the movement script and the [Seeker](https://arongranberg.com/astar/docs/seeker.html) component. Both need to be attached to an agent that needs to move. The movement script controls how the agent should move, its velocity, rotation, and so on, as well as what the current destination of the agent is and when it should recalculate its path. The [Seeker](https://arongranberg.com/astar/docs/seeker.html) component is controlled by the movement script. The movement script tells it to calculate a path, and the Seeker will process this and later (possibly in a later frame) return the result to the movement script. The Seeker is also responsible for running any path modifiers which may be attached. The [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component holds all the graph data in a scene. It follows the [singleton pattern](https://en.wikipedia.org/wiki/Singleton_pattern) , so there should only be one such component in a scene. It may contain one or many graphs, of the same or different types. Each graph, in turn, contains and manages all its nodes (of which there may be many, sometimes up to millions). You can access the graph data directly. For more info on this, see [Accessing graph data](https://arongranberg.com/astar/docs/accessingdata.html) . The [local avoidance system](https://arongranberg.com/astar/docs/localavoidance.html) is almost completely separate from all pathfinding. Local avoidance doesn't care about which graph it is used on, or even that there are graphs. The movement script interacts with local avoidance using the [RVOController](https://arongranberg.com/astar/docs/rvocontroller.html) component, which you may attach to your character GameObjects. The local avoidance simulation itself is done by the [RVOSimulator](https://arongranberg.com/astar/docs/rvosimulator.html) component. It also follows the singleton pattern, so only one should exist per scene. The RVOSimulator has its own internal worker threads, which it uses to simulate local avoidance with maximum performance. ### The calculation of a path When you set the [destination of a movement script](https://arongranberg.com/astar/docs/iastarai.html#destination) , this fires off a sequence of events: * The movement script will soon realize that its destination has changed, and will schedule an automatic path recalculation. * It creates a path object (e.g. [ABPath](https://arongranberg.com/astar/docs/abpath.html) ) which it sends to the [Seeker](https://arongranberg.com/astar/docs/seeker.html) for calculation (except for the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) , which skips the Seeker). * The Seeker will apply some settings and then send the path to the main [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component. * The path is then put in a queue and a worker thread will pick it up as soon as possible. There may be many worker threads working on pathfinding at the same time. * The worker thread calculates the path using the A\* algorithm. If you are interested, you can read more about that here: [https://www.redblobgames.com/pathfinding/a-star/introduction.html](https://www.redblobgames.com/pathfinding/a-star/introduction.html) . * The worker thread finishes the path calculation and puts the calculated path in a return queue. * In the next Update loop, the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component sends a message to the Seeker component that the path is calculated. * The Seeker runs modifiers which smooth the path, or post-process it in other ways. See [Using Modifiers](https://arongranberg.com/astar/docs/modifiers2.html) . * Finally, the Seeker calls the callback in the movement script to indicate that the path is now calculated and ready to be followed. You can also bypass the Seeker component if you want to, and use the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component directly. Take a look at [Searching for paths](https://arongranberg.com/astar/docs/callingpathfinding.html) if you want to read more about that. --- # Get Started Guide - A* Pathfinding Project Get Started Guide ================= How to get started with the A\* Pathfinding Project, create your first graph, and make an agent move around on it. Contents -------- * [Video Tutorial](https://arongranberg.com/astar/docs/getstarted.html#video) * [Overview](https://arongranberg.com/astar/docs/getstarted.html#getstarted-overview) * [Introduction](https://arongranberg.com/astar/docs/getstarted.html#getstarted-intro) * [Installation](https://arongranberg.com/astar/docs/getstarted.html#getstarted-installing) * [Creating a scene with some obstacles](https://arongranberg.com/astar/docs/getstarted.html#newscene) * [Adding Pathfinding](https://arongranberg.com/astar/docs/getstarted.html#addingastar) * [But what is a graph?](https://arongranberg.com/astar/docs/getstarted.html#whatisagraph) * [Adding a graph](https://arongranberg.com/astar/docs/getstarted.html#addinggraph) * [Adding an agent](https://arongranberg.com/astar/docs/getstarted.html#addingai) * [Setting the destination via code](https://arongranberg.com/astar/docs/getstarted.html#getstarted-script) * [Logging settings](https://arongranberg.com/astar/docs/getstarted.html#logging) * [Conclusion](https://arongranberg.com/astar/docs/getstarted.html#getstarted-conclusion) Video Tutorial -------------- If you prefer a video tutorial instead of a text tutorial, here is a video for you. The video tutorial and this text tutorial are very similar, so you can choose the one you prefer. You can also take a look at the excellent tutorial/review by Code Monkey: [https://www.youtube.com/watch?v=46qZgd-T-hk](https://www.youtube.com/watch?v=46qZgd-T-hk) Overview -------- This package focuses on 3 core areas: ![](https://arongranberg.com/astar/docs/images/getstarted/core_features@2x.png) * Graphs: which describe where an agent can move. * Pathfinding: finding the best path between two points on a graph, or similar tasks. * Movement: how an agent follows a path. Additionally, there are many supporting features. Broadly, they can be grouped into: * [Temporary obstacles](https://arongranberg.com/astar/docs/graphupdates.html) : which cut holes in the navmesh or update it in other ways. * [Off-mesh links](https://arongranberg.com/astar/docs/offmeshlinks2.html) : which allow an agent to move or jump between otherwise disconnected parts of the navmesh. * [Path modifiers](https://arongranberg.com/astar/docs/modifiers2.html) : which are used by some movement scripts to smooth or simplify paths (notably these are **not** used by the FollowerEntity, which you'll use in this tutorial. It has its own internal smoothing instead). * [Local avoidance](https://arongranberg.com/astar/docs/localavoidance.html) : which is used to make agents handle crowds. Introduction ------------ In this tutorial, we will create a simple scene with a few obstacles, generate a navmesh for it, and then make an agent move around on it. Installation ------------ The first thing you need to do, if you haven't done so already, is to install the A\* Pathfinding Project. Please read the [installation guide](https://arongranberg.com/astar/docs/installation.html) . If you want, you can explore the different [example scenes](https://arongranberg.com/astar/docs/examplescenes.html) in the project before you start with the next section. The example scenes are installed separately. Take a look at the installation guide for more info. See [Installation Guide](https://arongranberg.com/astar/docs/installation.html) [Example Scenes](https://arongranberg.com/astar/docs/examplescenes.html) Creating a scene with some obstacles ------------------------------------ Create a new empty scene, name it "PathfindingTest". The agent needs something to walk on, and something for it to avoid. ![](https://arongranberg.com/astar/docs/images/generated/scenes/GetStarted/overview.png) Add a plane to the scene, place it at the scene origin (0,0,0) and scale it to (10,10,10). Then create some cubes of different scales and place them on the plane; these will be obstacles which the agent should avoid. You can optionally add some materials to the objects, to make them look nicer. Your scene should now look something like in the image Adding Pathfinding ------------------ The [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component is the core of this package. It holds all the graphs in the scene and provides a central place for all pathfinding related settings. This is a singleton, so you should only have one instance of it in your scene. You can add multiple graphs to it, but most games only need one. ![](https://arongranberg.com/astar/docs/images/inspector/inspector@2x.png) Create a new GameObject and name it **A\***. Add the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component to the new GameObject. Component → Pathfinding → [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) The inspector of the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component is divided up into sections. * **Graphs**: contains all graphs in the scene. * **Settings**: contains all global pathfinding and logging settings. * **Save & Load**: allows you to save and load graphs to and from files. * **Optimization**: allows you to enable or disable some features project-wide. You typically don't have to touch these. * **About**: shows the current version and has links to the online documentation. * **Show Graphs Toggle**: enables or disables the graphs from being rendered in the scene view. * **Scan Button**: recalculates all graphs. There's also a shortcut for this: Cmd+Alt+S (mac) or Ctrl+Alt+S (windows). See [The A\* Inspector](https://arongranberg.com/astar/docs/inspector.html) , for a more detailed explanation of every setting in the A\* inspector. ### But what is a graph? A graph represents the traversable surface of the world. This is every point where your agent can walk. Or, more precisely, it is every location where it is valid for the center of an agent to be. ![](https://arongranberg.com/astar/docs/images/getstarted/navmesh_placement@2x.png) A graph consists of **nodes** and **connections** between them. The shape of the nodes can vary. Some graph types use grid tiles, some use triangles, and some use points. The word **navmesh** (or navigation mesh) is often used synonymously with the word **graph**. But it refers specifically to graphs that consist of triangle meshes (like the [RecastGraph](https://arongranberg.com/astar/docs/recastgraph.html) and [NavMeshGraph](https://arongranberg.com/astar/docs/navmeshgraph.html) ). ### Adding a graph For this tutorial, we will be using the [RecastGraph](https://arongranberg.com/astar/docs/recastgraph.html) . It can automatically generate a navmesh from the scene geometry. The recast graph is a good all-around graph type, which can handle most situations. It can handle both detailed features, and very large worlds, in both 2D and 3D games. However, it is worse at handling dynamic costs for different parts of the world, than, for example, a grid graph. ![](https://arongranberg.com/astar/docs/images/graphs/recast_inspector@2x.png) To create a recast graph, click on the **Graphs** section, then click on the **Add New Graph** button, and finally select the recast graph from the list. The recast graph is pro-only feature. If you are using the free version, you can use the [grid graph](https://arongranberg.com/astar/docs/graphtypes.html) instead. When the graph has been added, click on its label to expand the graph settings. We can actually get a decent navmesh by only changing a single setting. We need to ensure that the recast graph's bounding box, which is visualized in the scene view as a white box, covers our entire world. ![](https://arongranberg.com/astar/docs/images/generated/scenes/GetStarted/overviewwithbounds.png) Click the [Snap Bounds To Scene](https://arongranberg.com/astar/docs/recastgraph/snapboundstoscene.html#SnapBoundsToScene) button, in the recast graph inspector. You should see that the graph's bounding box has been resized to cover the entire scene. ![](https://arongranberg.com/astar/docs/images/generated/scenes/GetStarted/overviewwithgraphs.png) Now, we can click the **Scan** button, at the bottom of the inspector, to calculate the graph. Or use the keyboard shortcut: Cmd+Alt+S (mac) or Ctrl+Alt+S (windows). If you have done everything correctly, you should now have a generated navmesh in your scene. Different graphs represent the walkable surface differently. The recast graph uses a triangular mesh, while, for example, the grid graph uses a grid of nodes. See We'll use the recast graph's default settings for this tutorial. But check out [Get started with recast graphs](https://arongranberg.com/astar/docs/getstartedrecast.html) for a more in-depth guide on how to use the recast graph. Adding an agent --------------- What is a pathfinding test without some moving stuff? Not fun at all, so let's add an agent to play around with. ![](https://arongranberg.com/astar/docs/images/generated/scenes/GetStarted/agent.png) Create a new GameObject and name it "Agent" Place it somewhere on the ground Attach the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component to the agent's root GameObject If you do not have the Unity Entities package installed, the inspector will prompt you to install it. The FollowerEntity requires the entities package, but there are [other movement scripts](https://arongranberg.com/astar/docs/movementscripts.html) in the package that don't. Add a **Cylinder** object as a child of the agent, and move it to (0,1,0). This will make it line up with the FollowerEntity's bounds. There are multiple movement scripts in the package. They have different movement styles and performance characteristics. The role of these components is to take care of searching for paths and to follow them. You give it a destination, and it will figure out how to get there. The [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) movement script is a good choice for most games that need smooth movement. It works on all graphs except the [point graph](https://arongranberg.com/astar/docs/pointgraph.html) , and is pretty performant too. See There are also other included movement scripts called [AIPath](https://arongranberg.com/astar/docs/aipath.html) , [RichAI](https://arongranberg.com/astar/docs/richai.html) and [AILerp](https://arongranberg.com/astar/docs/ailerp.html) . Take a look at [Movement scripts](https://arongranberg.com/astar/docs/movementscripts.html) for more info. You can even write your own custom movement script, if you want. ![](https://arongranberg.com/astar/docs/images/generated/scenes/GetStarted/agentnavmeshhole.png) To prevent the graph from cutting a hole around the agent, we need to move the agent to a separate layer. ![](https://arongranberg.com/astar/docs/images/graphs/recast_inspector_filtering@2x.png) ![](https://arongranberg.com/astar/docs/images/generated/scenes/GetStarted/agentnavmeshholefixed.png) Move the agent to a separate layer. For example "TransparentFX", if you have the default unity layers. Any layer other than the default will do. Change the layer mask in the recast graph settings to exclude the layer that the agent is on. Scan the graph again. You should now see that the agent does not leave a hole in the navmesh. We'll also need to tell the agent where to go. You can do this via a script, or you can use the helper component [AIDestinationSetter](https://arongranberg.com/astar/docs/aidestinationsetter.html) , which allows moving to a GameObject. ![](https://arongranberg.com/astar/docs/images/generated/inspectors/AIDestinationSetter@2x.png) Attach the [AIDestinationSetter](https://arongranberg.com/astar/docs/aidestinationsetter.html) component to the agent. We'll also need a target for the agent to move to. Your browser does not support the video tag. Create a new Sphere object, name it **Target**. Place it somewhere in the scene, where you want the agent to move. Assign the **Target** GameObject to the "Target" field on the [AIDestinationSetter](https://arongranberg.com/astar/docs/aidestinationsetter.html) component. Now, if you press play, the agent should move towards the target. Note The agent draws its path in the scene view by default. This is controlled by the **Path** option in the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) 's Movement Debug Rendering settings. When you move the target around, the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) will automatically do a local repair of its path every frame. It will also recalculate the path from scratch at regular intervals, or when the destination has moved a lot. Setting the destination via code -------------------------------- We haven't quite achieved what we set out to do in this tutorial just yet. Our goal was to make the agent follow our cursor, but right now it only follows a target object. We can, of course, drag it around in the scene view, but that's not quite the same thing. To solve this, we'll need a small custom script. ![](https://arongranberg.com/astar/docs/images/getstarted/create_new_script@2x.png) Click "Create" in your project view, and select **MonoBehaviour Script**. Name the new script **FollowCursor**. Double click the created script, to open it in your favorite text editor. `using UnityEngine; // Use the Pathfinding namespace to be able to // use most common classes in the package using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) ; public class FollowCursor : MonoBehaviour { IAstarAI ai; // This runs when the game starts void OnEnable () { // Get a reference to our movement script. // We use the IAstarAI interface to make the code work with all movement scripts // You can alternatively use the concrete FollowerEntity class, // but that would make the code less flexible ai = GetComponent(); } void Update () { // Get the mouse position var mousePosition = Input.mousePosition; // Create a ray from the camera to the mouse position var ray = Camera.main.ScreenPointToRay(mousePosition); // Check if the ray hits something if (Physics.Raycast(ray, out var hit)) { // Set the destination for the AI to move towards ai.destination = hit.point; } } } ` Add **using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) ;** at the top of the script. This allows your script to access most of the common classes in the package. Create a field to store the agent reference. Set this field during **OnEnable**. In **Update**, fire a ray from the mouse cursor into the scene, and see if it hits anything. If so, set the [destination](https://arongranberg.com/astar/docs/followerentity.html#destination) of the agent to the hit point. ![](https://arongranberg.com/astar/docs/images/getstarted/add_follow_cursor@2x.png) Remove the [AIDestinationSetter](https://arongranberg.com/astar/docs/aidestinationsetter.html) component from the agent, since we don't need it anymore. Attach your new FollowCursor script to the agent. ![](https://arongranberg.com/astar/docs/images/getstarted/camera_placement@2x.png) Adjust the camera so that it looks down on the scene. Your browser does not support the video tag. Press play! You should now be able to make the agent follow your cursor around in the game view. Logging settings ---------------- Every time a path is calculated by the system, it can optionally be logged to the console. This can be a big help in understanding what the system is doing and also to spot performance issues. Logging is not free, however, so for release builds it is recommended that you disable it. You can change the logging settings under the A\* Inspector → Settings → Debug tab. ![](https://arongranberg.com/astar/docs/images/path_logging@2x.png) Use less debugging to improve performance (a bit) or just to get rid of the console spam. Use more debugging (heavy) if you want more information about what the pathfinding scripts are doing. The InGame option will display the latest path log using the in-game GUI. Conclusion ---------- That concludes the Get Started tutorial. We have covered the basics of creating a scene with obstacles, adding a graph, and making an agent move around on it, and how to interact with an agent using code. I wish you the best of luck in your continued exploration of this package. Here are some suggestions for what to do next: * Explore the [Example Scenes](https://arongranberg.com/astar/docs/examplescenes.html) included in the package. * [Improve your recast graph knowledge](https://arongranberg.com/astar/docs/getstartedrecast.html) . * [Try creating a grid graph](https://arongranberg.com/astar/docs/getstartedgrid.html) . * [How to migrate from Unity's built-in pathfinding to this package](https://arongranberg.com/astar/docs/migratingfromunity.html) . * [More about the overall architecture of the package](https://arongranberg.com/astar/docs/architecture.html) . * [More about other graph types](https://arongranberg.com/astar/docs/graphtypes.html) . --- # Using navmeshes - A* Pathfinding Project Using navmeshes =============== How to set up a navmesh graph. Note This tutorial has outdated screenshots. It's scheduled to be updated. What is a navmesh? ------------------ If you haven't used any pathfinding system before, you may feel more familiar with grid graphs. A GridGraph consists of a bunch of nodes arranged in a grid-like pattern. It is very structured and thus works for most things you throw at it. But doesn't it feel like a waste of nodes to generate a huge number of nodes for your large open grass field you are using in your game, just to be able to get enough precision to represent the small obstacles around the farmer's house (or whatever)? Wouldn't it be better to use a few nodes to represent the large field and then more nodes for the smaller obstacles? This is where navmeshes come in. Navmeshes represent the world using polygons (more specifically triangles in this case), much like other meshes you have in your game. Navmeshes are used to accurately describe the surface that the character(s) can walk on. ![](https://arongranberg.com/astar/docs/images/navmeshGraph.png) ![](https://arongranberg.com/astar/docs/images/navmeshgraph_graph.png) As you see in the above image, the navmesh does not have equally sized nodes, but nodes can be as large or as small as you want them to be. The end result is that navmeshes can more accurately describe the environment and are smaller because they do not need to waste a large number of nodes on empty areas. Because they are smaller, they are also usually faster to perform pathfinding on. Also, they can represent multilayered environments as opposed to normal grid graphs (but this is a feature of the LayeredGridGraph available in the pro version). So what are the downsides? The main problem with navmesh graphs is that they take a long time to generate (or model, if you do it by hand). To scan a whole GridGraph as in the GridGraph example scene takes something like 25-60 ms (depending on the computer), to generate an equivalent recast graph (we'll get to them later) takes a few hundred milliseconds, and can take many seconds for more complex scenes. They are also slower to update compared to grid graphs. It is possible to do limited fast updates of the graphs using [navmesh cutting](https://arongranberg.com/astar/docs/navmeshcut.html) . For recast graphs, it is also possible to recalculate individual **tiles** in it asynchronously (tiles will be explained in the recast tutorial further down) however this is still relatively slow. Creating a navmesh ------------------ Navmeshes can be modelled by hand, or automatically generated. The automatic generation is only available in the pro version. Take a look at one or both of these sub-tutorials in order to learn how to create a navmesh, either by hand or automatically. * [Creating a navmesh manually](https://arongranberg.com/astar/docs/createnavmesh.html) * [Get started with recast graphs](https://arongranberg.com/astar/docs/getstartedrecast.html) Movement on a navmesh --------------------- In the previous tutorial, we wrote a simple script for moving a character around. We could use the same script, but to get nicer movement I will introduce an included component which gives very nice movement on navmeshes (specifically navmeshes). It is called [RichAI](https://arongranberg.com/astar/docs/richai.html) . Create a new GameObject and attach the RichAI component to it. It will automatically attach a Seeker. For visualization purposes, add a Capsule object as a **child object** to root. Move the capsule one unit up, so that the root GameObject will have its pivot point at the capsule's base; the RichAI script assumes that the pivot is at the feet of the character. Take care that you remove the capsule collider (and any other colliders) from the character. Alternatively, you can configure the Gravity → Raycast Ground Mask field on the RichAI component to exclude those colliders. Why? Because the RichAI component by default uses raycasting to determine where the ground is, and if that raycast were to hit a collider which was attached to itself, you would see weird behaviour (try for yourself). It also supports using the CharacterController component, but I do not recommend that if you are planning to have a lot of characters in the game because character controllers are relatively slow. To tell the AI where it should move we need another script. Attach the [AIDestinationSetter](https://arongranberg.com/astar/docs/aidestinationsetter.html) component to the same GameObject as the RichAI component is attached to. This script has a single Transform field called 'Target' and what this script will do is tell the AI that it should move towards that object. Create another GameObject named "Target". Assign that object to the **Target** field on the AIDestinationSetter component. Note The screenshot below is of a slightly older version where the **Target** field was on the RichAI component instead of on the AIDestinationSetter component. ![](https://arongranberg.com/astar/docs/images/getstarted2/scene_richai.png) Now when pressing play you should see the agent moving towards the target. When moving the target object around, the agent should follow it. The RichAI script is specially written for movement on navmesh graphs. It enforces that the agent stays on the navmesh at all times. As opposed to other movement scripts in this project, it does not have support for path modifiers. This is because it does not follow a list of waypoints; instead it follows a list of nodes. This has the advantage that the character can be pushed around by some amount and it will still move correctly without a path recalculation. Describing every setting for the RichAI is too much for this tutorial; you can find documentation for it here: [RichAI](https://arongranberg.com/astar/docs/richai.html) . ### Notes about navmesh graphs When not using the RichAI component, which has built-in path simplification, it is recommended to attach the funnel modifier to the GameObject with the Seeker. The funnel modifier will simplify the path and make it much more aesthetically pleasing (and also shorter). See [FunnelModifier](https://arongranberg.com/astar/docs/funnelmodifier.html) Navmesh graphs can sometimes give suboptimal paths. This is because pathfinding costs are approximated for performance and algorithmic complexity reasons. It typically overestimates the cost of a path from 0% to 20%, and thus it may not always pick the completely optimal path. The effect is most prominent when the navmesh has very large and very small nodes (triangles) placed close to each other. The pathfinding then usually prefers the path with smaller triangles (sometimes the one with larger triangles, but not as common). Typically the effect is small enough that it is not a problem in practice. Version Before version 5.0, pathfinding was done on triangle centers, which was a lot less accurate in most cases. --- # Graph Types - A* Pathfinding Project Graph Types =========== Brief overview of the different graph types. There are several different graph types included in the project, and you can even write your own. In this document, I will briefly explain the different graph types and their settings. A [graph](https://en.wikipedia.org/wiki/Graph_(discrete_mathematics)) represents the walkable areas of the world. It is a collection of nodes and connections between them. Different graphs have very different representations of the world, from points to grid tiles to a triangle mesh. This means that different graphs are better suited for different types of games. Contents -------- * [TL;DR Which graph should I use?](https://arongranberg.com/astar/docs/graphtypes.html#graph-tldr) * [Grid Graph](https://arongranberg.com/astar/docs/graphtypes.html#grid) * [Hexagonal Grid Graph](https://arongranberg.com/astar/docs/graphtypes.html#hexagonal) * [Layered Grid Graph - A\* Pro Only](https://arongranberg.com/astar/docs/graphtypes.html#layergrid) * [Recast Graph - A\* Pro Only](https://arongranberg.com/astar/docs/graphtypes.html#recast) * [Navmesh Graph](https://arongranberg.com/astar/docs/graphtypes.html#navmesh) * [Point Graph](https://arongranberg.com/astar/docs/graphtypes.html#point) TL;DR Which graph should I use? ------------------------------- To make a first assessment of which graph type is best for your game, you can use this flowchart: ![](https://arongranberg.com/astar/docs/images/graphs/choose_graph.svg) * ¹ What's a large world? It depends, but if you'd need a grid graph larger than 400x400 nodes, a recast graph is almost always a better choice. * ² For a spherical world or other weird world shapes, see [Spherical Worlds](https://arongranberg.com/astar/docs/spherical.html) . * ³ Side-scrolling games unfortunately have little support in this package. But a point graph can work well for some games. * ⁴ For an infinite world, take a look at [A small moving graph](https://arongranberg.com/astar/docs/largeworlds.html#moving-grid) . Keep in mind that this is only a rough guide; you should read the rest of this page for more information about the pros and cons of each graph. Grid Graph ---------- ![](https://arongranberg.com/astar/docs/images/graphs/grid_graph.png) The Grid Graph is the most straightforward graph. As the name implies, it generates nodes in a grid pattern. It works great for most scenes and is especially good when you need to update the graph during runtime (such as in an RTS or a Tower Defence game). However, it is not particularly good from a performance and memory point of view at handling large worlds with large open spaces, as it represents all regions with the same node density regardless of whether they need that detail or not. Pros: * Grid graphs work well with penalties and tags. * Graph updates are fast. * Scanning the graph is comparatively fast. Cons: * Memory usage is higher than a recast graph. * Pathfinding over long distances can be much slower than on a recast graph. * It doesn't scale to very large worlds. See [GridGraph](https://arongranberg.com/astar/docs/gridgraph.html) [Get started with grid graphs](https://arongranberg.com/astar/docs/getstartedgrid.html) Hexagonal Grid Graph -------------------- ![](https://arongranberg.com/astar/docs/images/grid_hexagon_thin.png) You can create a hexagonal graph by creating a grid graph and changing the **Shape** option in the grid graph inspector to **Hexagonal**. All the same pros and cons as for a normal grid graph apply. ![](https://arongranberg.com/astar/docs/images/grid_shape@2x.png) See [Get started with grid graphs](https://arongranberg.com/astar/docs/getstartedgrid.html) If you want to see an example, you can take a look at the example scene [Hexagonal Turn Based](https://arongranberg.com/astar/docs/example_turn_based.html) . Layered Grid Graph - A\* Pro Only --------------------------------- ![](https://arongranberg.com/astar/docs/images/graphs/layered_grid_graph.png) The GridGraph is great, but sometimes the world contains overlapping areas, such as a house with multiple floors. The GridGraph cannot handle that in a good way. So here's a grid graph which supports overlapping areas. It uses a bit more memory compared to a normal grid graph, but otherwise it works the same. See [LayerGridGraph](https://arongranberg.com/astar/docs/layergridgraph.html) [Get started with grid graphs](https://arongranberg.com/astar/docs/getstartedgrid.html) Recast Graph - A\* Pro Only --------------------------- ![](https://arongranberg.com/astar/docs/images/graphs/recast_graph.png) The Recast Graph generates a triangle navmesh instead of a grid. It is based on [Recast](http://code.google.com/p/recastnavigation/) , an open source navmesh and navigation system in C++ which has been translated and modified to run natively in Unity. The recast graph generator will voxelize the world (convert it to a lot of cubes, like a high resolution Minecraft world) and then build a navigation mesh of it which can be used similar to the [Navmesh Graph](https://arongranberg.com/astar/docs/graphtypes.html#navmesh) . It can generate a robust mesh in seconds, something which could take hours using manual mesh building. If you have been using Unity's navigation system before, this graph should seem familiar to you, as it is based on the same principles. In fact, Unity's system is also based on recast. If you prefer to manually create a navmesh in a 3D modeling program, you can use the [Navmesh Graph](https://arongranberg.com/astar/docs/graphtypes.html#navmesh) . Pros: * Can represent small details and large areas at the same time. * Pathfinding is fast due to the low node count. * Supports large worlds. * Fast updates using [Navmesh Cutting](https://arongranberg.com/astar/docs/navmeshcutting.html) (limited to mostly cutting out holes in the navmesh). * Decently fast graph updates that recalculate whole recast graph tiles. * Comparatively low memory usage. Cons: * Can be slow to scan, especially if you need very high detail or very large worlds. * Slower to update than a grid graph (but navmesh cutting is faster if you can use it). * Large undulating empty regions, like a hill without any trees or obstacles, can be hard for the recast graph to represent well. Though, enabling tiling can help break up the large nodes. * Recast graphs are worse at representing tags and penalties. They can do it just fine, but the results will not be as precise and predictable as with a grid-based graph. See [RecastGraph](https://arongranberg.com/astar/docs/recastgraph.html) [Get started with recast graphs](https://arongranberg.com/astar/docs/getstartedrecast.html) Navmesh Graph ------------- The navmesh graph represents the pathfinding data as a triangle mesh instead of squares ([Grid Graph](https://arongranberg.com/astar/docs/graphtypes.html#grid) ) or points ([Point Graph](https://arongranberg.com/astar/docs/graphtypes.html#point) ). This is perfect for smooth and fast pathfinding where the graph doesn't need much changing during runtime. It is often faster than a grid graph since it usually contains fewer nodes and thus requires less searching. The paths returned from it can be used directly, but the funnel modifier is strongly recommended. The system can generate navmeshes automatically (see [Recast Graph - A\* Pro Only](https://arongranberg.com/astar/docs/graphtypes.html#recast) ), but with this graph you will have to create them yourself in your favorite 3D modeling application. A navmesh is a mesh where the polygons describe the walkable area. Vertices should always (except possibly in some special cases) lie at the edges of the mesh, not in the middle of it (i.e., a vertex with polygons surrounding it). It can also be good to split very long edges because similarly sized polygons yield better paths than really big and really small polygons next to each other. ![](https://arongranberg.com/astar/docs/images/navmeshgraph_graph.png) Pros: * Can represent small details and large areas at the same time. * Pathfinding is fast due to the low node count. * Supports large worlds. * Pretty fast updates using [Navmesh Cutting](https://arongranberg.com/astar/docs/navmeshcutting.html) (limited to mostly cutting out holes in the navmesh). * Comparatively low memory usage. * Fast to scan. Cons: * Requires a lot of manual work to create the navmesh. * Navmesh graphs are bad at representing tags and penalties. They can do it just fine, but the results will not be as precise and predictable as with a grid-based graph. See [NavMeshGraph](https://arongranberg.com/astar/docs/navmeshgraph.html) [Creating a navmesh manually](https://arongranberg.com/astar/docs/createnavmesh.html) [Using navmeshes](https://arongranberg.com/astar/docs/getstarted2.html) Point Graph ----------- ![](https://arongranberg.com/astar/docs/images/generated/scenes/PointGraph/pointgraphbanner.png) The PointGraph is the simplest of all graph types, but allows for a lot of customization. It consists of a set of user-placed points which are linked together. A point graph is scanned by taking a root Transform, and treating every child of it as a node. It then checks for possible connections between the nodes using raycasts to see if they should be linked together. Getting good and smooth paths from a point graph can be hard as they only define a point of walkability, not an area like the other graph types. The raycast modifier does a decent job, though. A common issue with point graphs is that getting the "right" closest node can be hard without adding a lot of nodes. For example, if an agent moves close to a wall, the closest node might be on the other side of a wall. You can mitigate this by ensuring that you don't place your nodes too sparsely. Using this graph type is discouraged unless the other graph types just don't work for your game. Pros: * You are in full control over where nodes are placed. You can even make 3D pathfinding with this. * Fast to scan for simple cases, but can get very slow if you are not careful with your settings. Cons: * Requires a lot of manual work to place all the nodes (or you have to write a script to do it automatically). * It's hard to get good quality paths without a very large number of nodes. * Pathfinding is often slow due to the high node count that is required. * Slow graph updates. See [PointGraph](https://arongranberg.com/astar/docs/pointgraph.html) [Get started with point graphs](https://arongranberg.com/astar/docs/getstartedpoint.html) --- # The A* Inspector - A* Pathfinding Project The A\* Inspector ================= Brief overview of the various settings in the A\* inspector. ![](https://arongranberg.com/astar/docs/images/inspector/inspector@2x.png) The inspector of the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component has 5 sections. * [Graphs](https://arongranberg.com/astar/docs/inspector.html#inspector-graphs) : holds a list of all graphs in the scene * [Settings](https://arongranberg.com/astar/docs/inspector.html#inspector-settings) : various pathfinding and editor settings * [Save & Load](https://arongranberg.com/astar/docs/inspector.html#inspector-save-load) : allows you to save and load graphs from files * [Optimization](https://arongranberg.com/astar/docs/inspector.html#inspector-optimization) : various optimizations that can be applied to the system using compiler directives * [About](https://arongranberg.com/astar/docs/inspector.html#inspector-about) : info about which version you have and some links to the documentation There is also the 'Show Graphs' toggle which enables or disables the graphs from being rendered in the scene view, and lastly there is the 'Scan' button which recalculates all graphs. In the editor, graphs are not scanned unless you press this button (or use the keyboard shortcut, see [Keyboard Shortcuts](https://arongranberg.com/astar/docs/shortcuts.html) ). Graphs ------ ![](https://arongranberg.com/astar/docs/images/inspector/graphs@2x.png) In the graphs tab, you can see all graphs that are in the current scene. You may have multiple graphs and they are all stored in the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component (you do not create multiple [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) components). If you click on the 'Add New Graph' button, you will see a list of all graph types that you can create. There are several graph types available in the package. Grids, manually created navmeshes, automatically created navmeshes (called recast graphs), point graphs, and you can even write your own custom graph types. Next to each graph there are 5 icons. ![](https://arongranberg.com/astar/docs/images/inspector/edit_icons@2x.png) They are: * **eye**: Shows or hides the graph from being rendered in the scene view. When the graph is hidden, this icon will turn red. * **pen**: Click on the pen to rename the graph. This can be very useful if you have many graphs and it is becoming hard to keep track of which one is which. * **i**: Clicking on the 'i' shows some information about how many nodes there are in the graph. Note that you must scan the graph for it to show anything relevant. * **duplicate**: Duplicates the graph. This can be useful if you want to have two graphs with only slightly different settings. * **trash can**: Deletes the graph. Take a look at each graph's respective documentation for more info about their settings. See [Graph Types](https://arongranberg.com/astar/docs/graphtypes.html) Settings -------- ![](https://arongranberg.com/astar/docs/images/inspector/settings@2x.png) This section contains all global pathfinding and logging settings. Here you can you can for example set the [number of threads to use for pathfinding](https://arongranberg.com/astar/docs/astarpath.html#threadCount) (note that this is only for pathfinding, when graphs are scanned, they typically use the unity job system, which uses all cores of the machine). Or you can tweak the [logging settings](https://arongranberg.com/astar/docs/astarpath.html#logPathResults) to get more information about what the system is doing. ### Pathfinding Thread Count Number of pathfinding threads to use. Multithreading puts pathfinding in another thread, this is great for performance on 2+ core computers since the framerate will barely be affected by the pathfinding at all. * None indicates that the pathfinding is run in the Unity thread as a coroutine * Automatic will try to adjust the number of threads to the number of cores and memory on the computer. Less than 512mb of memory or a single core computer will make it revert to using no multithreading. It is recommended that you use one of the "Auto" settings that are available. The reason is that even if your computer might be beefy and have 8 cores. Other computers might only be quad core or dual core in which case they will not benefit from more than 1 or 3 threads respectively (you usually want to leave one core for the unity thread). If you use more threads than the number of cores on the computer it is mostly just wasting memory, it will not run any faster. The extra memory usage is not trivially small. Each thread needs to keep a small amount of data for each node in all the graphs. It is not the full graph data but it is proportional to the number of nodes. The automatic settings will inspect the machine it is running on and use that to determine the number of threads so that no memory is wasted. The exception is if you only have one (or maybe two characters) active at time. Then you should probably just go with one thread always since it is very unlikely that you will need the extra throughput given by more threads. Keep in mind that more threads primarily increases throughput by calculating different paths on different threads, it will not calculate individual paths any faster. Warning If you are modifying the pathfinding core scripts or if you are directly modifying graph data without using any of the safe wrappers (like [AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) ), multithreading can cause strange errors and cause pathfinding to stop working if you are not careful. Note WebGL does not support threads at all (since javascript is single-threaded) so no threads will be used on that platform. This setting only applies to pathfinding. Graph updates use the Unity Job System, which uses a different thread pool. See CalculateThreadCount A\* Pro Feature This is an A\* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A\* Pathfinding Project or the functionality might be limited. The Pro version can be bought [here](http://www.arongranberg.com/astar/buy) See This setting corresponds to the member [AstarPath.threadCount](https://arongranberg.com/astar/docs/astarpath.html#threadCount) Max Nearest Node Distance Maximum distance to search for nodes. When searching for the nearest node to a point, this is the limit (in world units) for how far away it is allowed to be. This is relevant if you try to request a path to a point that cannot be reached and it thus has to search for the closest node to that point which can be reached (which might be far away). If it cannot find a node within this distance then the path will fail. ![](https://arongranberg.com/astar/docs/images/max_nearest_node_distance@2x.png) See [NearestNodeConstraint.maxDistance](https://arongranberg.com/astar/docs/nearestnodeconstraint.html#maxDistance) See This setting corresponds to the member [AstarPath.maxNearestNodeDistance](https://arongranberg.com/astar/docs/astarpath.html#maxNearestNodeDistance) Heuristic The distance function to use as a heuristic. The heuristic, often referred to as just 'H' is the estimated cost from a node to the target. Different heuristics affect how the path picks which one to follow from multiple possible with the same length See [Pathfinding.Heuristic](https://arongranberg.com/astar/docs/pathfinding.html#Heuristic) for more details and descriptions of the different modes. [Wikipedia: Admissible heuristic](https://en.wikipedia.org/wiki/Admissible_heuristic) [Wikipedia: A\* search algorithm](https://en.wikipedia.org/wiki/A*_search_algorithm) [Wikipedia: Dijkstra's Algorithm](https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm) Warning Reducing the heuristic scale below 1, or disabling the heuristic, can significantly increase the cpu cost for pathfinding, especially for large graphs. See This setting corresponds to the member [AstarPath.heuristic](https://arongranberg.com/astar/docs/astarpath.html#heuristic) Heuristic Scale The scale of the heuristic. If a value lower than 1 is used, the pathfinder will search more nodes (slower). If 0 is used, the pathfinding algorithm will be reduced to dijkstra's algorithm. This is equivalent to setting [heuristic](https://arongranberg.com/astar/docs/astarpath.html#heuristic) to None. If a value larger than 1 is used the pathfinding will (usually) be faster because it expands fewer nodes, but the paths may no longer be the optimal (i.e the shortest possible paths). Usually you should leave this to the default value of 1. Warning Reducing the heuristic scale below 1, or disabling the heuristic, can significantly increase the cpu cost for pathfinding, especially for large graphs. See [Wikipedia: Admissible heuristic](https://en.wikipedia.org/wiki/Admissible_heuristic) [Wikipedia: A\* search algorithm](https://en.wikipedia.org/wiki/A*_search_algorithm) [Wikipedia: Dijkstra's Algorithm](https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm) See This setting corresponds to the member [AstarPath.heuristicScale](https://arongranberg.com/astar/docs/astarpath.html#heuristicScale) ### Advanced Heuristic Optimization If heuristic optimization should be used and how to place the pivot points. See [Heuristic Optimization](https://arongranberg.com/astar/docs/heuristicopt.html) Game AI Pro - [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) Architecture Optimizations by Steve Rabin and Nathan R. Sturtevant See This setting corresponds to the member [EuclideanEmbedding.mode](https://arongranberg.com/astar/docs/euclideanembedding.html#mode) Batch Graph Updates Throttle graph updates and batch them to improve performance. If toggled, graph updates will batched and executed less often (specified by [graphUpdateBatchingInterval](https://arongranberg.com/astar/docs/astarpath.html#graphUpdateBatchingInterval) ). This can have a positive impact on pathfinding throughput since the pathfinding threads do not need to be stopped as often, and it reduces the overhead per graph update. All graph updates are still applied, they are just batched together so that more of them are applied at the same time. Do not use this if you want minimal latency between a graph update being requested and it being applied. This only applies to graph updates requested using the [UpdateGraphs](https://arongranberg.com/astar/docs/astarpath/updategraphs.html#UpdateGraphs3) method. Not those requested using [AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) . If you want to apply graph updates immediately at some point, you can call [FlushGraphUpdates](https://arongranberg.com/astar/docs/astarpath/flushgraphupdates.html#FlushGraphUpdates) . See [Graph Updates during Runtime](https://arongranberg.com/astar/docs/graphupdates.html) See This setting corresponds to the member [AstarPath.batchGraphUpdates](https://arongranberg.com/astar/docs/astarpath.html#batchGraphUpdates) Update Interval Minimum number of seconds between each batch of graph updates. If [batchGraphUpdates](https://arongranberg.com/astar/docs/astarpath.html#batchGraphUpdates) is true, this defines the minimum number of seconds between each batch of graph updates. This can have a positive impact on pathfinding throughput since the pathfinding threads do not need to be stopped as often, and it reduces the overhead per graph update. All graph updates are still applied however, they are just batched together so that more of them are applied at the same time. Do not use this if you want minimal latency between a graph update being requested and it being applied. This only applies to graph updates requested using the [UpdateGraphs](https://arongranberg.com/astar/docs/astarpath/updategraphs.html#UpdateGraphs3) method. Not those requested using [AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) . See [Graph Updates during Runtime](https://arongranberg.com/astar/docs/graphupdates.html) See This setting corresponds to the member [AstarPath.graphUpdateBatchingInterval](https://arongranberg.com/astar/docs/astarpath.html#graphUpdateBatchingInterval) Scan on Awake If true, all graphs will be scanned when the game starts, during OnEnable. If you disable this, you will have to call [AstarPath.active.Scan](https://arongranberg.com/astar/docs/astarpath/scan.html) yourself to enable pathfinding. Alternatively you could load a saved graph from a file. If a startup cache has been generated (see [Saving and Loading Graphs](https://arongranberg.com/astar/docs/saveloadgraphs.html) ), it always takes priority, and the graphs will be loaded from the cache instead of scanned. This can be useful to disable if you want to scan your graphs asynchronously, or if you have a procedural world which has not been created yet at the start of the game. See [Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) [ScanAsync](https://arongranberg.com/astar/docs/astarpath/scanasync.html#ScanAsync) See This setting corresponds to the member [AstarPath.scanOnStartup](https://arongranberg.com/astar/docs/astarpath.html#scanOnStartup) ### Debug Path Logging The amount of debugging messages. Use less debugging to improve performance (a bit) or just to get rid of the Console spamming. Use more debugging (heavy) if you want more information about what the pathfinding scripts are doing. The InGame option will display the latest path log using in-game GUI. ![](https://arongranberg.com/astar/docs/images/path_logging@2x.png) See This setting corresponds to the member [AstarPath.logPathResults](https://arongranberg.com/astar/docs/astarpath.html#logPathResults) Graph Coloring The mode to use for drawing nodes in the sceneview. Note Only relevant in the editor See [GraphDebugMode](https://arongranberg.com/astar/docs/pathfinding.html#GraphDebugMode) See This setting corresponds to the member [AstarPath.debugMode](https://arongranberg.com/astar/docs/astarpath.html#debugMode) Show Search Tree If enabled, nodes will draw a line to their 'parent'. This will show the search tree for the latest path. Note Only relevant in the editor See This setting corresponds to the member [AstarPath.showSearchTree](https://arongranberg.com/astar/docs/astarpath.html#showSearchTree) Show Unwalkable Nodes Toggle to show unwalkable nodes. Note Only relevant in the editor See [unwalkableNodeDebugSize](https://arongranberg.com/astar/docs/astarpath.html#unwalkableNodeDebugSize) See This setting corresponds to the member [AstarPath.showUnwalkableNodes](https://arongranberg.com/astar/docs/astarpath.html#showUnwalkableNodes) Graph Update Debug Mode How to visualize graph updates in the editor. This is used to visualize the bounds of graph updates, and how they affect the graph. If [showGraphsInStandalonePlayer](https://arongranberg.com/astar/docs/astarpath.html#showGraphsInStandalonePlayer) is enabled, the visualization will also be shown in a standalone player. ![](https://arongranberg.com/astar/docs/images/graph_update_debug_mode_inspector@2x.png) ![](https://arongranberg.com/astar/docs/images/graph_update_debug_mode.png) See [GraphUpdateDebugMode](https://arongranberg.com/astar/docs/pathfinding.html#GraphUpdateDebugMode) for more info about the different modes. See This setting corresponds to the member [AstarPath.graphUpdateDebugMode](https://arongranberg.com/astar/docs/astarpath.html#graphUpdateDebugMode) Show Graphs In Standalone Player Shows or hides the graph visualizations in standalone games. Normally, graph visualizations are only shown in the editor. If this is set to true, the graph visualizations will also be shown in standalone games. Note In the editor, this setting has no effect. [showNavGraphs](https://arongranberg.com/astar/docs/astarpath.html#showNavGraphs) will be ignored in standalone builds, and this value will be used instead. See [NavGraph.drawGizmos](https://arongranberg.com/astar/docs/navgraph.html#drawGizmos) See This setting corresponds to the member [AstarPath.showGraphsInStandalonePlayer](https://arongranberg.com/astar/docs/astarpath.html#showGraphsInStandalonePlayer) ### Colors Here you can set the colors to be used in the scene view to visualize the graphs. ### Tag Names Here you can set the names of all tags. See [Working with tags](https://arongranberg.com/astar/docs/tags.html) ### Editor Smooth Transitions Animate dropdowns when they open and close. See This setting corresponds to the member [FadeArea.fancyEffects](https://arongranberg.com/astar/docs/fadearea.html#fancyEffects) Save & Load ----------- ![](https://arongranberg.com/astar/docs/images/inspector/saveloadtab@2x.png) This section allows you to save and load graphs to and from files. Typically, the graphs will be scanned when the game starts. But if you have a large world, this may take some time. In that case, you can cache the scanned graph, so that it becomes much faster to load. See Take a look at this page for more information: [Saving and Loading Graphs](https://arongranberg.com/astar/docs/saveloadgraphs.html) Optimization ------------ ![](https://arongranberg.com/astar/docs/images/inspector/optimization@2x.png) This section contains various features that can be enabled or disabled project-wide, using compiler directives. You typically do not have to touch these at all. But they can in some cases give you small performance or memory improvements. See Take a look at this page for more information: [Compiler Directives](https://arongranberg.com/astar/docs/compilerdirectives.html) About ----- ![](https://arongranberg.com/astar/docs/images/inspector/about.png) This section shows the current version and links to the documentation. Note This always links to the latest non-beta documentation; however, you can find the documentation for older versions or beta releases by clicking on the 'Show Older Versions' button on the download page: [https://www.arongranberg.com/astar/download](https://www.arongranberg.com/astar/download) Show Graphs ----------- This toggle, at the bottom of the inspector, enables or disables the graphs from being rendered in the scene view. Show Graphs Visualize graphs in the scene view (editor only). ![](https://arongranberg.com/astar/docs/images/navmeshgraph_graph.png) See [showGraphsInStandalonePlayer](https://arongranberg.com/astar/docs/astarpath.html#showGraphsInStandalonePlayer) See This setting corresponds to the member [AstarPath.showNavGraphs](https://arongranberg.com/astar/docs/astarpath.html#showNavGraphs) Scan button ----------- The scan button at the bottom of the inspector is used to calculate the graphs based on their settings and the world. When editing settings in the inspector, it's handy to know that there's also a shortcut for scanning the graphs: Cmd+Alt+S (mac) or Ctrl+Alt+S (windows). The graphs will also be [scanned automatically](https://arongranberg.com/astar/docs/astarpath.html#scanOnStartup) when the game starts, by default. --- # Migrating from Unity Navigation - A* Pathfinding Project Migrating from Unity Navigation =============================== Guide to help you migrate from Unity Navigation to the A\* Pathfinding Project. In this guide, you will learn what Unity components correspond to which A\* Pathfinding Project components and what major differences there are. Feature comparison ------------------ If you are looking for a comparison between Unity's pathfinding and the A\* Pathfinding Project, you might be interested in this page: [Feature Comparison](https://arongranberg.com/astar/freevspro) . Architectural differences ------------------------- The overall architecture is not too different; in both packages there are: * Movement scripts, which tell the agent how to move and where it should move. * Graphs, which describe where an agent can move. * Temporary obstacles, which cut holes in the navmesh or update it in other ways. * Off-mesh links, which allow an agent to move or jump between otherwise disconnected parts of the navmesh. However, the names used differ between the packages. | Unity | A\* Pathfinding Project | | --- | --- | | Navigation Window | The [AstarPath](https://arongranberg.com/astar/docs/astarpath.html)
component | | NavMesh Agent component | There are multiple movement scripts in this package. The [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html)
is a single component can be used as a pretty close replacement. If you use one of the other included movement scripts, the movement and path calculations are split into two components: the [Seeker](https://arongranberg.com/astar/docs/seeker.html)
, which calculates paths, and [a movement script](https://arongranberg.com/astar/docs/movementscripts.html)
that follows the path ( [AILerp](https://arongranberg.com/astar/docs/ailerp.html)
/ [AIPath](https://arongranberg.com/astar/docs/aipath.html)
/ [RichAI](https://arongranberg.com/astar/docs/richai.html)
/[your own](https://arongranberg.com/astar/docs/custom_movement_script.html)
) | | Off-Mesh Link component | The [NodeLink2](https://arongranberg.com/astar/docs/nodelink2.html)
component | | NavMesh Obstacle | The [NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html)
component is closest analogue, but there are also other kinds of obstacles and ways to do graph updates in this package. See [Graph Updates during Runtime](https://arongranberg.com/astar/docs/graphupdates.html)
. | Graph settings -------------- Unity has a single graph type which automatically generates a navmesh. It is very similar to the [RecastGraph](https://arongranberg.com/astar/docs/recastgraph.html) in the A\* Pathfinding Project. If you create a recast graph in this package, its settings will most likely seem familiar to you. This package has several other graph types, however. For example, grid graphs, point graphs and navmesh graphs. See Read more about other graph types here: [Graph Types](https://arongranberg.com/astar/docs/graphtypes.html) . Local avoidance --------------- Unity's package and this package both have local avoidance, and they work in a similar way. If you are using the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) movement script, it's built-in, like with Unity's NavMesh Agent. If you are using another movement script, it is handled by a separate component called the [RVOController](https://arongranberg.com/astar/docs/rvocontroller.html) . You attach the [RVOController](https://arongranberg.com/astar/docs/rvocontroller.html) to an object which already has a [movement script](https://arongranberg.com/astar/docs/movementscripts.html) to make it use local avoidance. You will also need a single global instance of the [RVOSimulator](https://arongranberg.com/astar/docs/rvosimulator.html) component, which handles all the calculations and has the global simulation settings. See Read more about local avoidance here: [Local Avoidance](https://arongranberg.com/astar/docs/localavoidance.html) . AI Properties and methods ------------------------- When interacting with a movement script, the names again differ between Unity's package and this package. Here's a list of the most used properties/methods and their corresponding properties/methods in this package: The [IAstarAI](https://arongranberg.com/astar/docs/iastarai.html) interface is referenced here, which is an interface that all movement scripts (e.g. [AIPath](https://arongranberg.com/astar/docs/aipath.html) / [AILerp](https://arongranberg.com/astar/docs/ailerp.html) / [RichAI](https://arongranberg.com/astar/docs/richai.html) ) implement. | Unity | A\* Pathfinding Project | | --- | --- | | NavMeshAgent.areaMask | [Seeker.traversableTags](https://arongranberg.com/astar/docs/seeker.html#traversableTags)
or [FollowerEntity.pathfindingSettings.traversableTags](https://arongranberg.com/astar/docs/pathrequestsettings.html#traversableTags) | | NavMeshAgent.avoidancePriority | [RVOController.priority](https://arongranberg.com/astar/docs/rvocontroller.html#priority)
, but the range is reversed (0 is the lowest priority) | | NavMeshAgent.CalculatePath | [IAstarAI.SearchPath](https://arongranberg.com/astar/docs/iastarai/searchpath.html#SearchPath)
, but take a look at [Searching for paths](https://arongranberg.com/astar/docs/callingpathfinding.html)
for more info | | NavMeshAgent.currentOffMeshLinkData | [FollowerEntity.offMeshLink](https://arongranberg.com/astar/docs/followerentity.html#offMeshLink)
(not available for other movement scripts) | | NavMeshAgent.desiredVelocity | [IAstarAI.desiredVelocity](https://arongranberg.com/astar/docs/iastarai.html#desiredVelocity) | | NavMeshAgent.destination | [IAstarAI.destination](https://arongranberg.com/astar/docs/iastarai.html#destination) | | NavMeshAgent.stoppingDistance | [FollowerEntity.movementSettings.stopDistance](https://arongranberg.com/astar/docs/movementsettings.html#stopDistance)
, [RichAI.endReachedDistance](https://arongranberg.com/astar/docs/aibase.html#endReachedDistance)
, [AIPath.endReachedDistance](https://arongranberg.com/astar/docs/aibase.html#endReachedDistance) | | NavMeshAgent.GetAreaCost | [Seeker.tagCostMultipliers](https://arongranberg.com/astar/docs/seeker.html#tagCostMultipliers)
, [Seeker.tagEntryCosts](https://arongranberg.com/astar/docs/seeker.html#tagEntryCosts)
, [FollowerEntity.pathfindingSettings.tagCostMultipliers](https://arongranberg.com/astar/docs/pathrequestsettings.html#tagCostMultipliers)
or [FollowerEntity.pathfindingSettings.tagEntryCosts](https://arongranberg.com/astar/docs/pathrequestsettings.html#tagEntryCosts) | | NavMeshAgent.hasPath | [IAstarAI.hasPath](https://arongranberg.com/astar/docs/iastarai.html#hasPath) | | NavMeshAgent.isOnOffMeshLink | [FollowerEntity.isTraversingOffMeshLink](https://arongranberg.com/astar/docs/followerentity.html#isTraversingOffMeshLink)
(not available for other movement scripts) | | NavMeshAgent.isPathStale | [FollowerEntity.hasPath](https://arongranberg.com/astar/docs/followerentity.html#hasPath)
will become false when the path is stale (not available for other movement scripts) | | NavMeshAgent.isStopped | [IAstarAI.isStopped](https://arongranberg.com/astar/docs/iastarai.html#isStopped) | | NavMeshAgent.Move | [IAstarAI.Move](https://arongranberg.com/astar/docs/iastarai/move.html#Move) | | NavMeshAgent.nextOffMeshLinkData | [IAstarAI.GetRemainingPath(List,List,bool)](https://arongranberg.com/astar/docs/iastarai/getremainingpath.html#GetRemainingPath2)
can be used to get all off-mesh links in the path, if you use the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html)
or [RichAI](https://arongranberg.com/astar/docs/richai.html)
movement scripts | | NavMeshAgent.pathPending | [IAstarAI.pathPending](https://arongranberg.com/astar/docs/iastarai.html#pathPending) | | NavMeshAgent.Raycast | [AstarPath.Linecast](https://arongranberg.com/astar/docs/astarpath/linecast.html)
. See [Detecting obstacles along a line](https://arongranberg.com/astar/docs/linecasting.html) | | NavMeshAgent.remainingDistance | [IAstarAI.remainingDistance](https://arongranberg.com/astar/docs/iastarai.html#remainingDistance) | | NavMeshAgent.ResetPath | [IAstarAI.SetPath](https://arongranberg.com/astar/docs/iastarai/setpath.html#SetPath)
(null) | | NavMeshAgent.SamplePathPosition | There's no direct analogue, but it can be calculated using [IAstarAI.GetRemainingPath](https://arongranberg.com/astar/docs/iastarai/getremainingpath.html) | | NavMeshAgent.SetAreaCost | [Seeker.tagCostMultipliers](https://arongranberg.com/astar/docs/seeker.html#tagCostMultipliers)
, [Seeker.tagEntryCosts](https://arongranberg.com/astar/docs/seeker.html#tagEntryCosts)
, [FollowerEntity.pathfindingSettings.tagCostMultipliers](https://arongranberg.com/astar/docs/pathrequestsettings.html#tagCostMultipliers)
or [FollowerEntity.pathfindingSettings.tagEntryCosts](https://arongranberg.com/astar/docs/pathrequestsettings.html#tagEntryCosts) | | NavMeshAgent.SetDestination | [IAstarAI.destination](https://arongranberg.com/astar/docs/iastarai.html#destination) | | NavMeshAgent.SetPath | [IAstarAI.SetPath](https://arongranberg.com/astar/docs/iastarai/setpath.html#SetPath) | | NavMeshAgent.speed | [IAstarAI.maxSpeed](https://arongranberg.com/astar/docs/iastarai.html#maxSpeed) | | NavMeshAgent.updatePosition | [IAstarAI.updatePosition](https://arongranberg.com/astar/docs/iastarai.html#updatePosition) | | NavMeshAgent.updateRotation | [IAstarAI.updateRotation](https://arongranberg.com/astar/docs/iastarai.html#updateRotation) | | NavMeshAgent.velocity | [IAstarAI.velocity](https://arongranberg.com/astar/docs/iastarai.html#velocity) | | NavMeshAgent.Warp | [IAstarAI.Teleport](https://arongranberg.com/astar/docs/iastarai/teleport.html#Teleport) | See [IAstarAI](https://arongranberg.com/astar/docs/iastarai.html) for more properties and methods on the movement scripts, and [Seeker](https://arongranberg.com/astar/docs/seeker.html) for more settings related to the path calculation. --- # Error messages - A* Pathfinding Project Error messages ============== Detailed explanations of various error messages that you may see when using the package. See [Installation Errors](https://arongranberg.com/astar/docs/installation.html#installation-errors) Path error messages ------------------- These are errors that you may get when searching for paths. None of these errors are fatal in any way; they just mean that the system couldn't find a valid path for some reason. ### Couldn't find a node close to the start point When a path request is started, it will query the pathfinding system for the closest node (a node is one tile in a grid graph, one triangle in a navmesh/recast graph and one point in a PointGraph) to the start point of the path. This search has a limited range, though usually it is more than enough for all practical purposes. So if you try to request a path starting from a point that is nowhere near any (walkable) nodes on any graph, then this error will be logged. Ways to resolve this error: * Make sure that the starting point of your path request is correct. * If you are using one of the included movement scripts, make sure that the AI starts somewhere reasonably close to the graph. * If you know that your starting point \*is\* correct and you really do want to just extend the search, then increase the [AstarPath.maxNearestNodeDistance](https://arongranberg.com/astar/docs/astarpath.html#maxNearestNodeDistance) field. However, know that having to search very far for the closest node may have an impact on performance. ### Couldn't find a node close to the end point This is very similar to the error above. However, when searching for the closest end node to the end point, the system has an additional constraint in that the node must not only be walkable, it must also be able to be reached from the starting node. A common case when this error shows up is if the AI is, say, locked in a small room on one end of the map and gets an order to move to a point very far away. When trying to find a node close to the end point, it will have to search a very large distance since only the nodes inside that small room are reachable from the starting node. Ways to resolve this error: * See previous error. ### Searched whole area but could not find target This means that there is no possible path from the start node to the end node. Usually this happens if you are using tags and are configuring them so that some tags cannot be traversed. With regular walkability, the system precalculates which nodes of the graph can be reached from which other nodes; however, with tags it is not possible to do this. This image shows the nodes that were searched when all tags could be traversed. Note that all nodes inside the red rectangle have a modified tag. ![](https://arongranberg.com/astar/docs/images/errors/searched_whole_area1.png) This image shows the nodes that were searched when the nodes inside the red rectangle could not be traversed due to their changed tag. Note that every single node that could be reached from the start node had to be traversed in order for the system to come to this conclusion. ![](https://arongranberg.com/astar/docs/images/errors/searched_whole_area2.png) ### No open points, the start node didn't open any nodes This error is just a special case of the previous error. It is logged when only a single node was searched in the path and the end of the path could not be found. This particular error often happens due to a simple configuration error of grid graphs. If the AI has a collider and that collider is included in the Height Testing layer mask in the graph settings, then it may happen that the graph places a node on top of the AI's head (see image). ![](https://arongranberg.com/astar/docs/images/errors/node_on_top_of_ai.png) The result is that the AI thinks it is locked inside a very tiny room and cannot get out from there. Ways to resolve this error: * Make sure that the AI is in a layer that is not included in the Height Testing layer mask. ![](https://arongranberg.com/astar/docs/images/errors/grid_height_testing@2x.png) See [GraphCollision.heightMask](https://arongranberg.com/astar/docs/graphcollision.html#heightMask) [https://docs.unity3d.com/Manual/Layers.html](https://docs.unity3d.com/Manual/Layers.html) ### Canceled path because a new one was requested The [Seeker](https://arongranberg.com/astar/docs/seeker.html) component only handles a single path request at a time. Since path requests are asynchronous, it may happen that a script tries to start to calculate a path before the previous path has been fully calculated. There are several times when this is reasonable; for example, the agent might have teleported to another part of the map, then any previous path calculations would be pretty useless. In any case, when this happens the Seeker will cancel the previous path request and set this error message as the reason for it failing. If you are seeing this message even when you are just trying to calculate paths normally, it may be because your script is not properly waiting for the previous path to be calculated before starting a new path calculation. You can check if the Seeker is done calculating by calling the [Seeker.IsDone](https://arongranberg.com/astar/docs/seeker/isdone.html#IsDone) method, or you could simply wait until the OnPathComplete callback is called. ### Canceled by script (Seeker.CancelCurrentPathRequest) This is very similar to the previous error message, but it means some script canceled the path request using the [Seeker.CancelCurrentPathRequest](https://arongranberg.com/astar/docs/seeker/cancelcurrentpathrequest.html#CancelCurrentPathRequest) method. As the path was canceled explicitly by a script, one can reasonably assume that the script knows what it is doing, so you likely do not need to worry if you see this message. ### There are no graphs in the scene The [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component does not contain any graphs at all. If you are loading graphs from a file or creating a graph using a script, it seems that some other script is trying to request a path before that has been done. Graph errors ------------ ### Some meshes were statically batched... `Some meshes were statically batched. These meshes cannot be used for navmesh calculation due to technical constraints. During runtime scripts cannot access the data of meshes which have been statically batched. One way to solve this problem is to use cached startup (Save & Load tab in the inspector) to only calculate the graph when the game is not playing. `Unity's static batching system is great because it can combine multiple draw calls into a single draw call to improve the performance of your game. Unfortunately, in doing this Unity also makes it impossible for this package's scripts to read the mesh data during runtime (except in the Unity editor). For recast graphs, this means that those meshes cannot be used to generate a graph during runtime. This image shows the toggle that Unity uses for static batching. ![](https://arongranberg.com/astar/docs/images/errors/static_batching@2x.png) Ways to resolve this error: * You can use colliders instead of meshes to generate the recast graph (see recast graph settings). This is also usually faster since colliders are generally less detailed than meshes used for rendering. * You can calculate the graph in the editor and then just load it from a file when starting the game. This is very easy to do using the 'Cached Startup' feature that this package has. This also has the bonus of significantly improving your game's startup time since loading a graph from a file is much faster than generating it from scratch. The downside is that it does not work with procedural levels that are generated during runtime. Take a look at [Saving and Loading Graphs](https://arongranberg.com/astar/docs/saveloadgraphs.html) for more info. * It is possible to statically batch geometry during runtime \*after\* the graph has been generated. Take a look at [https://docs.unity3d.com/ScriptReference/StaticBatchingUtility.html](https://docs.unity3d.com/ScriptReference/StaticBatchingUtility.html) . * You can, of course, also simply not use static batching. Compiler errors --------------- If the package did not install or upgrade correctly, you may see some compiler errors. If you have just upgraded the package, the easiest way to make sure UnityPackages have not messed something up is to delete the AstarPathfindingProject folder (and the AstarPathfindingEditor folder too if you have it) and then import the package again. Otherwise, I recommend searching the [forum](http://forum.arongranberg.com/) for threads that mention similar errors. --- # Recast graph in a 3D game - A* Pathfinding Project Recast graph in a 3D game ========================= Example scene which demonstrates a recast graph in a 3D level. ![](https://arongranberg.com/astar/docs/images/generated/scenes/Recast3D/overview.png) This example scene demonstrates how to use a recast graph in a 3D game. It also demonstrates how to use the [Interactable](https://arongranberg.com/astar/docs/interactable.html) component to create simple interactive objects, and it contains an example of an off-mesh link, and how to use the [NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) component to create dynamic obstacles on recast graphs. There's a single agent in the scene that you can move around by clicking on the ground. You can also press "P" to spawn a dynamic obstacle in the form of a small box that falls down on the ground. Contents -------- * [Graph setup](https://arongranberg.com/astar/docs/example_recast3d.html#example_recast3d_graph) * [Chests](https://arongranberg.com/astar/docs/example_recast3d.html#example_recast3d_chests) * [Off-mesh link](https://arongranberg.com/astar/docs/example_recast3d.html#example_recast3d_droplink) * [Navmesh cutting](https://arongranberg.com/astar/docs/example_recast3d.html#example_recast3d_navmeshcut) * [Character animation](https://arongranberg.com/astar/docs/example_recast3d.html#exampl_recast3d_character_animation) Graph setup ----------- ![](https://arongranberg.com/astar/docs/images/generated/scenes/Recast3D/graphsettings@2x.png) The graph used in this scene is a [RecastGraph](https://arongranberg.com/astar/docs/recastgraph.html) . A recast graph has been chosen because: * It supports the overhangs and bridges that are present in this scene. * It can easily represent the required level of detail. * It easily supports the dynamic obstacles that are present in this scene, with good precision. A layered grid graph could also have been used for this scene. But it would likely have required a higher level of detail to represent the dynamic obstacles well. This scene does not benefit from the layered grid graph's better support for granular tags and penalties, and the world is itself not grid-based, so a recast graph is a better fit. Chests ------ This example scene contains a few chests which can be opened by the player by clicking on them. Your browser does not support the video tag. These chests use the [Interactable](https://arongranberg.com/astar/docs/interactable.html) component to implement a simple state machine which controls the animation of the chest and movement of the character. ![](https://arongranberg.com/astar/docs/images/generated/scenes/Recast3D/chestinteractable@2x.png) Note The [Interactable](https://arongranberg.com/astar/docs/interactable.html) component is a very simple state machine implementation which is intended for the example scenes. In a real game, you would probably want to use a more advanced state machine implementation, but this script can serve as a good example if you want to write your own state machine code for your game. The [TargetMover](https://arongranberg.com/astar/docs/targetmover.html) component on the main camera contains code which detects if the player clicks on an interactable object and if so, it will start the interaction. In this case, the interactable is configured to perform the following steps: 1. Spawn the same "move here" particle effect as when the player normally clicks somewhere on the ground. 2. Make the agent move to the chest, and rotate to face it. 3. Play the chest opening animation and spawn some particle effects. Off-mesh link ------------- In one corner of the map there's a ledge which the agent can jump down from. This is implemented using a [NodeLink2](https://arongranberg.com/astar/docs/nodelink2.html) component. Your browser does not support the video tag. Off-mesh links connect two parts of the navmesh that are not normally connected. They are used for things like jumping down from ledges, climbing ladders, opening doors, etc. This off-mesh link is configured with a start point at the top of the ledge, and the end point at the bottom of the ledge. The link is also configured to be one-way, to prevent the agent from trying to jump up the ledge. A cost factor of 2 has been used to make the agent prefer to walk around the ledge instead of jumping down from it. A cost factor of 1 would mean that the link is equally expensive as moving the same distance on the normal navmesh. See [NodeLink2.costFactor](https://arongranberg.com/astar/docs/nodelink2.html#costFactor) ![](https://arongranberg.com/astar/docs/images/generated/scenes/Recast3D/droplinkinspector@2x.png) See [Off-mesh links](https://arongranberg.com/astar/docs/offmeshlinks2.html) Navmesh cutting --------------- When in game mode, you can press "P" to create a dynamic obstacle in the form of a small box that falls down on the ground. It affects the navmesh using the [NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) component. Your browser does not support the video tag. Navmesh cutting is pretty fast on recast/navmesh graphs compared to recalculating tiles from scratch. But it is a bit more limited, since it can only be used to remove parts of the navmesh, not add new parts. The resulting navmesh is also not quite as good as if it had been recalculated from scratch. But for most games, navmesh cutting is great for dynamic obstacles. The navmesh cut on the box is configured as a sphere with a radius that approximates the cube. With a resolution of 6, the navmesh cut will remove a hexagonal shape from the navmesh. It could equally well have been configured using the "Box" shape, but the sphere shape is slightly simpler, and the rounded shape leads to nicer movement around the box. ![](https://arongranberg.com/astar/docs/images/generated/scenes/Recast3D/navmeshcutinspector@2x.png) See [Navmesh Cutting](https://arongranberg.com/astar/docs/navmeshcutting.html) Character animation ------------------- The character animation is handled by the [MineBotAnimation](https://arongranberg.com/astar/docs/minebotanimation.html) script. ![](https://arongranberg.com/astar/docs/images/generated/scenes/Recast3D/minebotanimation@2x.png) This script will forward the movement speed to the animator component using the following animator parameter: * **NormalizedSpeed:** Movement speed in world units, divided by [MineBotAnimation.naturalSpeed](https://arongranberg.com/astar/docs/minebotanimation.html#naturalSpeed) and the character's scale. This will be 1 when the agent is moving at the natural speed, and 0 when it is standing still. In the animator controller, the root has two states: **forward** and **idle**. These are two animation clips that are transitioned between, depending on if the **NormalizedSpeed** is high enough. The **forward** animation clip is also configured to multiply its speed by the **NormalizedSpeed** parameter, so that the animation will play faster or slower depending on how fast the agent is moving. ![](https://arongranberg.com/astar/docs/images/scenes/Recast3D/character_animation_root.png) --- # Movement scripts - A* Pathfinding Project Movement scripts ================ Brief overview of the different movement scripts in the package. There are several movement scripts included in the package. These are the scripts that actually move some object in your scene along a path, usually a character of some sort. The movement scripts' primary role is to take care of searching for paths and following them. These scripts are completely optional in this package; you can use [pathfinding without using a movement script](https://arongranberg.com/astar/docs/callingpathfinding.html) , or you can [write your own movement script](https://arongranberg.com/astar/docs/custom_movement_script.html) . However, for many games they provide a nice base to build your characters on, even if you perhaps later in development replace them with something specifically tailored for your game. There are four included movement scripts in the package: [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) , [AIPath](https://arongranberg.com/astar/docs/aipath.html) , [RichAI](https://arongranberg.com/astar/docs/richai.html) and [AILerp](https://arongranberg.com/astar/docs/ailerp.html) . The names of the scripts could, in hindsight, definitely have been chosen better, but I'm hesitant to change them at this point as a large quantity of support material and forum posts refer to these names. The primary differences between the movement scripts are: **[FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) ** * Good all-around movement script which works on grid, navmesh and recast graphs. * Follows paths smoothly and is very responsive. * Uses the Entity Component System behind the scenes. * Works well with local avoidance. * Supports movement in 3D games as well as 2D games. * Works well with off-mesh links. * Knows which node it is traversing at all times. * Not compatible with path modifiers (simplifies the path internally instead). * Stronger guarantees compared to the other movement scripts; it handles edge cases better. * High code complexity. * Cannot be used with Unity's character controller. * A standalone component which does not need a separate [Seeker](https://arongranberg.com/astar/docs/seeker.html) or [RVOController](https://arongranberg.com/astar/docs/rvocontroller.html) component attached to your agent. **[AIPath](https://arongranberg.com/astar/docs/aipath.html) ** * Good all-around movement script which works on all graph types. * Follows paths smoothly and responds to physics. * Works well with local avoidance. * Supports movement in 3D games as well as 2D games. * Can traverse off-mesh links, but cannot use special movement logic for them. * Compatible with path modifiers. * Requires the [Seeker](https://arongranberg.com/astar/docs/seeker.html) component, and optionally an [RVOController](https://arongranberg.com/astar/docs/rvocontroller.html) component for local avoidance, attached to your agent. **[AILerp](https://arongranberg.com/astar/docs/ailerp.html) ** * Uses linear interpolation to move along the path (which is why 'lerp', which stands for linear interpolation, is in the name). Does not use physics in any way. * Follows the path exactly, without any deviations whatsoever. * Due to the above points, it does not make sense to use it with local avoidance, and thus it does not support it. * By far the fastest of the movement scripts, because the movement in itself is much simpler, but keep in mind that if you need any kind of physical realism in the game, you should usually use one of the other movement scripts. * Supports movement in 3D games as well as 2D games. * Compatible with path modifiers. * Low code complexity. * Requires the [Seeker](https://arongranberg.com/astar/docs/seeker.html) component attached to your agent. **[RichAI](https://arongranberg.com/astar/docs/richai.html) ** * **Kept for compatibility only**. If you are starting a new project, the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) script is better in almost every way. * Designed specifically for navmesh/recast graphs and does not work with any other graph types. * Better than the AIPath script at following paths on navmesh-based graphs; it can handle getting pushed off its path better and usually follows the path more smoothly. * Has better support for off-mesh links compared to AIPath. * Works well with local avoidance. * Supports movement in 3D games (movement in the XZ plane), but not 2D. * Works well with off-mesh links. * Not compatible with most path modifiers (simplifies the path internally instead). * Requires the [Seeker](https://arongranberg.com/astar/docs/seeker.html) component, and optionally an [RVOController](https://arongranberg.com/astar/docs/rvocontroller.html) component for local avoidance. In short, if you are using a navmesh or grid-based graph: try the FollowerEntity component first, otherwise use either AIPath or AILerp depending on what kind of movement style your game needs. Check out the example scenes included in the package to see how the different movement scripts behave. All movement scripts included in the package implement the [Pathfinding.IAstarAI](https://arongranberg.com/astar/docs/iastarai.html) interface. So if you need something that can interact with several different movement scripts, this is a nice interface to use. For example, these are some properties which you may find useful (these properties exist on all movement scripts): destination Position in the world that this agent should move to. If no destination has been set yet, then (+infinity, +infinity, +infinity) will be returned. Note that setting this property does not immediately cause the agent to recalculate its path. So it may take some time before the agent starts to move towards this point. Most movement scripts have a **repathRate** field which indicates how often the agent looks for a new path. You can also call the [SearchPath](https://arongranberg.com/astar/docs/iastarai/searchpath.html#SearchPath) method to immediately start to search for a new path. Paths are calculated asynchronously so when an agent starts to search for path it may take a few frames (usually 1 or 2) until the result is available. During this time the [pathPending](https://arongranberg.com/astar/docs/iastarai.html#pathPending) property will return true. If you are setting a destination and then want to know when the agent has reached that destination then you could either use [reachedDestination](https://arongranberg.com/astar/docs/iastarai.html#reachedDestination) (recommended) or check both [pathPending](https://arongranberg.com/astar/docs/iastarai.html#pathPending) and [reachedEndOfPath](https://arongranberg.com/astar/docs/iastarai.html#reachedEndOfPath) . Check the documentation for the respective fields to learn about their differences. `IEnumerator Start () { ai.destination = somePoint; // Start to search for a path to the destination immediately ai.SearchPath(); // Wait until the agent has reached the destination while (!ai.reachedDestination) { yield return null; } // The agent has reached the destination now } ``IEnumerator Start () { ai.destination = somePoint; // Start to search for a path to the destination immediately // Note that the result may not become available until after a few frames // ai.pathPending will be true while the path is being calculated ai.SearchPath(); // Wait until we know for sure that the agent has calculated a path to the destination we set above while (ai.pathPending || !ai.reachedEndOfPath) { yield return null; } // The agent has reached the destination now } ` See This setting corresponds to the member [Pathfinding.IAstarAI.destination](https://arongranberg.com/astar/docs/iastarai.html#destination) reachedDestination True if the ai has reached the [destination](https://arongranberg.com/astar/docs/iastarai.html#destination) . This is a best effort calculation to see if the [destination](https://arongranberg.com/astar/docs/iastarai.html#destination) has been reached. For the AIPath/RichAI scripts, this is when the character is within [AIPath.endReachedDistance](https://arongranberg.com/astar/docs/aibase.html#endReachedDistance) world units from the [destination](https://arongranberg.com/astar/docs/iastarai.html#destination) . For the [AILerp](https://arongranberg.com/astar/docs/ailerp.html) script it is when the character is at the destination (±a very small margin). This value will be updated immediately when the [destination](https://arongranberg.com/astar/docs/iastarai.html#destination) is changed (in contrast to [reachedEndOfPath](https://arongranberg.com/astar/docs/iastarai.html#reachedEndOfPath) ), however since path requests are asynchronous it will use an approximation until it sees the real path result. What this property does is to check the distance to the end of the current path, and add to that the distance from the end of the path to the [destination](https://arongranberg.com/astar/docs/iastarai.html#destination) (i.e. is assumes it is possible to move in a straight line between the end of the current path to the destination) and then checks if that total distance is less than [AIPath.endReachedDistance](https://arongranberg.com/astar/docs/aibase.html#endReachedDistance) . This property is therefore only a best effort, but it will work well for almost all use cases. Furthermore it will not report that the destination is reached if the destination is above the head of the character or more than half the [height](https://arongranberg.com/astar/docs/iastarai.html#height) of the character below its feet (so if you have a multilevel building, it is important that you configure the [height](https://arongranberg.com/astar/docs/iastarai.html#height) of the character correctly). The cases which could be problematic are if an agent is standing next to a very thin wall and the destination suddenly changes to the other side of that thin wall. During the time that it takes for the path to be calculated the agent may see itself as alredy having reached the destination because the destination only moved a very small distance (the wall was thin), even though it may actually be quite a long way around the wall to the other side. In contrast to [reachedEndOfPath](https://arongranberg.com/astar/docs/iastarai.html#reachedEndOfPath) , this property is immediately updated when the [destination](https://arongranberg.com/astar/docs/iastarai.html#destination) is changed. `IEnumerator Start () { ai.destination = somePoint; // Start to search for a path to the destination immediately ai.SearchPath(); // Wait until the agent has reached the destination while (!ai.reachedDestination) { yield return null; } // The agent has reached the destination now } ` See [AIPath.endReachedDistance](https://arongranberg.com/astar/docs/aibase.html#endReachedDistance) [remainingDistance](https://arongranberg.com/astar/docs/iastarai.html#remainingDistance) [reachedEndOfPath](https://arongranberg.com/astar/docs/iastarai.html#reachedEndOfPath) See This setting corresponds to the member [Pathfinding.IAstarAI.reachedDestination](https://arongranberg.com/astar/docs/iastarai.html#reachedDestination) velocity Actual velocity that the agent is moving with. In world units per second. See [desiredVelocity](https://arongranberg.com/astar/docs/iastarai.html#desiredVelocity) See This setting corresponds to the member [Pathfinding.IAstarAI.velocity](https://arongranberg.com/astar/docs/iastarai.html#velocity) desiredVelocity Velocity that this agent wants to move with. Includes gravity and local avoidance if applicable. In world units per second. See [velocity](https://arongranberg.com/astar/docs/iastarai.html#velocity) Note The [Pathfinding.AILerp](https://arongranberg.com/astar/docs/ailerp.html) movement script doesn't use local avoidance or gravity so this property will always be identical to [velocity](https://arongranberg.com/astar/docs/iastarai.html#velocity) on that component. See This setting corresponds to the member [Pathfinding.IAstarAI.desiredVelocity](https://arongranberg.com/astar/docs/iastarai.html#desiredVelocity) See [IAstarAI](https://arongranberg.com/astar/docs/iastarai.html) [Migrating from Unity Navigation](https://arongranberg.com/astar/docs/migratingfromunity.html) If you want your character to follow a specific object, you can attach the [AIDestinationSetter](https://arongranberg.com/astar/docs/aidestinationsetter.html) component to your agent, and set a Transform as the target. This will, behind the scenes, set the [destination](https://arongranberg.com/astar/docs/iastarai.html#destination) property every frame to the position of your chosen target. [Writing a movement script](https://arongranberg.com/astar/docs/custom_movement_script.html) --- # Optimization - A* Pathfinding Project Optimization ============ Some tips on how to improve performance. There are various ways to increase the performance of the system. But first, **profile!** Before trying to optimize anything, use a profiler to figure out which part of the code is slowing down the game. Note that if multithreading is used, then pathfinding will only show up on a separate pathfinding thread (you can select this in the Unity profiler). * [General tips](https://arongranberg.com/astar/docs/optimization.html#opt-general) * [Optimizing game startup](https://arongranberg.com/astar/docs/optimization.html#opt-graphs) * [Optimizing Grid Graph Scanning](https://arongranberg.com/astar/docs/optimization.html#opt-gridgraph) * [Optimizing Recast Graph Scanning](https://arongranberg.com/astar/docs/optimization.html#opt-recastgraph) * [Optimizing Navmesh Graph Scanning](https://arongranberg.com/astar/docs/optimization.html#opt-navmesh) * [Optimizing Movement Scripts](https://arongranberg.com/astar/docs/optimization.html#opt-movement) * [Optimizing Pathfinding](https://arongranberg.com/astar/docs/optimization.html#opt-pathfinding) * [More Tips](https://arongranberg.com/astar/docs/optimization.html#opt-more) General tips ------------ * Make sure "Show Graphs" (bottom of the A\* inspector) is disabled when evaluating performance. For large graphs, the overhead of drawing it every frame can severely slow down the game (this only applies to the editor, not a standalone game). Optimizing game startup ----------------------- When the game starts, the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component will scan all graphs by default. This may take some time depending on your graph settings and graph sizes. If you have a purely static world, you can cache a scanned graph and just load the cache at startup. Take a look at [Saving and Loading Graphs](https://arongranberg.com/astar/docs/saveloadgraphs.html) for more info about this. Alternatively, if you want to show a progress bar while the graphs are being scanned, or just not freeze the game completely, you can scan graphs asynchronously. First, disable A\* Inspector → Settings → Scan On Awake. Then, in a custom script, you can scan graphs asynchronously like this: `IEnumerator Start () { foreach (Progress progress in [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[ScanAsync](https://arongranberg.com/astar/docs/astarpath/scanasync.html#ScanAsync) ()) { Debug.Log("Scanning... " + progress.ToString()); yield return null; } } `If caching the graph is not an option (perhaps because you have a dynamic level), you may want to tweak your graph settings to make scanning faster, or change the graph type altogether. In general, grid graphs are faster than recast graphs to scan, unless your world is very large. However, pathfinding is typically faster on recast graphs. In the following sections, some tips are included for the different graph types. See [Graph Types](https://arongranberg.com/astar/docs/graphtypes.html) for more info about the different graph types and their pros and cons. ### Optimizing Grid Graph Scanning There are several ways to reduce the time it takes for a grid graph to be scanned: * Reduce its resolution, if you can. * Disable Height Testing, if you have a completely flat world. * Disable Erosion, as it has a small performance overhead. * Disable Collision Testing, if you do not need it. ### Optimizing Recast Graph Scanning * Increase the cell size. This will reduce the resolution at which the graph voxelizes the world. * Use tiling, and use reasonably sized tiles. Values between 64 and 256 voxels are recommended. Tiles can be scanned in parallel, which can give a significant speedup on multicore computers. However, each tile has some overhead, so too small tile sizes will slow down the scan. * Rasterize colliders, instead of meshes. Colliders are typically much simpler than meshes and will therefore be faster to rasterize. In addition, this will improve graph update performance, as colliders can be queried efficiently using the physics engine, while meshes cannot. * Reduce the bounding box of the graph to only cover the part of the world that you need. ### Optimizing Navmesh Graph Scanning How long it takes to scan a navmesh graph is almost entirely dependent on the number of triangles in the input mesh. If you can reduce that, then the graph will be scanned faster. Optimizing Movement Scripts --------------------------- Movement scripts can have a pretty big impact on performance. The different included movement scripts have different performance characteristics. * [AILerp](https://arongranberg.com/astar/docs/ailerp.html) is the fastest, but the movement doesn't look very realistic, which may or may not be acceptable for your game. * [AIPath](https://arongranberg.com/astar/docs/aipath.html) is a bit slower, but it can handle local avoidance and has smoother movement (which may or may not be desirable). * [RichAI](https://arongranberg.com/astar/docs/richai.html) is the slowest, but it is more robust than AIPath when following paths, and has better support for off-mesh links. * [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) is typically somewhere between AILerp and AIPath on the performance scale. It can use multithreading to avoid blocking the main thread, but it still does a lot of work behind the scenes and is more complex than the other scripts. It is currently in beta, but I still recommend it over both AIPath and RichAI in most cases. You should also try to avoid having a CharacterController or Rigidbody component attached to your character, as they are quite slow. When none of these are attached, the AIPath and RichAI scripts will instead use a simple raycast to detect where the ground is, which is typically much faster. See [Movement scripts](https://arongranberg.com/astar/docs/movementscripts.html) for more details about the different movement scripts. Optimizing Pathfinding ---------------------- Pathfinding is often not actually a performance bottleneck. It only tends to become a bottleneck if you have a large grid graph and lots of agents. Use the profiler to see if the pathfinding threads are very busy. However, even if the throughput is not a bottleneck, improving pathfinding latency can still be a good idea. Latency is the time it takes for a single path to be calculated after a path request has been issued. If you set the destination for a lot of agents all at once, a high latency can cause some agents to lag behind the others, as they have to wait for their turn to have their path recalculated. ![](https://arongranberg.com/astar/docs/images/optimization/profiler_pathfinding_threads_latency.png) In the above picture, you can see that the pathfinding threads become very busy recalculating paths for 210 agents, as they all received a new destination at the same time. However, the latency is still quite low, as all paths are calculated before the next frame even starts. So performance is fine in this case. If you need to improve the pathfinding performance, here are some tips: * By far the easiest way is to enable multithreading (A\* Inspector → Settings). This will make the pathfinding run on separate threads instead of on the Unity thread, which will likely improve performance quite a bit since almost all computers and even phones have many cores these days. * Logging path results has a pretty large performance impact. Often as much as reducing the pathfinding throughput by 50%. You should disable path logging if you do not need it. Set A\* Inspector → Settings → Path Log Mode to None. * Reduce the frequency at which new paths are calculated. * Set the Recalculate Paths Automatically field on your movement script to [Dynamic](https://arongranberg.com/astar/docs/autorepathpolicy.html#Mode) to make the agent recalculate its path less often when it is far from its target, and more often if it is closer, or if the target changed position a lot. * If you use the [EveryNSeconds](https://arongranberg.com/astar/docs/autorepathpolicy.html#Mode) mode, try to increase the [period](https://arongranberg.com/astar/docs/autorepathpolicy.html#period) field. * Perhaps you can even disable automatic path recalculation and use your own game-specific logic to recalculate the path only when necessary. * Use lower quality settings on modifiers. In particular, you might be able to reduce the number of segments that the [SimpleSmoothModifier](https://arongranberg.com/astar/docs/simplesmoothmodifier.html) divides the path into if you are using it. The AIPath movement script already does a pretty good job at following the path smoothly, even if the path itself is not particularly smooth. * Using a recast graph instead of a grid graph will generally improve pathfinding performance, as recast graphs typically need much fewer nodes to cover the same area. * On a static map, heuristic optimization can be an option. See [Heuristic Optimization](https://arongranberg.com/astar/docs/heuristicopt.html) . More Tips --------- Take a look at the child pages for more ways to increase the performance. * [Heuristic Optimization](https://arongranberg.com/astar/docs/heuristicopt.html) * [Pooling](https://arongranberg.com/astar/docs/pooling.html) * [Compiler Directives](https://arongranberg.com/astar/docs/compilerdirectives.html) --- # Graph Updates during Runtime - A* Pathfinding Project Graph Updates during Runtime ============================ Contents -------- * [Overview](https://arongranberg.com/astar/docs/graphupdates.html#graph-updates-overview) * [What to update](https://arongranberg.com/astar/docs/graphupdates.html#what) * [Using Scripting](https://arongranberg.com/astar/docs/graphupdates.html#scripting) * [Using direct access to graph data](https://arongranberg.com/astar/docs/graphupdates.html#direct) * [Viewing the results of updates](https://arongranberg.com/astar/docs/graphupdates.html#debug) * [Technical Details](https://arongranberg.com/astar/docs/graphupdates.html#technical) * [GridGraph specific details](https://arongranberg.com/astar/docs/graphupdates.html#gridgraphs) * [Navmesh based graphs](https://arongranberg.com/astar/docs/graphupdates.html#navmeshes) * [PointGraphs](https://arongranberg.com/astar/docs/graphupdates.html#pointgraphs) * [The Graph Update Object](https://arongranberg.com/astar/docs/graphupdates.html#graphupdateobject) * [Check for blocking placements](https://arongranberg.com/astar/docs/graphupdates.html#blocking) Overview -------- Sometimes it can be necessary to update a graph during runtime. Maybe a player has constructed a new building or maybe a door has been opened. Graphs can either be completely recalculated or partially updated. A complete recalculation is good if you have changed your whole map, but smaller updates can be done much faster if you only need to change a small part of the graph. There are many ways to update a graph and many different scenarios in which you might want to do it. So here is a table summarizing the most common cases. Keep in mind that games are very different, so a solution might work for your game that isn't in this list. | You want | How to do it | | --- | --- | | to recalculate the whole graph | See [Recalculating the whole graph](https://arongranberg.com/astar/docs/graphupdates.html#recalculate-whole-graph) | | to set exactly which nodes are walkable and which are not (e.g., based on a tilemap) | See [Writing Custom Grid Graph Rules](https://arongranberg.com/astar/docs/gridruleswrite.html)
, [Using direct access to graph data](https://arongranberg.com/astar/docs/graphupdates.html#direct)
, [Agent-Specific Pathfinding](https://arongranberg.com/astar/docs/traversal_provider.html)
and [Grid Graph Rules](https://arongranberg.com/astar/docs/gridrules.html) | | to update the graph as some objects move around or are created/destroyed | See [Recalculating parts of graphs](https://arongranberg.com/astar/docs/graphupdates.html#smaller-updates)
, in particular [DynamicObstacle](https://arongranberg.com/astar/docs/dynamicobstacle.html)
and [Navmesh Cutting](https://arongranberg.com/astar/docs/navmeshcutting.html) | | to update the properties of a single node | See [Using direct access to graph data](https://arongranberg.com/astar/docs/graphupdates.html#direct)
, [GraphUpdateScene](https://arongranberg.com/astar/docs/graphupdatescene.html)
and [Grid Graph Rules](https://arongranberg.com/astar/docs/gridrules.html) | | to dynamically load and unload graphs (e.g., to a file) | See [Saving and Loading Graphs](https://arongranberg.com/astar/docs/saveloadgraphs.html) | | a smaller grid graph to follow the player around (e.g., for a procedural world) | See [ProceduralGraphMover](https://arongranberg.com/astar/docs/proceduralgraphmover.html) | | to create new nodes and connect them using code | See [PointGraph.AddNode](https://arongranberg.com/astar/docs/pointgraph/addnode.html)
and [Writing Graph Generators](https://arongranberg.com/astar/docs/writinggraphgenerators.html) | | to make a part of the graph more costly to traverse | See [Writing Custom Grid Graph Rules](https://arongranberg.com/astar/docs/gridruleswrite.html)
, [Recalculating parts of graphs](https://arongranberg.com/astar/docs/graphupdates.html#smaller-updates)
, [Using direct access to graph data](https://arongranberg.com/astar/docs/graphupdates.html#direct)
, [GraphUpdateScene](https://arongranberg.com/astar/docs/graphupdatescene.html)
and [Grid Graph Rules](https://arongranberg.com/astar/docs/gridrules.html) | | to prevent some units from traversing some nodes but allow other units | See [Agent-Specific Pathfinding](https://arongranberg.com/astar/docs/traversal_provider.html)
, [Recalculating parts of graphs](https://arongranberg.com/astar/docs/graphupdates.html#smaller-updates)
, [GraphUpdateScene](https://arongranberg.com/astar/docs/graphupdatescene.html)
, [Using direct access to graph data](https://arongranberg.com/astar/docs/graphupdates.html#direct)
and [Grid Graph Rules](https://arongranberg.com/astar/docs/gridrules.html) | | pathfinding on a moving object (e.g., a ship) | See the example scene called 'Moving' (pro version only). This is not that well documented at the moment. | | to add an obstacle, but first make sure that it doesn't block any units (useful in TD games) | See [Check for blocking placements](https://arongranberg.com/astar/docs/graphupdates.html#blocking) | What to update -------------- When updating graphs, one usually wants to accomplish one of two things. You might want to recalculate the graph with the same settings as it was calculated with when it was initially generated, but if you have only updated the graph in a small region, it seems wasteful to recalculate the whole graph (using [AstarPath.Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) ). For example, the player might just have placed a new tower in a tower defense game. Or you might want to change some settings on the existing graph. For example, you might want to change the tag or penalty on some nodes. To just recalculate a small part of the graph in the same way as it was calculated at the start can be done for all graphs except the NavMeshGraph since it usually only makes sense to completely recalculate it. The way you do this using both scripting and the GraphUpdateScene component is that you set the field called "updatePhysics" to true. It might not be the most descriptive name, sorry about that. Grid graphs will work as you expect; you can just specify the bounds and it will do everything for you. It may, however, recalculate a region which is slightly larger than the one you specified in order to make sure things like erosion are correctly taken into account. Recast graphs can only be recalculated a whole tile at a time. So when a request is made to update it, all tiles which the bounds touch will be completely recalculated. Therefore, it can be good to use a smaller tile size to avoid very large recalculation times. However, not too small since then it essentially degenerates into a grid graph. If you use multithreading, a large part of the tile recalculation will be offloaded to a separate thread to avoid impacting the FPS too much. Point graphs will recalculate all connections that pass through the bounds. It will, however, not look for new nodes that are added as GameObjects. For that you need to use [AstarPath.Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) . If you want to change properties on the existing graph, there are a bunch of things you can change. You can change the tags on the nodes. This can be used to enable some units to traverse a region while preventing other units from doing that. You can read more about tagging here: [Working with tags](https://arongranberg.com/astar/docs/tags.html) . You can change the penalty on the nodes. This is used to make some nodes harder/slower to traverse compared to other nodes so that an agent will prefer some paths before others. There are some limitations though. You cannot specify negative penalties since the algorithms used cannot handle that (and if they could, the system would be a lot slower). However, a common trick is to set a very large initial penalty (which can be done in the graph settings) and then decrease the penalty from that high value. Note, however, that this will make pathfinding slower overall since it has to search more nodes. The penalty values that are required are quite high. There is no real "penalty unit"; however, a penalty of 1000 corresponds roughly to one world unit of travel. Walkability of the nodes can also be modified directly. So you can make all nodes within some bounds be all walkable or all unwalkable. For information about how to use the [GraphUpdateScene component](https://arongranberg.com/astar/docs/graphupdatescene.html) , see the docs for that class. The GraphUpdateScene component settings map almost 1 to 1 to the GraphUpdateObject which is used when updating graphs using scripting. So I recommend that you read that page even though you are only going to use scripting. Recalculating the whole graph ----------------------------- A complete recalculation of all graphs or just a few can be done using `// Recalculate all graphs [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) (); // Recalculate only the first grid graph var graphToScan = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .gridGraph; [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) (graphToScan); // Recalculate only the first and third graphs var graphsToScan = new [] { [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .graphs[0], [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .graphs[2] }; [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) (graphsToScan); `You can also recalculate graphs asynchronously (only available in the pro version). This does not guarantee a good frame rate, but you can at least show a loading screen. `IEnumerator Start () { foreach (Progress progress in [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[ScanAsync](https://arongranberg.com/astar/docs/astarpath/scanasync.html#ScanAsync) ()) { Debug.Log("Scanning... " + progress.ToString()); yield return null; } } ` See [AstarPath.Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) [AstarPath.ScanAsync](https://arongranberg.com/astar/docs/astarpath/scanasync.html#ScanAsync) Recalculating parts of graphs ----------------------------- Smaller graph updates can either be done using the [GraphUpdateScene](https://arongranberg.com/astar/docs/graphupdatescene.html) component which can be edited in the Unity inspector or using scripting which is done by calling a method in the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) class with either a Bounds object or a [Pathfinding.GraphUpdateObject](https://arongranberg.com/astar/docs/graphupdateobject.html) (which is what the GraphUpdateScene component actually does in the background). `// As an example, use the bounding box from the attached collider Bounds bounds = GetComponent().bounds; [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[UpdateGraphs](https://arongranberg.com/astar/docs/astarpath/updategraphs.html#UpdateGraphs3) (bounds); ``// using Pathfinding; //At top of script // As an example, use the bounding box from the attached collider Bounds bounds = GetComponent().bounds; var guo = new GraphUpdateObject(bounds); // Set some settings guo.updatePhysics = true; [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[UpdateGraphs](https://arongranberg.com/astar/docs/astarpath/updategraphs.html#UpdateGraphs3) (guo); `The method will then put the task in a queue to be carried out before the next path calculation. It has to be put in a queue because if it were carried out directly, it might interfere with pathfinding, especially if multithreading is on, and cause all kinds of errors. This means that you might not see an update of the graph directly, but it will always be updated before the next pathfinding calculation starts (almost always, see AstarPath.limitGraphUpdates). Recast graphs can also be pseudo-updated using [navmesh cutting](https://arongranberg.com/astar/docs/navmeshcutting.html) . Navmesh cutting can cut out holes for obstacles in the navmesh, but cannot add more navmesh surface. See [Pathfinding.NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) . This is much faster, but more limited than recalculating a whole recast tile. Using the GraphUpdateScene component is usually easiest if you are working in the Unity Editor on a known graph. For example, you can easily change the tag of a specific region without any code. However, updating the graph using code is usually easier if you are doing it dynamically during runtime. For example, if you are updating the graph to account for a newly placed building in a tower defense game. Using Scripting --------------- To update a graph you create a GraphUpdateObject and set the parameters you want, then you call the [AstarPath.UpdateGraphs](https://arongranberg.com/astar/docs/astarpath/updategraphs.html#UpdateGraphs3) method to queue the update. `// using Pathfinding; //At top of script // As an example, use the bounding box from the attached collider Bounds bounds = GetComponent().bounds; var guo = new GraphUpdateObject(bounds); // Set some settings guo.updatePhysics = true; [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[UpdateGraphs](https://arongranberg.com/astar/docs/astarpath/updategraphs.html#UpdateGraphs3) (guo); `The bounds variable referred to is a UnityEngine.Bounds object. It defines an axis-aligned box in which to update the graphs. Often you want to update the graph around some newly created object. In the example, the bounding box is taken from the attached collider. However, make sure that this object will be recognized by the graph. For grid graphs, you should make sure that the object's layer is included in either the collision testing mask or the height testing mask. If you don't need to recalculate all parameters on the nodes when using a grid graph or connections when using a point graph, you can set updatePhysics (see [GridGraph specific details](https://arongranberg.com/astar/docs/graphupdates.html#gridgraphs) ) to false to avoid unnecessary calculations `guo.updatePhysics = false; ` For details about exactly what fields to set, take a look at the class documentation for the [GraphUpdateObject](https://arongranberg.com/astar/docs/graphupdateobject.html) . ### Using direct access to graph data In some cases, it might be inconvenient to use a GraphUpdateObject to update the graph. In those cases, you can update the graph data directly. However, care needs to be taken. When using the GraphUpdateObject, the system takes care of a lot of things for you. See [Accessing graph data](https://arongranberg.com/astar/docs/accessingdata.html) for information about how to access graph data. [Node properties](https://arongranberg.com/astar/docs/usingnodes.html#node-properties) and [Pathfinding.GraphNode](https://arongranberg.com/astar/docs/graphnode.html) for information about what properties a node has. [Grid Graph Rules](https://arongranberg.com/astar/docs/gridrules.html) for how to create custom GridGraph rules. If you are using a grid graph, it is often more robust to write a custom grid graph rule. Here is an example of changing all nodes in a grid graph and using [perlin noise](https://en.wikipedia.org/wiki/Perlin_noise) to determine if nodes should be walkable: `[AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) (new AstarWorkItem(ctx => { var gg = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .gridGraph; for (int z = 0; z < gg.depth; z++) { for (int x = 0; x < gg.width; x++) { var node = gg.GetNode(x, z); // This example uses perlin noise to generate the map node.Walkable = Mathf.PerlinNoise(x * 0.087f, z * 0.087f) > 0.4f; } } // Recalculate all grid connections // This is required because we have updated the walkability of some nodes gg.RecalculateAllConnections(); // If you are only updating one or a few nodes you may want to use // gg.CalculateConnectionsForCellAndNeighbours only on those nodes instead for performance. })); `The above code will generate this graph: ![](https://arongranberg.com/astar/docs/images/grid_perlin.png) Graph data must only be modified when it is safe to do so. Pathfinding might be running at any time so it is necessary to first pause the pathfinding threads and then update the data. The easiest way to do this is to use [AstarPath.AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) : `[AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) (new AstarWorkItem(() => { // Safe to update graphs here var node = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (transform.position).node; node.Walkable = false; })); ``[AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) (() => { // Safe to update graphs here var node = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (transform.position).node; node.position = (Int3)transform.position; }); `When the connectivity of the nodes is changed, the system automatically recalculates the connected components of the graph. You can read more about this in the documentation for this class: [Pathfinding.HierarchicalGraph](https://arongranberg.com/astar/docs/hierarchicalgraph.html) . However, in the middle of a sequence of work items, it may not be up to date. If you are using methods such as [Pathfinding.PathUtilities.IsPathPossible](https://arongranberg.com/astar/docs/pathutilities/ispathpossible.html#IsPathPossible3) or the [Pathfinding.GraphNode.Area](https://arongranberg.com/astar/docs/graphnode.html#Area) property you should call the [ctx.EnsureValidFloodFill](https://arongranberg.com/astar/docs/iworkitemcontext/ensurevalidfloodfill.html#EnsureValidFloodFill) method first. Usually, this is not something that work items require, however. Version Prior to 4.2 you had to manually call methods like QueueFloodFill to keep this data up to date. However, in 4.2 and above there is no need for that. The system will handle it automatically behind the scenes in a more performant way. `[AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) (new AstarWorkItem((IWorkItemContext ctx) => { // Update the graph in some way // ... // Ensure that connectivity information is up to date. // This will also automatically run after all work items have been executed. ctx.EnsureValidFloodFill(); // Use connectivity information if (PathUtilities.IsPathPossible(someNode, someOtherNode)) { // Do something } })); `If you are modifying walkability you also need to make sure that connections are recalculated properly. This is important mostly for the grid graph. You can use the [GridGraph.RecalculateConnectionsInRegion](https://arongranberg.com/astar/docs/gridgraph/recalculateconnectionsinregion.html#RecalculateConnectionsInRegion) or [GridGraph.RecalculateAllConnections](https://arongranberg.com/astar/docs/gridgraph/recalculateallconnections.html#RecalculateAllConnections) methods. Note that this needs to be called both on the nodes you changed walkability on and also on any adjacent nodes to them, since they might have to change their connections to the affected nodes. If you are only updating a single node you could use the [GridGraph.CalculateConnectionsForCellAndNeighbours](https://arongranberg.com/astar/docs/gridgraph/calculateconnectionsforcellandn.html#CalculateConnectionsForCellAndNeighbours) method for simplicity. The AddWorkItem method can also be used in more advanced ways. For example, it allows you to spread the calculation over multiple frames if necessary: `[AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) (new AstarWorkItem(() => { // Called once, right before the // first call to the method below }, force => { // Called every frame until complete. // Signal that the work item is // complete by returning true. // The "force" parameter will // be true if the work item is // required to complete immediately. // In that case this method should // block and return true when done. return true; })); `For a list of all different ways of creating a work item, take a look at the constructors for [Pathfinding.AstarWorkItem](https://arongranberg.com/astar/docs/astarworkitem.html) . Viewing the results of updates ------------------------------ While some things like walkability and position are immediately visible changes, tags and penalties are not directly visible on the graph. However, there are other viewing modes that can be enabled to visualize both tags and penalties. The viewing mode can be edited at A\* Inspector → Settings → Debug → Graph Coloring. If you set it to "Tags" all tags will be visible as different colors on the graph. ![](https://arongranberg.com/astar/docs/images/debug_inspector_tags.png) ![](https://arongranberg.com/astar/docs/images/debug_tags.png) You can also set it to show penalties. By default, it will automatically adjust itself so that the node(s) with the highest penalty will show up as pure red and the node(s) with the lowest penalty will show up as green. ![](https://arongranberg.com/astar/docs/images/debug_inspector_penalties.png) Technical Details ----------------- When a GraphUpdateObject is used to update graphs, all graphs will be iterated over and those which can be updated (all built-in ones) will have their ScheduleGraphUpdates function called. Each node is updated by the graphs calling [GraphUpdateObject.Apply](https://arongranberg.com/astar/docs/graphupdateobject/apply.html#Apply) . The Apply function will then change penalty, walkability or other parameters specified. Graphs typically also have custom logic for updating the graph, such as the GridGraph (see [GridGraph specific details](https://arongranberg.com/astar/docs/graphupdates.html#gridgraphs) ). You do not have to understand all different function calls to be able to use it; those are mostly for people who want to mess around with the source code. ### GridGraph specific details The [updatePhysics](https://arongranberg.com/astar/docs/graphupdateobject.html#updatePhysics) variable matters a lot when updating grid graphs. If it is set to true, all affected nodes will have their height recalculated and then checked if they are still walkable. You usually want to leave this as true when updating a grid graph. When updating a GridGraph, the GraphUpdateObject's Apply function (which changed walkability, tags and penalties) will be called for each node inside the bounds. It will check the [updatePhysics](https://arongranberg.com/astar/docs/graphupdateobject.html#updatePhysics) variable. If it is true (which is the default value), the area will be expanded by the diameter specified in the Collision Testing settings and every node inside the area will be checked for collisions. If it is false, however, only the Apply function will be called for the nodes inside the area (not expanded) and nothing else will be done. ### Navmesh based graphs Navmesh based graphs (NavMeshGraph and RecastGraph) only have support for updating the penalty, walkability and similar on already existing nodes or, for recast graphs, to completely recalculate whole tiles. New nodes cannot be created using GraphUpdateObjects (unless recalculating whole tiles). The GraphUpdateObject will affect all nodes/triangles which intersect or are contained by the GUO's bounds. For recast graphs you can also use [navmesh cutting](https://arongranberg.com/astar/docs/navmeshcut.html) to update the graph in a fast way. ### PointGraphs Point graphs will call Apply on every node inside the bounds. If GraphUpdateObject.updatePhysics is set to true (default true) it will also recalculate all connections which pass through the bounds object. Note Updating Point graphs is only available in the pro version of the A\* [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) Project. A\* Pro Feature This is an A\* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A\* Pathfinding Project or the functionality might be limited. The Pro version can be bought [here](http://www.arongranberg.com/astar/buy) The Graph Update Object ----------------------- The GraphUpdateObject contains some basic variables on how to update each node. See documentation for the [Pathfinding.GraphUpdateObject](https://arongranberg.com/astar/docs/graphupdateobject.html) for more info. ### Inheriting from the GraphUpdateObject Classes can inherit from the GraphUpdateObject to override some functionality. Here's an example of a GraphUpdateObject which moves nodes by some offset while still keeping the base functionality. `using UnityEngine; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) ; public class MyGUO : GraphUpdateObject { public Vector3 offset = Vector3.up; public override void Apply (GraphNode node) { // Keep the base functionality base.Apply(node); // The position of a node is an Int3, so we need to cast the offset node.position += (Int3)offset; } } `You could then use that GUO like this: `public void Start () { MyGUO guo = new MyGUO(); guo.offset = Vector3.up*2; guo.bounds = new Bounds(Vector3.zero, Vector3.one*10); [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[UpdateGraphs](https://arongranberg.com/astar/docs/astarpath/updategraphs.html#UpdateGraphs3) (guo); } ` Check for blocking placements ----------------------------- A common thing in tower defense games is to make sure that the towers the player places do not block the path between the spawn points and the goal. This might seem hard to do, but luckily there is an API for that. The [Pathfinding.GraphUpdateUtilities.UpdateGraphsNoBlock](https://arongranberg.com/astar/docs/graphupdateutilities/updategraphsnoblock.html#UpdateGraphsNoBlock2) method can be used to first check if a given graph update object will cause the path between two or more points to become blocked. This is, however, slower than a normal graph update so you probably don't want to use it too often. For example, when a player in a tower defense game places a tower, you could instantiate it, then call the UpdateGraphsNoBlock method to check if the newly placed tower will block the path. If it did, then remove the tower immediately and notify the player that the chosen position was not valid. You can pass a list of nodes to the UpdateGraphsNoBlock method so you could, for example, make sure that not only is the path from the start to the goal not blocked, but also that all units can still reach the goal (if it is possible to place towers when enemies are walking around). `var graphUpdate = new GraphUpdateObject(tower.GetComponent().bounds); var spawnPointNode = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (spawnPoint.position).node; var goalNode = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (goalPoint.position).node; if (GraphUpdateUtilities.UpdateGraphsNoBlock(graphUpdate, spawnPointNode, goalNode, false)) { // Valid tower position // Since the last parameter (which is called "alwaysRevert") in the method call was false // The graph is now updated and the game can just continue } else { // Invalid tower position. It blocks the path between the spawn point and the goal // The effect on the graph has been reverted Destroy(tower); } ` --- # Bitmask Tutorial - A* Pathfinding Project Bitmask Tutorial ================ A short tutorial on bitmasks. There are several bitmasks used in various places in the package. These may not be familiar to all users, so in this tutorial I will briefly explain how they are used. What is a bitmask? ------------------ A bitmask is a very efficient way to represent a set of options that can be enabled or disabled. A common example that is used both in Unity and in this package is layer masks. Layer masks represent a set of layers. For example, if you have a light, you could set a layer mask to determine which layers it should cast light on. In this package, layer masks are used for: selecting sets of layers to use, sets of graphs, sets of tags and sets of RVO layers. A bitmask is represented in a single number, usually a 32-bit integer. Since we have 32 bits in that number, this means that we have 32 options that we can turn on and off. For simplicity, let's say we have a 3-bit number and 3 options: "A", "B" and "C". In this 3-bit number, we can use the first bit to determine if option "A" is enabled, the second bit to determine if "B" is enabled, and the last bit for "C". For example, the number 6, which is 110 in binary, means that "B" and "C" are enabled, but "A" is disabled. 2 or 010 in binary would mean that only option "B" is enabled. In the same way, we can use this for 32-bit numbers. Creating bitmasks ----------------- In code, you can easily create bitmasks using bitshifts and bitwise-or. A bitshift essentially just moves some bits in a direction. `1 = 1 (in binary) 1 << 0 = 1 (in binary) 1 << 1 = 10 (in binary) 1 << 2 = 100 (in binary) // etc. 57 = 111001 (in binary) 57 << 2 = 11100100 (in binary) ` A [bitwise-or](https://en.wikipedia.org/wiki/Bitwise_operation#OR) will set a bit to 1 if the bit was 1 in either of the two numbers. If we want to enable options 0, 3 and 4, we can construct individual bitmasks for enabling the options separately and then OR the bitmasks together. `var mask0 = 1 << 0; // in binary: 00001 var mask3 = 1 << 3; // in binary: 01000 var mask4 = 1 << 4; // in binary: 10000 // Use a bitwise-or to create the mask var fullMask = mask0 | mask3 | mask4; // in binary: 11001 // Or combined var fullMask = (1 << 4) | (1 << 3) | (1 << 0); // in binary: 11001 `The value -1 is represented in binary as all 1s. So -1 means that all options are enabled. Similarly, the value 0 means no options are enabled. For more information, check out the [Wikipedia article](https://en.wikipedia.org/wiki/Mask_(computing)) on the subject. Uses in the package ------------------- The most common use of bitmasks in the package is for selecting which tags are traversable. The [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint.html) struct has a field called [TraversalConstraint.tags](https://arongranberg.com/astar/docs/traversalconstraint.html#tags) which determines which tags are traversable. `var traversalConstraint = TraversalConstraint.None; // Allows the first and third tags to be searched, but not the rest traversalConstraint.tags = (1 << 0) | (1 << 2); // Allows the two named tags to be searched, but not the rest traversalConstraint.tags = PathfindingTag.FromName("Grass").ToMask() | PathfindingTag.FromName("Lava").ToMask(); `There's also a built-in struct called [GraphMask](https://arongranberg.com/astar/docs/graphmask.html) to help you build masks that represent different graphs: `GraphMask mask1 = GraphMask.FromGraphName("My Grid Graph"); GraphMask mask2 = GraphMask.FromGraphName("My Other Grid Graph"); NearestNodeConstraint nn = NearestNodeConstraint.Walkable; nn.graphMask = mask1 | mask2; // Find the node closest to somePoint which is either in 'My Grid Graph' OR in 'My Other Grid Graph' var info = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (somePoint, nn); `It is not quite a normal bitmask under the hood, but it behaves like one. The [Seeker.StartPath](https://arongranberg.com/astar/docs/seeker/startpath.html) method also takes a parameter called 'graphMask' which is just forwarded to [Path.traversalConstraint.graphMask](https://arongranberg.com/astar/docs/traversalconstraint.html#graphMask) . It can be used in the same way. `// Schedule a path search that will only start searching the graphs with index 0 and 3 seeker.StartPath(startPoint, endPoint, null, GraphMask.FromGraphIndex(0) | GraphMask.FromGraphIndex(3)); ` See [GraphMask](https://arongranberg.com/astar/docs/graphmask.html) --- # Useful Classes - A* Pathfinding Project Group Useful Classes ==================== These are the classes you will use most. [AstarData](https://arongranberg.com/astar/docs/astardata.html) Stores the navigation graphs for the A\* [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) System. [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) Core component for the A\* Pathfinding System. [Seeker](https://arongranberg.com/astar/docs/seeker.html) Handles path calls for a single unit. [Path Types](https://arongranberg.com/astar/docs/paths.html) Collection of the most used path types. [Utilities](https://arongranberg.com/astar/docs/utils.html) Collection of utility classes which might be useful. [Modifiers](https://arongranberg.com/astar/docs/modifiers.html) Collection of the most used modifiers. [Graph Types](https://arongranberg.com/astar/docs/graphs.html) Collection of the most used graph types. --- # Recast graph with doors - A* Pathfinding Project Recast graph with doors ======================= Example scene which demonstrates doors and moving bridges in a 3D level. ![](https://arongranberg.com/astar/docs/images/generated/scenes/RecastDoors/overview.png) This example shows how to use the [NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) component to make doors that can be opened and closed. It also shows how to make a moving bridge that updates the navmesh using the [DynamicObstacle](https://arongranberg.com/astar/docs/dynamicobstacle.html) component. Contents -------- * [Graph setup](https://arongranberg.com/astar/docs/example_recast_doors.html#example_recast_doors_graph) * [Doors](https://arongranberg.com/astar/docs/example_recast_doors.html#example_recast_doors_doors) * [Bridge](https://arongranberg.com/astar/docs/example_recast_doors.html#example_recast_doors_bridge) * [Chest](https://arongranberg.com/astar/docs/example_recast_doors.html#example_recast_doors_chest) Graph setup ----------- ![](https://arongranberg.com/astar/docs/images/generated/scenes/RecastDoors/graphsettings@2x.png) This example uses a recast graph because it supports the navmesh cuts that are used for the doors. A grid graph could also have been used, but then the doors would have to be implemented using [DynamicObstacle](https://arongranberg.com/astar/docs/dynamicobstacle.html) components instead, or using some other method. The ground is pretty much flat, so the recast graph does not require many tweaks from the default settings. The most notable changes are: * The cell size of the graph has been reduced a bit to make it represent the world more accurately. * The character radius has also been changed to reflect the size of the agents that will be used in the scene. * The bounding box of the graph has been changed to fit the world. * The layer mask has been changed to only include the Default layer. This is because all obstacles in this scene are on the Default layer. * The graph has been changed to rasterize colliders, instead of meshes, which is the default. This is primarily because the bridge is always visible, but the animation on it enables and disables a collider to toggle its traversability. Doors ----- There are two doors in the scene with identical configuration. If you click on the red dot in the scene, the agent will move there and the door will open. Your browser does not support the video tag. The interaction is done via the [Interactable](https://arongranberg.com/astar/docs/interactable.html) component. Note The [Interactable](https://arongranberg.com/astar/docs/interactable.html) component is a very simple state machine implementation which is intended for the example scenes. In a real game, you would probably want to use a more advanced state machine implementation, but this script can serve as a good example if you want to write your own state machine code for your game. It is configured to do the following when clicked on: 1. Spawn the same "move here" particle effect as when the player normally clicks somewhere on the ground. 2. Make the agent move to the red dot, and rotate to face the console. 3. Spawn a bunch of particle effects. 4. Set the parameter "open" on the door's animator component to true. This will cause the door opening animation to play. ![](https://arongranberg.com/astar/docs/images/generated/scenes/RecastDoors/doorinteractable@2x.png) The door's animator can be in either the open state or the closed state. If the animator detects a change in the "open" parameter, it will play the appropriate transition animation and move to the other state. There is also a [NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) covering the opening. When the opening animation starts, this navmesh cut will be disabled, which allows the agent to move through the door. Note You could alternatively use a collider together with a [DynamicObstacle](https://arongranberg.com/astar/docs/dynamicobstacle.html) component, to trigger a recalculation of the graph around the door. This approach is used in the [Bridge](https://arongranberg.com/astar/docs/example_recast_doors.html#example_recast_doors_bridge) section. ![](https://arongranberg.com/astar/docs/images/scenes/RecastDoors/door_animator.png) Bridge ------ Your browser does not support the video tag. The movable bridge is initially not traversable, but it can be moved into position by moving the agent to the console with the red dot next to it. It is configured in a very similar way to the doors. The primary difference lies in the animation. The bridge animation will enable or disable a collider object when the animation finishes, and this collider object also has a [DynamicObstacle](https://arongranberg.com/astar/docs/dynamicobstacle.html) component attached to it. Enabling or disabling the collider will make the [DynamicObstacle](https://arongranberg.com/astar/docs/dynamicobstacle.html) component recalculate the graph around the bridge from scratch. This is a much more powerful operation than navmesh cutting, as this can change any aspect of the graph, not just remove parts of it. However, it may be slower, depending on your graph complexity. Chest ----- Your browser does not support the video tag. There's a chest in the scene which can be opened by clicking on it. Chests are described in more detail in [Chests](https://arongranberg.com/astar/docs/example_recast3d.html#example_recast3d_chests) . --- # Searching for paths - A* Pathfinding Project Searching for paths =================== Tutorial on how to calculate paths. * [Introduction](https://arongranberg.com/astar/docs/callingpathfinding.html#calling-intro) * [Using a built-in movement script](https://arongranberg.com/astar/docs/callingpathfinding.html#calling-movement-script) * [Using the Seeker component](https://arongranberg.com/astar/docs/callingpathfinding.html#calling-custom-movement-script) * [Other types of paths](https://arongranberg.com/astar/docs/callingpathfinding.html#other-paths) * [Using the AstarPath class directly](https://arongranberg.com/astar/docs/callingpathfinding.html#calling-directly) * [Path pooling](https://arongranberg.com/astar/docs/callingpathfinding.html#calling-path-pooling) Introduction ------------ Pathfinding is all about calculating paths. But there are many variations on this. The most basic path goes from a point A to another point B, but there are other path types that, for example, calculate paths to the closest point of a list of candidate points, and path types that calculate a path in a random direction. Furthermore, you may be using a built-in movement script, in which case it will handle pathfinding requests, or you may want to write a custom movement script, in which case you will have to handle pathfinding requests yourself. You may even want to calculate a path without a movement script at all, for example to show a preview path to the player, before any movement takes place. This page will cover how to calculate paths in a number of different ways. Using a built-in movement script -------------------------------- If you are using one of the [built-in movement scripts](https://arongranberg.com/astar/docs/movementscripts.html) , the agent periodically recalculates its path completely automatically. The only thing you need to do is to set the [ai.destination](https://arongranberg.com/astar/docs/iastarai.html#destination) property to the target point, or use the [AIDestinationSetter](https://arongranberg.com/astar/docs/aidestinationsetter.html) to make it move towards an existing GameObject. You can control how often the agent recalculates its path using the properties on the [AutoRepathPolicy](https://arongranberg.com/astar/docs/autorepathpolicy.html) , which is part of the movement script. `void PointAndClick (IAstarAI ai) { // Check if the mouse button is pressed if (Input.GetMouseButton(0)) { var cam = Camera.main; // Make the raycast hit all colliders LayerMask mask = -1; // Shoot a ray from the cursor, to see where in the world it hits if (Physics.Raycast(cam.ScreenPointToRay(Input.mousePosition), out var hit, Mathf.Infinity, mask)) { // Set the destination of the AI to the point where the ray hit ai.destination = hit.point; } } } `If you need to, you can force the agent to recalculate its path immediately using [ai.SearchPath](https://arongranberg.com/astar/docs/iastarai/searchpath.html#SearchPath) . In some cases you may want to take more direct control over the pathfinding requests. In that case you can use the [ai.SetPath](https://arongranberg.com/astar/docs/iastarai/setpath.html#SetPath) method to assign a pathfinding request, or an already calculated path, to the agent. However, you should take care to disable the agent's automatic path recalculations if you do this, otherwise the agent will overwrite your path with its own path shortly after you set it. `// Disable the automatic path recalculation ai.canSearch = false; var pointToAvoid = enemy.position; // Make the AI flee from the enemy. // The path will be about 20 world units long (the default cost of moving 1 world unit is 1000). var path = FleePath.Construct(ai.position, pointToAvoid, 1000 * 20); ai.SetPath(path); ` See [IAstarAI.SetPath](https://arongranberg.com/astar/docs/iastarai/setpath.html#SetPath) [IAstarAI.SearchPath](https://arongranberg.com/astar/docs/iastarai/searchpath.html#SearchPath) [Path Types](https://arongranberg.com/astar/docs/example_path_types.html) for a demonstration of all path types. Using the Seeker component -------------------------- If you are writing your own movement script, or you have some other reason to calculate paths yourself, you can use the [Seeker](https://arongranberg.com/astar/docs/seeker.html) component to calculate paths. The Seeker component can be attached to any GameObject and it will handle pathfinding requests for that GameObject. It has a convenient collection of methods that make it easy to request paths, it also contains various pathfinding settings, and it can handle [path modifiers](https://arongranberg.com/astar/docs/modifiers2.html) . See [Writing a movement script](https://arongranberg.com/astar/docs/custom_movement_script.html) Most [built-in movement scripts](https://arongranberg.com/astar/docs/movementscripts.html) use the Seeker component internally to calculate paths. The exception is the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component, since it uses Unity's Entity Component System behind the scenes, and that doesn't play well with traditional Unity components. Note A Seeker will only process one pathfinding request at a time. If you request a new path before the previous one has been completed, the previous path request will be canceled. If you want to calculate multiple paths simultaneously you should skip the Seeker and [use the AstarPath class directly](https://arongranberg.com/astar/docs/callingpathfinding.html#calling-directly) . `void Start () { // Get the seeker component attached to this GameObject var seeker = GetComponent(); // Schedule a new path request from the current position to a position 10 units forward. // When the path has been calculated, the OnPathComplete method will be called, unless it was canceled by another path request seeker.StartPath(transform.position, transform.position + Vector3.forward * 10, OnPathComplete); // Note that the path is NOT calculated at this point // It has just been queued for calculation } void OnPathComplete (Path path) { // The path is now calculated! if (path.error) { Debug.LogError("Path failed: " + path.errorLog); return; } // Cast the path to the path type we were using var abPath = path as ABPath; // Draw the path in the scene view for 10 seconds for (int i = 0; i < abPath.vectorPath.Count - 1; i++) { Debug.DrawLine(abPath.vectorPath[i], abPath.vectorPath[i+1], Color.red, 10); } } `The above code will request a path from the current position of the GameObject to a position 10 units forward. When the path has been calculated, the OnPathComplete method will be called with the path as an argument. If you attach any [path modifiers](https://arongranberg.com/astar/docs/modifiers2.html) to the same GameObject as the Seeker, they will be applied to the path before the OnPathComplete method is called. Try it out in your own scene. Attach a Seeker component to a GameObject, and then attach the above script to the same GameObject. It may take a frame or two for the path to be calculated, depending on the complexity of the path, and how many other paths are scheduled at the same time. If your path requests are failing, then you may want to take a look at the page [Error messages](https://arongranberg.com/astar/docs/errormessages.html) for a list of common error messages and how to solve them. A common mistake is to assume that the path is already calculated right after the StartPath call. This is, however, incorrect, as the StartPath call will only put the path in a queue. This is done because when many units are calculating their paths at the same time, it is desirable to spread out the path calculations over several frames to avoid FPS drops. If you have enabled [multithreading](https://arongranberg.com/astar/docs/astarpath.html#threadCount) , all paths will be calculated asynchronously on separate threads. There are, of course, cases when you need to calculate the path immediately. Then you can use the [Path.BlockUntilCalculated](https://arongranberg.com/astar/docs/path/blockuntilcalculated.html#BlockUntilCalculated) method. `var path = seeker.StartPath(transform.position, transform.position + Vector3.forward * 10, OnPathComplete); path.BlockUntilCalculated(); // The path is calculated now, and the OnPathComplete callback has been called `You can also wait for the path to be calculated in a coroutine using [Path.WaitForPath](https://arongranberg.com/astar/docs/path/waitforpath.html#WaitForPath) . `IEnumerator Start () { // Get the seeker component attached to this GameObject var seeker = GetComponent(); var path = seeker.StartPath(transform.position, transform.position + Vector3.forward * 10, null); // Wait... This may take a frame or two depending on how complex the path is // The rest of the game will continue to run while we wait yield return StartCoroutine(path.WaitForPath()); // The path is calculated now // Draw the path in the scene view for 10 seconds for (int i = 0; i < path.vectorPath.Count - 1; i++) { Debug.DrawLine(path.vectorPath[i], path.vectorPath[i+1], Color.red, 10); } } `You can also create your own path objects, instead of using the Seeker's methods. This will allow you to change settings on the path object before calculating it. `// Create a new path object, the last parameter is a callback function // but it will be used internally by the seeker, so we will set it to null here // Paths are created using the static Construct call because then it can use // pooled paths, instead of creating a new path object all the time. // This is is a nice way to avoid frequent GC spikes. var p = ABPath.Construct(transform.position, transform.position+transform.forward*10, null); // For example, you can set a custom ending condition. // This one will find the shortest path that comes within 5 meters of the destination p.endingCondition = new EndingConditionProximity(p, 5.0f); // Schedule the path request by sending it to the Seeker seeker.StartPath(p, OnPathComplete); `Observant readers may notice a GC allocation occurring every time a delegate to OnPathComplete is created. It's not much, but it adds up. You can avoid this allocation by caching a delegate in a local field. `protected [OnPathDelegate](https://arongranberg.com/astar/docs/pathfinding.html#OnPathDelegate) onPathComplete; void OnEnable () { onPathComplete = OnPathComplete; } public void SearchPath () { // Now use the onPathComplete field, instead of OnPathComplete directly, to avoid a GC allocation GetComponent().StartPath(transform.position, transform.position+transform.forward*10, onPathComplete); } void OnPathComplete (Path p) { // Just in case this component was destroyed while a path was being calculated if (!this) return; } `The Seeker component is intended to handle pathfinding requests for a single character in the game. For this reason it will only process a single path request at a time. If you call StartPath when another path is already being calculated, it will log a warning saying that the previous path calculation was aborted. If you specifically wanted to cancel the previous path request you can do this without logging a warning by calling [Seeker.CancelCurrentPathRequest](https://arongranberg.com/astar/docs/seeker/cancelcurrentpathrequest.html#CancelCurrentPathRequest) . If you want to calculate multiple paths simultaneously, you should skip the Seeker. Take a look at the [Using the AstarPath class directly](https://arongranberg.com/astar/docs/callingpathfinding.html#calling-directly) section instead. ### Other types of paths There are other types of paths than the standard one, for example the [MultiTargetPath](https://arongranberg.com/astar/docs/multitargetpath.html) (Pro feature). These can be scheduled easily as well, especially the MultiTargetPath since the Seeker has a special function for it `var endPoints = new Vector3[] { transform.position + Vector3.forward * 5, transform.position + Vector3.right * 10, transform.position + Vector3.back * 15 }; // Start a multi target path, where endPoints is a Vector3[] array. // The pathsForAll parameter specifies if a path to every end point should be searched for // or if it should only try to find the shortest path to any end point. var path = seeker.StartMultiTargetPath(transform.position, endPoints, pathsForAll: true, callback: null); path.BlockUntilCalculated(); if (path.error) { Debug.LogError("Error calculating path: " + path.errorLog); return; } Debug.Log("The closest target was index " + path.chosenTarget); // Draw the path to all targets foreach (var subPath in path.vectorPaths) { for (int i = 0; i < subPath.Count - 1; i++) { Debug.DrawLine(subPath[i], subPath[i+1], Color.green, 10); } } // Draw the path to the closest target for (int i = 0; i < path.vectorPath.Count - 1; i++) { Debug.DrawLine(path.vectorPath[i], path.vectorPath[i+1], Color.red, 10); } ` Note The MultiTargetPath is an A\* [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) Project Pro Feature, so you will get an error if you try the above code using the Free version of the project. The generic way to schedule any type of path is `Path p = MyPathType.Construct (...); // Where MyPathType is for example MultiTargetPath seeker.StartPath(p, OnPathComplete); ` The Construct method is used instead of a constructor so that path pooling can be done more easily. See [Path Types](https://arongranberg.com/astar/docs/paths.html) [Pooling](https://arongranberg.com/astar/docs/pooling.html) [Path Types](https://arongranberg.com/astar/docs/example_path_types.html) for a demonstration of all path types. Using the AstarPath class directly ---------------------------------- If you want even more control of each path, then you can use the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component directly. The main function you then use is [AstarPath.StartPath](https://arongranberg.com/astar/docs/astarpath/startpath.html#StartPath) . This is useful if you want to calculate a lot of paths at the same time. The Seeker is for agents that only have one active path at a time, and if you try to request multiple paths at the same time it will only calculate the last one and cancel the rest. The Seeker internally uses the [AstarPath.StartPath](https://arongranberg.com/astar/docs/astarpath/startpath.html#StartPath) method to calculate the paths. Note The paths calculated using [AstarPath.StartPath](https://arongranberg.com/astar/docs/astarpath/startpath.html#StartPath) will not be post-processed. However, you can call [Seeker.PostProcess](https://arongranberg.com/astar/docs/seeker/postprocess.html#PostProcess) after a path has been calculated, to post-process it using the modifiers attached to a particular Seeker. `// There must be an AstarPath instance in the scene if ([AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) == null) return; // We can calculate multiple paths asynchronously for (int i = 0; i < 10; i++) { var path = ABPath.Construct(transform.position, transform.position+transform.forward*i*10, OnPathComplete); // Calculate the path by using the AstarPath component directly [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[StartPath](https://arongranberg.com/astar/docs/astarpath/startpath.html#StartPath) (path); } ` Path pooling ------------ To avoid allocations when creating new path objects, path pooling can be used. This has been skipped in the above examples, but if you care about minimizing garbage collection, it might be a good idea to use it. The built-in movement scripts already use path pooling internally. You can read more about path pooling in: [Pooling](https://arongranberg.com/astar/docs/pooling.html) . --- # Deploying for mobile/uwp - A* Pathfinding Project Deploying for mobile/uwp ======================== This page is about working with the A\* Pathfinding Project when deploying for iPhone/Android or UWP (Universal Windows Platform). Most things here apply to both iPhone and Android. But some are only relevant for iPhone since iPhone is more restrictive and thus greater care must be taken for compatibility. Universal Windows Platform (UWP) -------------------------------- Unity, for some reason, refuses to include the metadata for some .dll files in the package with the UnityPackage file. To get it working on UWP, you need to locate the Pathfinding.Ionic.Zip.dll file in your Unity project and make sure it is marked as being \*excluded\* when building for UWP. This should be the only thing you need to do to get it to work. iPhone ------ The A\* Pathfinding Project works for the most part out of the box even for iPhone. But if you are using stripping (Assembly or bytecode) you will have to locate the link.xml file, which you can find at Assets/AstarPathfindingProject/link.xml and place it at Assets/link.xml. This file will instruct the AOT (ahead-of-time) compiler not to strip out the classes mentioned in the file. If you do not do this, you might get errors in some cases, for example when attempting to use caching. Using the micro mscorlib is not supported since that strips out too much of .Net. If you are using the Fast But No Exceptions option, you will need to enable the ASTAR\_FAST\_NO\_EXCEPTIONS define since some reflection code cannot be used then. If you are using the pro version, simply open the Optimizations tab in the A\* Inspector, enable ASTAR\_FAST\_NO\_EXCEPTIONS and click Apply. If you are using the free version, open the [AstarData.cs](https://arongranberg.com/astar/docs/%3Cundefined%3E) script (in the Core folder) and add (or uncomment) this line at the top: `#define ASTAR_FAST_NO_EXCEPTIONS `Also do the same in [JsonSerializer.cs](https://arongranberg.com/astar/docs/%3Cundefined%3E) . This will hard-code references to the built-in graph types. If you have written any custom graph types, you will have to add them to the hard-coded list defined in the variable DefaultGraphTypes in [AstarData.cs](https://arongranberg.com/astar/docs/%3Cundefined%3E) . See Pathfinding.AstarData.DefaultGraphTypes Optimize for mobile ------------------- Caching Startup is a good idea when deploying for the iPhone since that will reduce startup times, especially if you are using Recast graphs. See [Saving and Loading Graphs](https://arongranberg.com/astar/docs/saveloadgraphs.html) You can also check out the various options under A\* Inspector → Optimizations as they can help increase the performance in some cases. See [Compiler Directives](https://arongranberg.com/astar/docs/compilerdirectives.html) --- # Frequently Asked Questions - A* Pathfinding Project Frequently Asked Questions ========================== ### Can the Free version be used in a commercial project? Yes, it can! Go ahead! But consider purchasing the Pro version if you make money from it to support the development of this project, as I have put quite a lot of work into it. A credit is always appreciated as well ;) --- # Fast Facts - A* Pathfinding Project Fast Facts ========== Just some random facts about the system: | | | | --- | --- | | Creator's name | Aron Granberg | | Graph structures supported | Grid, Point, Navmesh | | Node Position precision | 0.001 (1/1000) Integer values | | Node Position Range (xyz) | ± 2147483 (you may start to lose precision before that however, I would recommend keeping the world coordinates within ±16000) | | Works for mobile (e.g. iPhone) | Users have tested the project on Android and iPhone, both seem to work without any problems | --- # Keyboard Shortcuts - A* Pathfinding Project Keyboard Shortcuts ================== * **Scan Graphs** - alt+cmd+s on Mac - alt+ctrl+s on Windows (does not always work for some reason) --- # Collections - A* Pathfinding Project Namespace Collections ===================== Classes ------- [AABBTree](https://arongranberg.com/astar/docs/aabbtree.html) Axis Aligned Bounding Box Tree. [BBTree](https://arongranberg.com/astar/docs/bbtree.html) Axis Aligned Bounding Box Tree. [CircularBuffer](https://arongranberg.com/astar/docs/circularbuffer.html) Implements an efficient circular buffer that can be appended to in both directions. [GridLookup](https://arongranberg.com/astar/docs/gridlookup.html) Holds a lookup datastructure to quickly find objects inside rectangles. [HierarchicalBitset](https://arongranberg.com/astar/docs/hierarchicalbitset.html) Thread-safe hierarchical bitset. [NativeCircularBuffer](https://arongranberg.com/astar/docs/nativecircularbuffer.html) Implements an efficient circular buffer that can be appended to in both directions. [SlabAllocator](https://arongranberg.com/astar/docs/slaballocator.html) A tiny slab allocator. [SlabListExtensions](https://arongranberg.com/astar/docs/slablistextensions.html) [SpanExtensions](https://arongranberg.com/astar/docs/spanextensions.html) [UnsafeSpan](https://arongranberg.com/astar/docs/unsafespan.html) Replacement for System.Span which is compatible with earlier versions of C#. --- # Grid Graph Rules - A* Pathfinding Project Grid Graph Rules ================ Contents -------- * [Overview](https://arongranberg.com/astar/docs/gridrules.html#gridgraphrule-overview) * [Adding rules using a script](https://arongranberg.com/astar/docs/gridrules.html#gridgraphrule-scripting) * [Writing Custom Rules](https://arongranberg.com/astar/docs/gridrules.html#gridgraphrule-custom-rule) Overview -------- The [GridGraph](https://arongranberg.com/astar/docs/gridgraph.html) has a flexible system of rules that can be applied. These rules modify the nodes in various ways. For example, a rule can apply a tag to a node based on the layer of the GameObject below the node, or it can apply a penalty to the node based on the slope of the surface. You can add new rules by clicking the "Add Rule" button in the GridGraph inspector. ![](https://arongranberg.com/astar/docs/images/rules/rules_editor@2x.png) The available rules are: * [Penalty from slope angle](https://arongranberg.com/astar/docs/ruleanglepenalty.html) ![](https://arongranberg.com/astar/docs/images/gridgraph/rule_penalty_from_slope.png) * [Penalty from elevation](https://arongranberg.com/astar/docs/ruleelevationpenalty.html) ![](https://arongranberg.com/astar/docs/images/gridgraph/rule_penalty_from_elevation.png) * [Per layer modifications](https://arongranberg.com/astar/docs/ruleperlayermodifications.html) ![](https://arongranberg.com/astar/docs/images/gridgraph/rule_per_layer.png) * [Texture](https://arongranberg.com/astar/docs/ruletexture.html) (set the penalty and walkability based on a texture) ![](https://arongranberg.com/astar/docs/images/gridgraph/rule_texture.png) Adding rules using a script --------------------------- You can also add rules from a script: `// Get the first grid graph in the scene var gridGraph = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .gridGraph; gridGraph.rules.AddRule(new [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) .[Graphs](https://arongranberg.com/astar/docs/graphs2.html) .[Grid](https://arongranberg.com/astar/docs/grid.html) .[Rules](https://arongranberg.com/astar/docs/rules.html) .[RuleAnglePenalty](https://arongranberg.com/astar/docs/ruleanglepenalty.html) { penaltyScale = 10000, curve = AnimationCurve.Linear(0, 0, 90, 1), }); ` Writing Custom Rules -------------------- If you want to write your own grid graph rules, then check out: [Writing Custom Grid Graph Rules](https://arongranberg.com/astar/docs/gridruleswrite.html) . --- # Recast graph on a moving surface - A* Pathfinding Project Recast graph on a moving surface ================================ Example scene which demonstrates navigation on a moving surface. ![](https://arongranberg.com/astar/docs/images/generated/scenes/RecastMoving/overview.png) This movement scene is a bit different. The agent moves around on a spaceship that is simultaneously moving around in space. Contents -------- * [Graph setup](https://arongranberg.com/astar/docs/example_recast_moving.html#example_recast_moving_graph) * [Detailed setup](https://arongranberg.com/astar/docs/example_recast_moving.html#example_recast_setup) Graph setup ----------- ![](https://arongranberg.com/astar/docs/images/generated/scenes/RecastMoving/graphsettings@2x.png) Moving every single node in the graph every frame would be slow, and propagating this information to already calculated paths would also be pretty tricky. So instead, the movement script that we use here ( [LocalSpaceRichAI](https://arongranberg.com/astar/docs/localspacerichai.html) ) cheats. The graph in the scene is actually static. It stays in the same position as the ship moves around. However, when the graph is scanned as the game starts, the position of the ship is recorded. When it is time to calculate a path, the movement script will transform its position and destination so that it looks as if the ship was still at its initial position. This means it will match the scanned graph perfectly. Similarly, when it follows the path, it will transform all points on the path to account for the current position and rotation of the ship. This has some limitations, for example navmesh cutting and other graph updates will not work. But following a path works just fine regardless of how the ship moves. ### Detailed setup The scene is configured like this: 1. The ship is added. This can be any mesh or collection of meshes. 2. A recast graph is added, and configured to cover the ship at its initial position. ![](https://arongranberg.com/astar/docs/images/generated/scenes/RecastMoving/graphsettings@2x.png) 3. An agent is added as a child of the ship GameObject. This ensures that it will move with the ship. 4. The [LocalSpaceGraph](https://arongranberg.com/astar/docs/localspacegraph.html) component is added to the ship GameObject. This will track the initial position of the ship, and provide the means for the agent to translate back and forth between the ship's coordinate system and the world coordinate system. 5. The [LocalSpaceRichAI](https://arongranberg.com/astar/docs/localspacerichai.html) component is added to the agent, and the [LocalSpaceGraph](https://arongranberg.com/astar/docs/localspacegraph.html) component is assigned to its [LocalSpaceRichAI.graph](https://arongranberg.com/astar/docs/localspacerichai.html#graph) field. ![](https://arongranberg.com/astar/docs/images/generated/scenes/RecastMoving/bot@2x.png) 6. The ship is made to move using the [BezierMover](https://arongranberg.com/astar/docs/beziermover.html) component. This component moves the ship through a series of points, along a smooth curve. --- # AABBTree - A* Pathfinding Project Class AABBTree ============== Public Axis Aligned Bounding Box Tree. Holds a bounding box tree with arbitrary data. The tree self-balances itself regularly when nodes are added. A\* Pro Feature This is an A\* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A\* Pathfinding Project or the functionality might be limited. The Pro version can be bought [here](http://www.arongranberg.com/astar/buy) Inner Types ----------- [AABBComparer](https://arongranberg.com/astar/docs/aabbcomparer.html) [Key](https://arongranberg.com/astar/docs/key.html) A key to a leaf node in the tree. [Node](https://arongranberg.com/astar/docs/node.html) Public Methods -------------- [Add](https://arongranberg.com/astar/docs/aabbtree/add.html#Add) (bounds, value) [Clear](https://arongranberg.com/astar/docs/aabbtree/clear.html#Clear) () Removes all nodes from the tree. [GetBounds](https://arongranberg.com/astar/docs/aabbtree/getbounds.html#GetBounds) (key) Bounding box of a given node. [Move](https://arongranberg.com/astar/docs/aabbtree/move.html#Move) (key, bounds) Moves a node to a new position. [Query](https://arongranberg.com/astar/docs/aabbtree/query.html#Query) (bounds, buffer) Queries the tree for all objects that touch the specified bounds. [QueryTagged](https://arongranberg.com/astar/docs/aabbtree/querytagged.html#QueryTagged) (buffer, clearTags=…) Queries the tree for all objects that have been previously tagged using the [Tag](https://arongranberg.com/astar/docs/aabbtree/tag.html#Tag) method. [Rebuild](https://arongranberg.com/astar/docs/aabbtree/rebuild.html) (\[...\]) ... [Remove](https://arongranberg.com/astar/docs/aabbtree/remove.html#Remove) (key) [Tag](https://arongranberg.com/astar/docs/aabbtree/tag.html) (...) Tags a... Public Variables ---------------- this\[Key key\] User data for a node in the tree. Public ##### T this\[Key key\] User data for a node in the tree. Private/Protected Members ------------------------- [AllocNode](https://arongranberg.com/astar/docs/aabbtree/allocnode.html#AllocNode) () [ArgMax](https://arongranberg.com/astar/docs/aabbtree/argmax.html#ArgMax) (v) [ExpansionRequired](https://arongranberg.com/astar/docs/aabbtree/expansionrequired.html#ExpansionRequired) (b, b2) [FreeNode](https://arongranberg.com/astar/docs/aabbtree/freenode.html#FreeNode) (node) NoNode Private Static ##### const int NoNode = -1 [QueryNode](https://arongranberg.com/astar/docs/aabbtree/querynode.html#QueryNode) (node, bounds, buffer) [QueryTaggedNode](https://arongranberg.com/astar/docs/aabbtree/querytaggednode.html#QueryTaggedNode) (node, clearTags, buffer) [TagNode](https://arongranberg.com/astar/docs/aabbtree/tagnode.html#TagNode) (node, bounds) [Validate](https://arongranberg.com/astar/docs/aabbtree/validate.html#Validate) (node) freeNodes Private Readonly ##### Stack freeNodes = new Stack() nodes Private ##### [Node](https://arongranberg.com/astar/docs/node.html) \[\] nodes = new [Node](https://arongranberg.com/astar/docs/node.html) \[0\] rebuildCounter Private ##### int rebuildCounter = 64 root Private ##### int root = [NoNode](https://arongranberg.com/astar/docs/aabbtree.html#NoNode) --- # Path Types - A* Pathfinding Project Group Path Types ================ Collection of the most used path types. [ABPath](https://arongranberg.com/astar/docs/abpath.html) Basic path, finds the shortest path from A to B. [ConstantPath](https://arongranberg.com/astar/docs/constantpath.html) Finds all nodes within a specified distance from the start. [FleePath](https://arongranberg.com/astar/docs/fleepath.html) Returns a path heading away from a specified point to avoid. [FloodPath](https://arongranberg.com/astar/docs/floodpath.html) Calculates paths from everywhere to a single point. [FloodPathTracer](https://arongranberg.com/astar/docs/floodpathtracer.html) Traces a path created with the [Pathfinding.FloodPath](https://arongranberg.com/astar/docs/floodpath.html) . [MultiTargetPath](https://arongranberg.com/astar/docs/multitargetpath.html) A path which searches from one point to a number of different targets in one search or from a number of different start points to a single target. [RandomPath](https://arongranberg.com/astar/docs/randompath.html) Finds a path in a random direction from the start node. [XPath](https://arongranberg.com/astar/docs/xpath.html) Extended [Path](https://arongranberg.com/astar/docs/path.html) . --- # Utilities - A* Pathfinding Project Group Utilities =============== Collection of utility classes which might be useful. [AstarMath](https://arongranberg.com/astar/docs/astarmath.html) Utility functions for working with numbers and strings. [AstarSplines](https://arongranberg.com/astar/docs/astarsplines.html) Contains various spline functions. [GraphUpdateUtilities](https://arongranberg.com/astar/docs/graphupdateutilities.html) Contains useful functions for updating graphs. [GraphUtilities](https://arongranberg.com/astar/docs/graphutilities.html) Contains utility methods for getting useful information out of graph. [PathUtilities](https://arongranberg.com/astar/docs/pathutilities.html) Contains useful functions for working with paths and nodes. [Polygon](https://arongranberg.com/astar/docs/polygon.html) Utility functions for working with polygons, lines, and other vector math. [VectorMath](https://arongranberg.com/astar/docs/vectormath.html) Various vector math utility functions. --- # Recast graph with tags - A* Pathfinding Project Recast graph with tags ====================== Example scene which demonstrates tags and penalties on a recast graph. ![](https://arongranberg.com/astar/docs/images/generated/scenes/RecastTags/overview.png) This example scene demonstrates how to use tags to make different agents be able to traverse different areas of the graph. It also shows how to make some agents try to avoid moving over certain areas of the graph. Contents -------- * [Graph setup](https://arongranberg.com/astar/docs/example_recast_tags.html#example_recast_tags_graph) * [Tags that influence traversability](https://arongranberg.com/astar/docs/example_recast_tags.html#example_recast_tags_tags) * [Tags with penalties](https://arongranberg.com/astar/docs/example_recast_tags.html#example_recast_tags_penalties) Graph setup ----------- ![](https://arongranberg.com/astar/docs/images/generated/scenes/RecastTags/graphsettings@2x.png) A [RecastGraph](https://arongranberg.com/astar/docs/recastgraph.html) or a [GridGraph](https://arongranberg.com/astar/docs/gridgraph.html) would work about equally well for this scene. But a recast graph was arbitrarily chosen for this particular example. The ground is pretty much flat, so the recast graph does not require many tweaks from the default settings. The most notable changes are: * The cell size of the graph has been reduced a bit to make it represent the world more accurately. * The character radius has also been changed to reflect the size of the agents that will be used in the scene. * The bounding box of the graph has been changed to fit the world. * The layer mask has been changed to only include the Default layer. This is because all obstacles in this scene are on the Default layer. Tags that influence traversability ---------------------------------- There is one red corridor, and one blue corridor in the scene. There are also two agents, one red and one blue. The red agent is only able to traverse the red corridor, and the blue agent is only able to traverse the blue corridor. Your browser does not support the video tag. This is implemented using [tags](https://arongranberg.com/astar/docs/tags.html) . The ground in the red corridor has been assigned the tag "Red", and the blue corridor has been assigned the tag "Blue". Similarly, the agents have been configured to only be able to traverse the default ground tag, as well as the tag that corresponds to their color. ![](https://arongranberg.com/astar/docs/images/generated/scenes/RecastTags/recastmeshobjcorridor@2x.png) On the ground tiles in the corridor, the [RecastNavmeshModifier](https://arongranberg.com/astar/docs/recastnavmeshmodifier.html) component has been added. This allows us to change how the recast graph scans these meshes. In this case, the surface type has been changed to "Walkable Surface with Tag", and the tag has been changed to "Red" or "Blue" respectively. ![](https://arongranberg.com/astar/docs/images/generated/scenes/RecastTags/redbot@2x.png) The [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component, which each agent has, has been tweaked a bit to account for the tags. In particular, under the "Tags" foldout, the tag which each bot is not allowed to traverse has been disabled. In the screenshot, the inspector for the red bot is shown. It will treat all nodes with the blue tag as not traversable. See [Working with tags](https://arongranberg.com/astar/docs/tags.html) Tags with penalties ------------------- Building on the tags described in the previous section, there's also a black region in the scene. This region is traversable by both agents, but the blue agent will try to avoid it unless it has to take a very long detour to avoid it. Your browser does not support the video tag. The blue agent will avoid the black region if it can do so with only a short detour. Your browser does not support the video tag. The blue agent will traverse the black region if it has to take a long detour to avoid it. The way this is configured is that on the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component, under the "Tags" foldout, the "BlackHighPenalty" tag has been given a high penalty for the blue agent. The ground is tagged with the "BlackHighPenalty" tag using the [RecastNavmeshModifier](https://arongranberg.com/astar/docs/recastnavmeshmodifier.html) component, similar to how it was done in the previous section. ![](https://arongranberg.com/astar/docs/images/generated/scenes/RecastTags/bluebot@2x.png) See [Working with tags](https://arongranberg.com/astar/docs/tags.html) --- # Using Modifiers - A* Pathfinding Project Using Modifiers =============== Modifiers are small scripts which can hook into the [Seeker](https://arongranberg.com/astar/docs/seeker.html) and pre- and/or post-process the path before it is returned to the caller. Modifiers are used by simply attaching the scripts to the same GameObject as the Seeker component is attached to. They will work automatically without any code modifications. This can, for example, be a Raycast Modifier which removes unnecessary nodes in a path to make it shorter but still valid. Or a Smooth Modifier which subdivides the path and smooths it to make it more aesthetically appealing. Below is a comparison of a few of the most common types of modifiers/combination of modifiers on a grid graph. ![](https://arongranberg.com/astar/docs/images/modifier_comparison_grid.png) See [SimpleSmoothModifier](https://arongranberg.com/astar/docs/simplesmoothmodifier.html) [RaycastModifier](https://arongranberg.com/astar/docs/raycastmodifier.html) [FunnelModifier](https://arongranberg.com/astar/docs/funnelmodifier.html) [RadiusModifier](https://arongranberg.com/astar/docs/radiusmodifier.html) [StartEndModifier](https://arongranberg.com/astar/docs/startendmodifier.html) [AlternativePath](https://arongranberg.com/astar/docs/alternativepath.html) [Modifiers](https://arongranberg.com/astar/docs/modifiers.html) Note Not all movement scripts use modifiers. The [AIPath](https://arongranberg.com/astar/docs/aipath.html) and [AILerp](https://arongranberg.com/astar/docs/ailerp.html) movement scripts support all modifiers; however, the [RichAI](https://arongranberg.com/astar/docs/richai.html) movement script will ignore most of them (all that smooth and simplify the path). And the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) movement script does not use modifiers at all. The RichAI and FollowerEntity scripts include their own path smoothing code. You can still attach other modifiers when using the RichAI movement script. Simple Smooth Modifier ---------------------- The [simple smooth modifier](https://arongranberg.com/astar/docs/simplesmoothmodifier.html) is a modifier to smooth the path. It can do that either by just subdividing it and moving the vertices closer to each other or by using splines, namely the Bezier curve. Below are two images showing a path with the smooth modifier turned off first and then on. Note that the smoothed path cuts the corners a bit; this can be a problem with the smooth modifier since it does not take world geometry into account when smoothing. ![](https://arongranberg.com/astar/docs/images/smoothModifier_off.png) ![](https://arongranberg.com/astar/docs/images/smoothModifier_on.png) For variable documentation, look at the [Simple Smooth Modifier documentation](https://arongranberg.com/astar/docs/simplesmoothmodifier.html) Funnel Modifier --------------- The [funnel modifier](https://arongranberg.com/astar/docs/funnelmodifier.html) is a modifier for simplifying paths on navmeshes or grid graphs in a fast and exact way. As the name implies, it applies the [funnel algorithm](http://digestingduck.blogspot.com/2010/03/simple-stupid-funnel-algorithm.html) to the path. This will return the shortest path inside the path corridor the pathfinder calculated ![](https://arongranberg.com/astar/docs/images/funnelModifier_on.png) You can see a list of all modifiers if you click on Modules above and go to "Modifiers". Raycast Modifier ---------------- The [raycast modifier](https://arongranberg.com/astar/docs/raycastmodifier.html) simplifies paths by doing a series of straight line checks. This modifier is primarily useful on grid graphs, though depending on your game, it can be useful if you are using a point graph too. ![](https://arongranberg.com/astar/docs/images/raycast_modifier_quality.gif) Custom modifiers ---------------- It is also possible to write your own path modifiers. See [Writing Modifiers](https://arongranberg.com/astar/docs/writemodifiers.html) --- # Recast graph on a terrain - A* Pathfinding Project Recast graph on a terrain ========================= Example scene with a terrain and a recast graph. ![](https://arongranberg.com/astar/docs/images/generated/scenes/RecastTerrain/overview.png) This example scene demonstrates how to use a recast graph on a Unity terrain. It also demonstrates how to use tags to make the agent prefer moving on the dirt road instead of on the grass. In the scene, you can move the cursor around, and the agent will move to that position. Contents -------- * [Graph setup](https://arongranberg.com/astar/docs/example_recast_terrain.html#example_recast_terrain_graph) * [Making the agent prefer the dirt road](https://arongranberg.com/astar/docs/example_recast_terrain.html#example_recast_terrain_agent) Graph setup ----------- The recast graph works pretty much out of the box on Unity terrains. The only thing you need to ensure is that the graph has the [rasterize terrain](https://arongranberg.com/astar/docs/collectionsettings.html#rasterizeTerrain) option enabled. The recast graph converts the terrain into a mesh before rasterizing it. To improve performance when rasterizing the terrain, the heightmap is downsampled. You can adjust how much the recast graph should downsample the heightmap using the [Terrain Heightmap Downsampling Factor](https://arongranberg.com/astar/docs/collectionsettings.html#terrainHeightmapDownsamplingFactor) field. Lower values will result in a more accurate graph. Using higher values can speed up scanning a bit, and is of particular importance if you want to do graph updates at runtime. Any trees on the terrain will be automatically detected and added to the graph. However, only colliders will be rasterized on trees. Rasterizing the meshes in tree prefabs is not supported. This is usually what you want, since rasterizing all meshes on all trees can very quickly make the scan take a very long time. Colliders on trees will be rasterized regardless of what the [rasterize colliders](https://arongranberg.com/astar/docs/collectionsettings.html#rasterizeColliders) field is set to. ![](https://arongranberg.com/astar/docs/images/generated/scenes/RecastTerrain/graphsettings@2x.png) Making the agent prefer the dirt road ------------------------------------- The agent in the scene will prefer to move on the dirt road, since it has a lower cost than the grass around it. Your browser does not support the video tag. To achieve this, the recast graph has been configured with a per-terrain layer modification (see screenshot in previous section) that marks the graph as having the "Dirt Road" tag everywhere the dirt texture has been painted. ![](https://arongranberg.com/astar/docs/images/generated/scenes/RecastTerrain/terraintagswithgraph.png) The [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component on the agent has been configured such that the "Basic Ground" tag has a cost per world unit of 2000, but the "Dirt Road" tag has a cost per world unit of only 1000. This means it is twice as costly to move on the grass than on the dirt road. You configure this under the **Tags** foldout in the FollowerEntity component, or in the Seeker component if you are using that instead. ![](https://arongranberg.com/astar/docs/images/scenes/RecastTerrain/tags_foldout@2x.png) See [Working with tags](https://arongranberg.com/astar/docs/tags.html) [RecastGraph.perTerrainLayerModifications](https://arongranberg.com/astar/docs/recastgraph.html#perTerrainLayerModifications) . [FollowerEntity.pathfindingSettings.tagCostMultipliers](https://arongranberg.com/astar/docs/pathrequestsettings.html#tagCostMultipliers) . --- # Using nodes - A* Pathfinding Project Using nodes =========== Introduction to how to use nodes. Contents -------- * [Introduction](https://arongranberg.com/astar/docs/usingnodes.html#using_nodes_intro) * [Finding Nodes close to Positions](https://arongranberg.com/astar/docs/usingnodes.html#getnearest) * [Closest Point on Nodes](https://arongranberg.com/astar/docs/usingnodes.html#getnearest-info) * [Node connections](https://arongranberg.com/astar/docs/usingnodes.html#node-connections) * [Node properties](https://arongranberg.com/astar/docs/usingnodes.html#node-properties) * [TriangleMeshNode](https://arongranberg.com/astar/docs/usingnodes.html#meshnodes) * [Reachability](https://arongranberg.com/astar/docs/usingnodes.html#reachability) Introduction ------------ Pathfinding is done on graphs of nodes. These nodes are connected to each other in various ways. In grids, each tile is a node and they are connected to their 4 or 8 adjacent tiles. In navmesh/recast graphs, each triangle is a node and the nodes are positioned in the centers of the triangles. ![](https://arongranberg.com/astar/docs/images/node_graph.png) Explaining how the whole search algorithm works is beyond the scope of this tutorial, but here is a nice animation from [Wikipedia](https://en.wikipedia.org/wiki/A*_search_algorithm) : ![](https://arongranberg.com/astar/docs/images/astar_progress_animation.gif) See [Graph Updates during Runtime](https://arongranberg.com/astar/docs/graphupdates.html) . [Accessing graph data](https://arongranberg.com/astar/docs/accessingdata.html) Finding Nodes close to Positions -------------------------------- Often you want to figure out which node is the closest one to a point in the world. Usually when just dealing with the built-in movement scripts, you do not have to deal with nodes at all, but as you dig deeper it becomes very useful. `// Find the closest node to this GameObject's position GraphNode node = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (transform.position).node; if (node.Walkable) { // Yay, the node is walkable, we can place a tower here or something } `There are also cases where you want to get only certain nodes, such as "What is the closest \*Walkable\* node to this position?". This can be accomplished using the [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint.html) class. `GraphNode node = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (transform.position, NearestNodeConstraint.Walkable).node; `You can also create custom constraints: `var constraint = NearestNodeConstraint.None; // Constrain the search to walkable nodes only constraint.walkable = NearestNodeConstraint.WalkabilityConstraint.Walkable; // Constrain the search to only nodes with tag 3 or tag 5 // The 'tags' field is a bitmask constraint.tags = (1 << 3) | (1 << 5); var info = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (transform.position, constraint); var node = info.node; var closestPoint = info.position; `The search range of these constraints is not unlimited, but quite large. The maximum distance can be set in A\* Inspector → Settings → Max Nearest Node Distance or [AstarPath.maxNearestNodeDistance](https://arongranberg.com/astar/docs/astarpath.html#maxNearestNodeDistance) . If the closest node is further away than the 'Max Nearest Node Distance' then the GetNearest method will return a null node. See The [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint.html) struct has a few more options that you can take a look at if you want. ### Closest Point on Nodes You may have noticed above that to get the node from the GetNearest call we had to access the **node** field. The GetNearest method returns an [NNInfo](https://arongranberg.com/astar/docs/nninfo.html) struct which contains two fields. The first one is the [node](https://arongranberg.com/astar/docs/nninfo.html#node) field which contains the best node (or null if no node could be found). The second one is the [position](https://arongranberg.com/astar/docs/nninfo.html#position) field which contains the closest point on that node to the query point. On grid graphs, the nodes are thought of as squares so the position field will then contain the closest point inside that square to the query point. On navmesh based graphs (RecastGraph and NavMeshGraph) the position field will contain the closest point on the closest triangle. Point nodes do not have a surface so the position will just be set to the node's position. `var info = AstarPath.active.GetNearest(transform.position); var node = info.node; var closestPoint = info.position; ` Node connections ---------------- Each node stores which other nodes it is connected to. How this is represented depends on the graph. Grid graphs, for example, take advantage of their grid structure and can store all connections to their adjacent grid nodes in just a single byte! This is significantly more memory efficient compared to, for example, an array of references to other nodes as that would use at least 80 times more memory. You can access all connections of a node using the [GetConnections](https://arongranberg.com/astar/docs/graphnode/getconnections.html#GetConnections) method. This method takes a delegate which will be called for each node it is connected to and abstracts away the underlying representation. `GraphNode node = ...; // Draw a line to all nodes that this node is connected to node.GetConnections(otherNode => { Debug.DrawLine((Vector3)node.position, (Vector3)otherNode.position); }); ` See You can also add or remove custom connections from nodes. For more information, take a look at [Writing Graph Generators](https://arongranberg.com/astar/docs/writinggraphgenerators.html) . Node properties --------------- There are a few methods on node instances that are of interest. Firstly, nodes have a [position](https://arongranberg.com/astar/docs/graphnode.html#position) field which is the position of the node in world space. This position is stored as an [Int3](https://arongranberg.com/astar/docs/int3.html) , not as a Vector3. You can, however, easily convert between Vector3s and Int3s. `GraphNode node = ...; Vector3 v3position = (Vector3)node.position; node.position = (Int3)v3position; ` You can also access various properties on the node such as if it is walkable, which tag it has and its penalty. `bool walkable = node.Walkable; uint tag = node.Tag; uint penalty = node.Penalty; ` See [Graph Updates during Runtime](https://arongranberg.com/astar/docs/graphupdates.html) if you want to learn more about how to change the properties of nodes. There are also some utility methods for finding points on nodes. You can get a random point on the node's surface: `Vector3 randomPoint = node.RandomPointOnSurface(); `and the surface area of the node (this will be zero for point nodes): `float surfaceArea = node.SurfaceArea(); ` TriangleMeshNode ---------------- Mesh nodes are used on navmesh and recast graphs. See [Graph Types](https://arongranberg.com/astar/docs/graphtypes.html) These have a few more utilities. You can get the closest point on just that node. Either in XZ space (i.e., as if you would view it from above) or in 3D space. `TriangleMeshNode node = ...; Vector3 closestPoint = node.ClosestPointOnNode(somePoint); Vector3 closestPoint = node.ClosestPointOnNodeXZ(somePoint); `You can also check if a specific point is inside that node (when seen from above). `if (node.ContainsPoint(somePoint)) { // The point is inside the node } ` You can get the vertices of the triangle that the node represents using `// Individually Int3 v0 = node.GetVertex(0); Int3 v1 = node.GetVertex(1); Int3 v2 = node.GetVertex(2); ` `// Or combined (faster) Int3 v0, v1, v2; node.GetVertices(out v0, out v1, out v2); ` Reachability ------------ Often it is useful to determine if a character can reach a certain node. Keep in mind that when a path is calculated, it will by default try to move to the closest node to the target that it can reach (up to a maximum distance of [AstarPath.maxNearestNodeDistance](https://arongranberg.com/astar/docs/astarpath.html#maxNearestNodeDistance) as discussed earlier). So often you do not have to care about this. The pathfinding system precalculates which nodes are reachable from which other nodes by calculating the [connected components](https://en.wikipedia.org/wiki/Connected_component_(graph_theory)) of the graphs. This is what is visible as the different colors in the scene view (when the [Graph Coloring](https://arongranberg.com/astar/docs/astarpath.html#debugMode) option is set to 'Areas'). Each node's [Area](https://arongranberg.com/astar/docs/graphnode.html#Area) field is set to the index of its connected component. If 2 nodes have the same area, it means there is a valid path between them. You can also check this using the [PathUtilities.IsPathPossible](https://arongranberg.com/astar/docs/pathutilities/ispathpossible.html#IsPathPossible3) method. `var node1 = AstarPath.active.GetNearest(somePoint1); var node2 = AstarPath.active.GetNearest(somePoint2); if (PathUtilities.IsPathPossible(node1, node2)) { // There is a valid path between the nodes } `The process of calculating these areas or connected components is referred to as 'flood filling' in various parts of the documentation and code. You can also supply a tag mask or a list of nodes to the IsPathPossible method. See [Pathfinding.PathUtilities](https://arongranberg.com/astar/docs/pathutilities.html) You can also find all nodes that can be reached from a given node. `List reachableNodes = PathUtilities.GetReachableNodes(node); ` See There are also several ways of finding all nodes up to a specific distance from a node. For more info, take a look at [Wandering AI Tutorial](https://arongranberg.com/astar/docs/wander.html) . --- # Navmesh Cutting - A* Pathfinding Project Navmesh Cutting =============== Tutorial on navmesh cutting. ![](https://arongranberg.com/astar/docs/images/generated/inspectors/NavmeshCut@2x.png) Navmesh cutting is used to cut holes in an existing navmesh generated by a recast or navmesh graph. With navmesh cutting you can remove (cut) parts of the navmesh that is blocked by obstacles such as a new building in an RTS game however you cannot add anything new to the navmesh or change the positions of the nodes. Normal graph updates on recast/navmesh graphs, in contrast, only allow either just changing parameters on existing nodes (e.g make a whole triangle unwalkable), which is not very flexible, or recalculate whole tiles, which can be slow. Navmesh cutting is typically significantly faster than recalculating whole tiles from scratch in a recast graph. Your browser does not support the video tag. The [NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) component uses a 2D shape to cut the navmesh with. This shape can be produced by either one of the built-in 2D shapes (rectangle/circle) or one of the 3D shapes (cube/sphere/capsule) which will be projected down to a 2D shape when cutting happens. You can also specify a custom 2D mesh to use as a cut. ![](https://arongranberg.com/astar/docs/images/navmeshcut.png) Note that the rectangle/circle shapes are not 3D. If you rotate them, you will see that the 2D shape will be rotated and then just projected down on the XZ plane. Therefore it is recommended to use the 3D shapes (cube/sphere/capsule) in most cases since those are easier to use. In the scene view the [NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) looks like an extruded 2D shape because a navmesh cut also has a height. It will only cut the part of the navmesh which it touches. For performance reasons it only checks the bounding boxes of the triangles in the navmesh, so it may cut triangles whoose bounding boxes it intersects even if the triangle does not intersect the extruded shape. However in most cases this does not make a large difference. It is also possible to set the navmesh cut to dual mode by setting the [isDual](https://arongranberg.com/astar/docs/navmeshcut.html#isDual) field to true. This will prevent it from cutting a hole in the navmesh and it will instead just split the navmesh along the border but keep both the interior and the exterior. This can be useful if you for example want to change the penalty of some region which does not neatly line up with the navmesh triangles. It is often combined with the [GraphUpdateScene](https://arongranberg.com/astar/docs/graphupdatescene.html) component (however note that the [GraphUpdateScene](https://arongranberg.com/astar/docs/graphupdatescene.html) component will not automatically reapply the penalty if the graph is updated again). By default the navmesh cut does not take rotation or scaling into account. If you want to do that, you can set the [useRotationAndScale](https://arongranberg.com/astar/docs/navmeshcut.html#useRotationAndScale) field to true. **Custom meshes** For most purposes you can use the built-in shapes, however in some cases a custom cutting mesh may be useful. The custom mesh should be a flat 2D shape like in the image below. The script will then find the contour of that mesh and use that shape as the cut. Make sure that all normals are smooth and that the mesh contains no UV information. Otherwise Unity might split a vertex and then the script will not find the correct contour. You should not use a very high polygon mesh since that will create a lot of nodes in the navmesh graph and slow down pathfinding because of that. For very high polygon meshes it might even cause more suboptimal paths to be generated if it causes many thin triangles to be added to the navmesh. ![](https://arongranberg.com/astar/docs/images/navmeshcut_mesh.png) **Update frequency** Navmesh cuts are typically pretty fast, so you may be tempted to make them update the navmesh very often (once every few frames perhaps), just because you can spare the CPU power. However, updating the navmesh too often can also have consequences for agents that are following paths on the graph. If a navmesh cut updates the graph near an agent, it will usually have to recalculate its path. If this happens too often, this can lead to the pathfinding worker threads being overwhelmed by pathfinding requests, causing higher latency for individual pathfinding requests. This can, in turn, make agents less responsive. So it's recommended to keep the update frequency reasonable. After all, a player is unlikely to notice if the navmesh was updated 20 times per second or 2 times per second (or even less often). You can primarily control this using the [updateDistance](https://arongranberg.com/astar/docs/navmeshcut.html#updateDistance) and [updateRotationDistance](https://arongranberg.com/astar/docs/navmeshcut.html#updateRotationDistance) fields. But you can also control the global frequency of updates. This is explained in the next section. **Control updates through code** Navmesh cuts are applied periodically, but sometimes you may want to ensure the graph is up to date right now. Then you can use the following code. `// Schedule pending updates to be done as soon as the pathfinding threads // are done with what they are currently doing. [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[navmeshUpdates](https://arongranberg.com/astar/docs/astarpath.html#navmeshUpdates) .ForceUpdate(); // Block until the updates have finished [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[FlushGraphUpdates](https://arongranberg.com/astar/docs/astarpath/flushgraphupdates.html#FlushGraphUpdates) (); `You can also control how often the scripts check for if any navmesh cut has changed. If you have a very large number of cuts it may be good for performance to not check it as often. `// Check every frame (the default) [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[navmeshUpdates](https://arongranberg.com/astar/docs/astarpath.html#navmeshUpdates) .updateInterval = 0; // Check every 0.1 seconds [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[navmeshUpdates](https://arongranberg.com/astar/docs/astarpath.html#navmeshUpdates) .updateInterval = 0.1f; // Never check for changes [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[navmeshUpdates](https://arongranberg.com/astar/docs/astarpath.html#navmeshUpdates) .updateInterval = -1; // You will have to schedule updates manually using [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[navmeshUpdates](https://arongranberg.com/astar/docs/astarpath.html#navmeshUpdates) .ForceUpdate(); `You can also find this setting in the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) inspector under Settings. ![](https://arongranberg.com/astar/docs/images/navmeshcut_update_interval@2x.png) **Navmesh cutting and tags/penalties** Navmesh cuts can only preserve tags for updates which happen when the graph is first scanned, or when a recast graph tile is recalculated from scratch. This means that any tags that you apply dynamically using e.g. a [GraphUpdateScene](https://arongranberg.com/astar/docs/graphupdatescene.html) component may be lost when a navmesh cut is applied. If you need to combine tags and navmesh cutting, it is therefore strongly recommended to use the [RecastNavmeshModifier](https://arongranberg.com/astar/docs/recastnavmeshmodifier.html) component to apply the tags, as that will work smoothly with navmesh cutting. Internally, what happens is that when a graph is scanned, the navmesh cutting subsystem takes a snapshot of all triangles in the graph, including tags. This data will then be referenced every time cutting happens and the tags from the snapshot will be copied to the new triangles after cutting has taken place. You can also apply tags and penalties using a graph update after cutting has taken place. For example by subclassing a navmesh cut and overriding the [UsedForCut](https://arongranberg.com/astar/docs/navmeshcut/usedforcut.html#UsedForCut) method. However, it is recommended to use the [RecastNavmeshModifier](https://arongranberg.com/astar/docs/recastnavmeshmodifier.html) as mentioned before, as this is a more robust solution. A\* Pro Feature This is an A\* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A\* Pathfinding Project or the functionality might be limited. The Pro version can be bought [here](http://www.arongranberg.com/astar/buy) See [http://www.arongranberg.com/2013/08/navmesh-cutting/](http://www.arongranberg.com/2013/08/navmesh-cutting/) Version This component is only available in 2022.3 and later, due to Unity bugs in earlier versions. --- # Local Avoidance - A* Pathfinding Project Local Avoidance =============== How to use the local avoidance in the A\* [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) Project. The local avoidance included in the A\* [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) Project is based on RVO: Reciprocal [Velocity Obstacles](https://en.wikipedia.org/wiki/Velocity_obstacle) and more specifically uses the ORCA algorithm. It is well suited for, for example, human agents that move around. It is not particularly well suited to vehicles that cannot change their velocity quickly. A\* Pro Feature This is an A\* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A\* Pathfinding Project or the functionality might be limited. The Pro version can be bought [here](http://www.arongranberg.com/astar/buy) Overview -------- Local avoidance is used for making agents avoid each other, and also for simpler dynamic obstacle avoidance. In contrast to pathfinding, local avoidance is, as the name implies, very local. It only cares about the agents and obstacles that are close to the agent. It does not care about the global goal of the agent and cannot find its way around larger obstacles. On the other hand, handling small dynamic objects with pathfinding is often not very efficient, as paths would have to be recalculated for every tiny change. Local avoidance is much better suited for this. The RVO system is divided into two parts. First, there is the core simulation code. It is completely independent of Unity-specific objects, such as GameObjects and MonoBehaviours. This core handles all simulation of local avoidance agents. The second part is the Unity interface. Many of those classes are just wrappers for the corresponding core classes. The [RVOController](https://arongranberg.com/astar/docs/rvocontroller.html) class is, for example, just a wrapper class for the [Pathfinding.RVO.IAgent](https://arongranberg.com/astar/docs/iagent.html) interface. Examples -------- There are three example scenes included which show how the local avoidance system works. * The one called "Local Avoidance" * [Spherical world](https://arongranberg.com/astar/docs/example_spherical.html) * [Lightweight Local Avoidance Simulation](https://arongranberg.com/astar/docs/example_local_avoidance_lightweight.html) Integration ----------- In your scene, you should have exactly one [RVOSimulator](https://arongranberg.com/astar/docs/rvosimulator.html) component. All other components will find this component automatically. How you configure your agents depends on which movement script you are using. If you are using the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) movement script, you can enable the Local Avoidance checkbox on the movement script. If you are using the [AIPath](https://arongranberg.com/astar/docs/aipath.html) , [RichAI](https://arongranberg.com/astar/docs/richai.html) , or a custom movement script, you should add the [RVOController](https://arongranberg.com/astar/docs/rvocontroller.html) component to your agents. Note The [AILerp](https://arongranberg.com/astar/docs/ailerp.html) movement script is designed to interpolate along the path and follow it exactly, therefore it makes no sense for it to deviate from the path and thus it does not support local avoidance. See If you want to use local avoidance with your own custom movement script or just want to learn more in-depth about how it works, take a look at this page: [Custom Local Avoidance Movement Script](https://arongranberg.com/astar/docs/localavoidanceintegration.html) . These two ways expose essentially identical settings. The [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) uses the Entity Component System (ECS) internally, and so it cannot use the [RVOController](https://arongranberg.com/astar/docs/rvocontroller.html) as a separate component. Internally, both are simulated in exactly the same way. ![](https://arongranberg.com/astar/docs/images/generated/inspectors/RVOController@2x.png) Radius Radius of the agent in world units. Note If a movement script (AIPath/RichAI/AILerp, anything implementing the [IAstarAI](https://arongranberg.com/astar/docs/iastarai.html) interface) is attached to the same GameObject, this value will be driven by that script. See This setting corresponds to the member [RVOController.radius](https://arongranberg.com/astar/docs/rvocontroller.html#radius) Height Height of the agent in world units. Note If a movement script (AIPath/RichAI/AILerp, anything implementing the [IAstarAI](https://arongranberg.com/astar/docs/iastarai.html) interface) is attached to the same GameObject, this value will be driven by that script. See This setting corresponds to the member [RVOController.height](https://arongranberg.com/astar/docs/rvocontroller.html#height) Center Center of the agent relative to the pivot point of this game object. Note If a movement script (AIPath/RichAI/AILerp, anything implementing the [IAstarAI](https://arongranberg.com/astar/docs/iastarai.html) interface) is attached to the same GameObject, this value will be driven by that script. See This setting corresponds to the member [RVOController.center](https://arongranberg.com/astar/docs/rvocontroller.html#center) Agent Time Horizon How far into the future to look for collisions with other agents (in seconds) See This setting corresponds to the member [RVOController.agentTimeHorizon](https://arongranberg.com/astar/docs/rvocontroller.html#agentTimeHorizon) Obstacle Time Horizon How far into the future to look for collisions with obstacles (in seconds) See This setting corresponds to the member [RVOController.obstacleTimeHorizon](https://arongranberg.com/astar/docs/rvocontroller.html#obstacleTimeHorizon) Max Neighbours Max number of other agents to take into account. A smaller value can reduce CPU load, a higher value can lead to better local avoidance quality. See This setting corresponds to the member [RVOController.maxNeighbours](https://arongranberg.com/astar/docs/rvocontroller.html#maxNeighbours) Layer Specifies the avoidance layer for this agent. The [collidesWith](https://arongranberg.com/astar/docs/rvocontroller.html#collidesWith) mask on other agents will determine if they will avoid this agent. See This setting corresponds to the member [RVOController.layer](https://arongranberg.com/astar/docs/rvocontroller.html#layer) Collides with Layer mask specifying which layers this agent will avoid. You can set it as CollidesWith = RVOLayer.DefaultAgent | RVOLayer.Layer3 | RVOLayer.Layer6 ... This can be very useful in games which have multiple teams of some sort. For example you usually want the agents in one team to avoid each other, but you do not want them to avoid the enemies. This field only affects which other agents that this agent will avoid, it does not affect how other agents react to this agent. See [Bitmask Tutorial](https://arongranberg.com/astar/docs/bitmasks.html) [http://en.wikipedia.org/wiki/Mask\_(computing)](http://en.wikipedia.org/wiki/Mask_(computing)) See This setting corresponds to the member [RVOController.collidesWith](https://arongranberg.com/astar/docs/rvocontroller.html#collidesWith) Priority How strongly other agents will avoid this agent. Usually a value between 0 and 1. Agents with similar priorities will avoid each other with an equal strength. If an agent sees another agent with a higher priority than itself it will avoid that agent more strongly. In the extreme case (e.g this agent has a priority of 0 and the other agent has a priority of 1) it will treat the other agent as being a moving obstacle. Similarly if an agent sees another agent with a lower priority than itself it will avoid that agent less. In general the avoidance strength for this agent is: `if this.priority > 0 or other.priority > 0: avoidanceStrength = other.priority / (this.priority + other.priority); else: avoidanceStrength = 0.5 ` See This setting corresponds to the member [RVOController.priority](https://arongranberg.com/astar/docs/rvocontroller.html#priority) Lock When Not Moving Automatically set [locked](https://arongranberg.com/astar/docs/rvocontroller.html#locked) to true when desired velocity is approximately zero. This prevents other units from pushing them away when they are supposed to e.g block a choke point. When this is true every call to [SetTarget](https://arongranberg.com/astar/docs/rvocontroller/settarget.html#SetTarget) or [Move](https://arongranberg.com/astar/docs/rvocontroller/move.html#Move) will set the [locked](https://arongranberg.com/astar/docs/rvocontroller.html#locked) field to true if the desired velocity was non-zero or false if it was zero. See This setting corresponds to the member [RVOController.lockWhenNotMoving](https://arongranberg.com/astar/docs/rvocontroller.html#lockWhenNotMoving) Locked A locked unit cannot move. Other units will still avoid it but avoidance quality is not the best. See This setting corresponds to the member [RVOController.locked](https://arongranberg.com/astar/docs/rvocontroller.html#locked) Debug Enables drawing debug information in the scene view. See This setting corresponds to the member [RVOController.debug](https://arongranberg.com/astar/docs/rvocontroller.html#debug) Integration with physics ------------------------ Often you want to have colliders on your agents, maybe to be able to hit them with bullets or something. However, if you just add colliders (plus a rigidbody) to your agents, you may see that the local avoidance quality goes down drastically in crowded scenarios. This is because when it is very crowded, agents may overlap a tiny bit. The physics system will prevent that, but it will not do it in as nice a way as the local avoidance system, and this may lead to worse movement. If you have colliders on your agents, I recommend disabling collisions between the agents themselves to solve this. Put the agents in a separate layer and in the Unity physics settings, you can disable collisions of that layer with itself. Note that Unity has separate settings for 2D and 3D physics, so make sure you change the right settings. ![](https://arongranberg.com/astar/docs/images/rvo/disable_collisions.png) Keeping the agents on the navmesh --------------------------------- When using local avoidance, it is not hard to find cases where agents will manage to push other agents outside the graph. This is usually not desired; fortunately, there are ways to mitigate this. You can enable the [RVOSimulator.useNavmeshAsObstacle](https://arongranberg.com/astar/docs/rvosimulator.html#useNavmeshAsObstacle) option to make the local avoidance system treat the navmesh as an obstacle. This has a performance overhead, but agents will be much less likely to be pushed outside the graph. Agents can also constrain themselves to the graph, without using local avoidance. If you are using the [RichAI](https://arongranberg.com/astar/docs/richai.html) or [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) movement scripts, this automatically happens because the way they handle movement requires it. If you are using the [AIPath](https://arongranberg.com/astar/docs/aipath.html) script, you can enable this using the [constrainInsideGraph](https://arongranberg.com/astar/docs/aipath.html#constrainInsideGraph) option. However, if the local avoidance agents are not aware of the navmesh (using the [RVOSimulator.useNavmeshAsObstacle](https://arongranberg.com/astar/docs/rvosimulator.html#useNavmeshAsObstacle) option), they may still **try** to move outside the graph, which can lead to some jittery behavior near the edges of the graph, especially in crowded scenarios. Below you can see an image where several agents using local avoidance were ordered to go to the same point in a corner. When not constraining the agents to the graph, they are easily pushed inside obstacles. ![](https://arongranberg.com/astar/docs/images/constrained_inside.png) Performance ----------- ![](https://arongranberg.com/astar/docs/images/rvo/rvo_stress_30000_white.png) So how fast is local avoidance then, you might wonder. It is very high performance. Especially if you take into account the fact that a local avoidance simulation does not need to run at a very high fps, that's just a waste of CPU cycles because the quality won't improve much. I have been able to simulate 30,000 agents at a good fps on my, admittedly quite beefy, computer (i9 processor, 16 cores). The local avoidance simulation ran at a fixed 60 fps and the game ran at a few hundred fps, with a lowest fps of around 60. The visualization for this simulation was done simply by creating a mesh which held one quad for each agent. The reason for this is that at such high numbers, creating a GameObject for every agent is really slow; just creating that many game objects took something like 10 seconds when I tested. The agents were set up in a circle, and each one tried to move to a point on the opposite side of the circle. So it was basically as crowded as it can get. However, do not count on having this high number of agents in your game. The above test was very lightweight, and in a game there is usually lots of overhead from many other things. The image above shows the aforementioned stress test. See [Lightweight Local Avoidance Simulation](https://arongranberg.com/astar/docs/example_local_avoidance_lightweight.html) Local Avoidance Priorities -------------------------- All agents are equal, but some may be more equal than others. This is where priorities come in. If an agent has a higher priority, other agents will try to avoid it more, and it will also try to avoid other agents less. In general, if one agent has a priority A, and another has priority B, then A will take this fraction of the responsibility of avoiding any collision: `B / (A + B) ` So, for example, if A has priority 1 and B has priority 2, then A will take 2/3 of the responsibility and B will take 1/3 of the responsibility. Local Avoidance Layers ---------------------- You can also make some agents completely ignore other characters by changing their agent layer, and which layers they will avoid. Every [RVOController](https://arongranberg.com/astar/docs/rvocontroller.html) has one field for its own layer, and one for the layers it will consider when avoiding other agents. Note that these layers are not the same thing as Unity layers. These are used purely for local avoidance. Layer Specifies the avoidance layer for this agent. The [collidesWith](https://arongranberg.com/astar/docs/rvocontroller.html#collidesWith) mask on other agents will determine if they will avoid this agent. See This setting corresponds to the member [RVOController.layer](https://arongranberg.com/astar/docs/rvocontroller.html#layer) Collides With Layer mask specifying which layers this agent will avoid. You can set it as CollidesWith = RVOLayer.DefaultAgent | RVOLayer.Layer3 | RVOLayer.Layer6 ... This can be very useful in games which have multiple teams of some sort. For example you usually want the agents in one team to avoid each other, but you do not want them to avoid the enemies. This field only affects which other agents that this agent will avoid, it does not affect how other agents react to this agent. See [Bitmask Tutorial](https://arongranberg.com/astar/docs/bitmasks.html) [http://en.wikipedia.org/wiki/Mask\_(computing)](http://en.wikipedia.org/wiki/Mask_(computing)) See This setting corresponds to the member [RVOController.collidesWith](https://arongranberg.com/astar/docs/rvocontroller.html#collidesWith) This can be very useful if you are making a game with two teams. In those cases, you often don't want agents of different teams to avoid each other. You can then put all agents of team A in one layer, and all agents of team B in another layer, and then make sure that agents only avoid agents in their own team's layer. Player Characters ----------------- You may want your player character to be unaffected by local avoidance altogether, but you may want other agents to avoid the player. You can do this by manually setting the velocity of an [RVOController](https://arongranberg.com/astar/docs/rvocontroller.html) component. `void Update () { var x = Input.GetAxis("Horizontal"); var y = Input.GetAxis("Vertical"); var v = new Vector3(x, 0, y) * speed; // Override the RVOController's velocity. This will disable local avoidance calculations for one simulation step. rvo.velocity = v; transform.position += v * Time.deltaTime; } `This will make the local avoidance system skip calculations for that agent completely, and instead assume it will move with the velocity that you set. This can sometimes also be useful for moving obstacles, assuming that they are small enough that pathfinding is not necessary, and that it's fine that they are circular. There's an included sample script called [ManualRVOAgent.cs](https://arongranberg.com/astar/docs/manualrvoagentcs.html) which shows how you can integrate your existing character movement script with local avoidance in this way. --- # AABBComparer - A* Pathfinding Project Struct AABBComparer Extends IComparer ========================================== Private Public Methods -------------- [Compare](https://arongranberg.com/astar/docs/aabbcomparer/compare.html#Compare) (a, b) Public Variables ---------------- dim Public ##### int dim nodes Public ##### [Node](https://arongranberg.com/astar/docs/node.html) \[\] nodes --- # Key - A* Pathfinding Project Struct Key ========== Public A key to a leaf node in the tree. Public Variables ---------------- isValid Public ##### bool isValid node Public ##### int node Private/Protected Members ------------------------- [Key](https://arongranberg.com/astar/docs/key/key.html#Key) (node) value Internal Readonly ##### int value --- # Modifiers - A* Pathfinding Project Group Modifiers =============== Collection of the most used modifiers. See [Using Modifiers](https://arongranberg.com/astar/docs/modifiers2.html) [AdvancedSmooth](https://arongranberg.com/astar/docs/advancedsmooth.html) Smoothing by dividing path into turns and straight segments. [AlternativePath](https://arongranberg.com/astar/docs/alternativepath.html) Applies penalty to the paths it processes telling other units to avoid choosing the same path. [FunnelModifier](https://arongranberg.com/astar/docs/funnelmodifier.html) Simplifies paths on navmesh graphs using the funnel algorithm. [RadiusModifier](https://arongranberg.com/astar/docs/radiusmodifier.html) Radius path modifier for offsetting paths. [RaycastModifier](https://arongranberg.com/astar/docs/raycastmodifier.html) Simplifies a path using raycasting. [SimpleSmoothModifier](https://arongranberg.com/astar/docs/simplesmoothmodifier.html) Modifier which smooths the path. [StartEndModifier](https://arongranberg.com/astar/docs/startendmodifier.html) Adjusts start and end points of a path. --- # Pathfinding - A* Pathfinding Project Namespace Pathfinding ===================== Namespaces ---------- [Collections](https://arongranberg.com/astar/docs/collections.html) [ECS](https://arongranberg.com/astar/docs/ecs2.html) Examples [Graphs](https://arongranberg.com/astar/docs/graphs2.html) [Jobs](https://arongranberg.com/astar/docs/jobs3.html) [Legacy](https://arongranberg.com/astar/docs/legacy.html) [PID](https://arongranberg.com/astar/docs/pid.html) [Pooling](https://arongranberg.com/astar/docs/pooling2.html) [RVO](https://arongranberg.com/astar/docs/rvo2.html) Local avoidance related classes. [Serialization](https://arongranberg.com/astar/docs/serialization.html) [Sync](https://arongranberg.com/astar/docs/sync.html) Synchronization primitives. [Util](https://arongranberg.com/astar/docs/util2.html) [WindowsStore](https://arongranberg.com/astar/docs/windowsstore.html) Classes ------- [ABPath](https://arongranberg.com/astar/docs/abpath.html) Basic path, finds the shortest path from A to B. [ABPathEndingCondition](https://arongranberg.com/astar/docs/abpathendingcondition.html) Ending condition which emulates the default one for the [ABPath](https://arongranberg.com/astar/docs/abpath.html) . [AdvancedSmooth](https://arongranberg.com/astar/docs/advancedsmooth.html) Smoothing by dividing path into turns and straight segments. [AIBase](https://arongranberg.com/astar/docs/aibase.html) Base class for [AIPath](https://arongranberg.com/astar/docs/aipath.html) and [RichAI](https://arongranberg.com/astar/docs/richai.html) . [AIDestinationSetter](https://arongranberg.com/astar/docs/aidestinationsetter.html) Sets the destination of an AI to the position of a specified object. [AIDestinationSetterEditor](https://arongranberg.com/astar/docs/aidestinationsettereditor.html) [AILerp](https://arongranberg.com/astar/docs/ailerp.html) Linearly interpolating movement script. [AILerpEditor](https://arongranberg.com/astar/docs/ailerpeditor.html) [AIPath](https://arongranberg.com/astar/docs/aipath.html) AI for following paths. [AIPathAlignedToSurface](https://arongranberg.com/astar/docs/aipathalignedtosurface.html) Movement script for curved worlds. [AlternativePath](https://arongranberg.com/astar/docs/alternativepath.html) Applies penalty to the paths it processes telling other units to avoid choosing the same path. [AnimationLink](https://arongranberg.com/astar/docs/animationlink.html) [AnimationLinkEditor](https://arongranberg.com/astar/docs/animationlinkeditor.html) [AstarColor](https://arongranberg.com/astar/docs/astarcolor.html) Stores editor colors. [AstarData](https://arongranberg.com/astar/docs/astardata.html) Stores the navigation graphs for the A\* [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) System. [AstarDebugger](https://arongranberg.com/astar/docs/astardebugger.html) Debugger for the A\* [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) Project. [AstarMath](https://arongranberg.com/astar/docs/astarmath.html) Utility functions for working with numbers and strings. [AstarPathEditor](https://arongranberg.com/astar/docs/astarpatheditor.html) [AstarSplines](https://arongranberg.com/astar/docs/astarsplines.html) Contains various spline functions. [AstarUpdateChecker](https://arongranberg.com/astar/docs/astarupdatechecker.html) Handles update checking for the A\* [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) Project. [AstarUpdateWindow](https://arongranberg.com/astar/docs/astarupdatewindow.html) [AstarWorkItem](https://arongranberg.com/astar/docs/astarworkitem.html) An item of work that can be executed when graphs are safe to update. [AutoRepathPolicy](https://arongranberg.com/astar/docs/autorepathpolicy.html) Policy for how often to recalculate an agent's path. [BaseAIEditor](https://arongranberg.com/astar/docs/baseaieditor.html) [BinaryHeap](https://arongranberg.com/astar/docs/binaryheap.html) Binary heap implementation. [BlockManager](https://arongranberg.com/astar/docs/blockmanager.html) Manager for blocker scripts such as [SingleNodeBlocker](https://arongranberg.com/astar/docs/singlenodeblocker.html) . [Connection](https://arongranberg.com/astar/docs/connection.html) Represents a connection to another node. [ConstantPath](https://arongranberg.com/astar/docs/constantpath.html) Finds all nodes within a specified distance from the start. [CustomGraphEditorAttribute](https://arongranberg.com/astar/docs/customgrapheditorattribute.html) Added to editors of custom graph types. [DefaultITraversalProvider](https://arongranberg.com/astar/docs/defaultitraversalprovider.html) Convenience class to access the default implementation of the [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) . [DistanceMetric](https://arongranberg.com/astar/docs/distancemetric.html) Determines how to measure distances to the navmesh. [DynamicGridObstacle](https://arongranberg.com/astar/docs/dynamicgridobstacle.html) Updates graphs around the object as it moves. [DynamicObstacle](https://arongranberg.com/astar/docs/dynamicobstacle.html) Updates graphs around the object as it moves. [EditorBase](https://arongranberg.com/astar/docs/editorbase.html) Helper for creating editors. [EditorGUILayoutx](https://arongranberg.com/astar/docs/editorguilayoutx.html) Handles fading effects and also some custom GUI functions such as LayerMaskField. [EditorResourceHelper](https://arongranberg.com/astar/docs/editorresourcehelper.html) Internal utility class for looking up editor resources. [EndingConditionDistance](https://arongranberg.com/astar/docs/endingconditiondistance.html) Target is found when the path is longer than a specified value. [EndingConditionProximity](https://arongranberg.com/astar/docs/endingconditionproximity.html) Ending condition which stops a fixed distance from the target point. [EnumFlagAttribute](https://arongranberg.com/astar/docs/enumflagattribute.html) [EnumFlagDrawer](https://arongranberg.com/astar/docs/enumflagdrawer.html) [FadeArea](https://arongranberg.com/astar/docs/fadearea.html) Editor helper for hiding and showing a group of GUI elements. [FakeTransform](https://arongranberg.com/astar/docs/faketransform.html) [FleePath](https://arongranberg.com/astar/docs/fleepath.html) Returns a path heading away from a specified point to avoid. [FloodPath](https://arongranberg.com/astar/docs/floodpath.html) Calculates paths from everywhere to a single point. [FloodPathTracer](https://arongranberg.com/astar/docs/floodpathtracer.html) Traces a path created with the [Pathfinding.FloodPath](https://arongranberg.com/astar/docs/floodpath.html) . [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) Movement script that uses ECS. [FollowerEntityEditor](https://arongranberg.com/astar/docs/followerentityeditor.html) [Funnel](https://arongranberg.com/astar/docs/funnel.html) Implements the funnel algorithm as well as various related methods. [FunnelModifier](https://arongranberg.com/astar/docs/funnelmodifier.html) Simplifies paths on navmesh graphs using the funnel algorithm. [FunnelModifierEditor](https://arongranberg.com/astar/docs/funnelmodifiereditor.html) [GlobalNodeStorage](https://arongranberg.com/astar/docs/globalnodestorage.html) [GraphEditor](https://arongranberg.com/astar/docs/grapheditor.html) [GraphEditorBase](https://arongranberg.com/astar/docs/grapheditorbase.html) Base class for all graph editors. [GraphHitInfo](https://arongranberg.com/astar/docs/graphhitinfo.html) Info about what a raycast, linecast or nearest border query hit. [GraphMask](https://arongranberg.com/astar/docs/graphmask.html) A combination of graphs. [GraphMaskDrawer](https://arongranberg.com/astar/docs/graphmaskdrawer.html) [GraphModifier](https://arongranberg.com/astar/docs/graphmodifier.html) [GraphModifier](https://arongranberg.com/astar/docs/graphmodifier.html) is used for modifying graphs or processing graph data based on events. [GraphNode](https://arongranberg.com/astar/docs/graphnode.html) Base class for all nodes. [GraphUpdateObject](https://arongranberg.com/astar/docs/graphupdateobject.html) Represents a collection of settings used to update nodes in a specific region of a graph. [GraphUpdateProcessor](https://arongranberg.com/astar/docs/graphupdateprocessor.html) [GraphUpdateScene](https://arongranberg.com/astar/docs/graphupdatescene.html) Helper class for easily updating graphs. [GraphUpdateSceneEditor](https://arongranberg.com/astar/docs/graphupdatesceneeditor.html) Editor for [GraphUpdateScene](https://arongranberg.com/astar/docs/graphupdatescene.html) . [GraphUpdateShape](https://arongranberg.com/astar/docs/graphupdateshape.html) Defines a shape for a [Pathfinding.GraphUpdateObject](https://arongranberg.com/astar/docs/graphupdateobject.html) . [GraphUpdateUtilities](https://arongranberg.com/astar/docs/graphupdateutilities.html) Contains useful functions for updating graphs. [GraphUtilities](https://arongranberg.com/astar/docs/graphutilities.html) Contains utility methods for getting useful information out of graph. [GridGraph](https://arongranberg.com/astar/docs/gridgraph.html) Generates a grid of nodes. [GridGraphEditor](https://arongranberg.com/astar/docs/gridgrapheditor.html) [GridHitInfo](https://arongranberg.com/astar/docs/gridhitinfo.html) Information about a linecast hit on a grid graph. [GridNode](https://arongranberg.com/astar/docs/gridnode.html) Node used for the [GridGraph](https://arongranberg.com/astar/docs/gridgraph.html) . [GridNodeBase](https://arongranberg.com/astar/docs/gridnodebase.html) Base class for [GridNode](https://arongranberg.com/astar/docs/gridnode.html) and [LevelGridNode](https://arongranberg.com/astar/docs/levelgridnode.html) . [GridStringPulling](https://arongranberg.com/astar/docs/gridstringpulling.html) Simplifies a path on a grid graph using a string pulling algorithm. [GUIUtilityx](https://arongranberg.com/astar/docs/guiutilityx.html) Simple GUI utility functions. [HeuristicObjective](https://arongranberg.com/astar/docs/heuristicobjective.html) Calculates an estimated cost from the specified point to the target. [HierarchicalGraph](https://arongranberg.com/astar/docs/hierarchicalgraph.html) Holds a hierarchical graph to speed up certain pathfinding queries. [IAstarAI](https://arongranberg.com/astar/docs/iastarai.html) Common interface for all movement scripts in the A\* [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) Project. [IGraphInternals](https://arongranberg.com/astar/docs/igraphinternals.html) Exposes internal methods for graphs. [IGraphUpdateContext](https://arongranberg.com/astar/docs/igraphupdatecontext.html) Helper functions for graph updates. [IGraphUpdatePromise](https://arongranberg.com/astar/docs/igraphupdatepromise.html) Promise representing a graph update. [INavmeshHolder](https://arongranberg.com/astar/docs/inavmeshholder.html) Interface for something that holds a triangle based navmesh. [Int3](https://arongranberg.com/astar/docs/int3.html) Holds a coordinate in (integer) millimeters. [IntBounds](https://arongranberg.com/astar/docs/intbounds.html) Integer bounding box. [IntRect](https://arongranberg.com/astar/docs/intrect.html) Integer Rectangle. [IOffMeshLinkHandler](https://arongranberg.com/astar/docs/ioffmeshlinkhandler.html) Interface for handling off-mesh links. [IOffMeshLinkStateMachine](https://arongranberg.com/astar/docs/ioffmeshlinkstatemachine.html) [IPathInternals](https://arongranberg.com/astar/docs/ipathinternals.html) Used for hiding internal methods of the [Path](https://arongranberg.com/astar/docs/path.html) class. [IPathModifier](https://arongranberg.com/astar/docs/ipathmodifier.html) Base for all path modifiers. [IRaycastableGraph](https://arongranberg.com/astar/docs/iraycastablegraph.html) Graph which supports the Linecast method. [ITransformedGraph](https://arongranberg.com/astar/docs/itransformedgraph.html) Graph which has a well defined transformation from graph space to world space. [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) Provides additional traversal information to a path request. [IUpdatableGraph](https://arongranberg.com/astar/docs/iupdatablegraph.html) [Graphs](https://arongranberg.com/astar/docs/graphs2.html) which can be updated during runtime. [IVersionedMonoBehaviourInternal](https://arongranberg.com/astar/docs/iversionedmonobehaviourinternal.html) Exposes internal methods from [Pathfinding.VersionedMonoBehaviour](https://arongranberg.com/astar/docs/versionedmonobehaviour.html) . [IWorkItemContext](https://arongranberg.com/astar/docs/iworkitemcontext.html) Interface to expose a subset of the [WorkItemProcessor](https://arongranberg.com/astar/docs/workitemprocessor.html) functionality. [LayerGridGraph](https://arongranberg.com/astar/docs/layergridgraph.html) Grid Graph, supports layered worlds. [LayerGridGraphEditor](https://arongranberg.com/astar/docs/layergridgrapheditor.html) [LevelGridNode](https://arongranberg.com/astar/docs/levelgridnode.html) Describes a single node for the [LayerGridGraph](https://arongranberg.com/astar/docs/layergridgraph.html) . [LinkGraph](https://arongranberg.com/astar/docs/linkgraph.html) Graph for off-mesh links. [LinkNode](https://arongranberg.com/astar/docs/linknode.html) [LocalSpaceGraph](https://arongranberg.com/astar/docs/localspacegraph.html) Helper for [Pathfinding.Examples.LocalSpaceRichAI](https://arongranberg.com/astar/docs/localspacerichai.html) . [MeshNode](https://arongranberg.com/astar/docs/meshnode.html) [MonoModifier](https://arongranberg.com/astar/docs/monomodifier.html) Base class for path modifiers which can be attached to GameObjects. [MoveInCircle](https://arongranberg.com/astar/docs/moveincircle.html) Moves an agent in a circle around a point. [MultiTargetPath](https://arongranberg.com/astar/docs/multitargetpath.html) A path which searches from one point to a number of different targets in one search or from a number of different start points to a single target. [NavGraph](https://arongranberg.com/astar/docs/navgraph.html) Base class for all graphs. [NavmeshAdd](https://arongranberg.com/astar/docs/navmeshadd.html) Adds new geometry to a recast graph. [NavmeshAddEditor](https://arongranberg.com/astar/docs/navmeshaddeditor.html) [NavmeshBase](https://arongranberg.com/astar/docs/navmeshbase.html) Base class for [RecastGraph](https://arongranberg.com/astar/docs/recastgraph.html) and [NavMeshGraph](https://arongranberg.com/astar/docs/navmeshgraph.html) . [NavmeshClamp](https://arongranberg.com/astar/docs/navmeshclamp.html) Attach to any GameObject and the object will be clamped to the navmesh. [NavmeshClipper](https://arongranberg.com/astar/docs/navmeshclipper.html) Base class for the [NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) and [NavmeshAdd](https://arongranberg.com/astar/docs/navmeshadd.html) components. [NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) Navmesh cutting is used for fast recast/navmesh graph updates. [NavmeshCutEditor](https://arongranberg.com/astar/docs/navmeshcuteditor.html) [NavmeshCutJobs](https://arongranberg.com/astar/docs/navmeshcutjobs.html) [NavmeshEdges](https://arongranberg.com/astar/docs/navmeshedges.html) [NavMeshGraph](https://arongranberg.com/astar/docs/navmeshgraph.html) Generates graphs based on navmeshes. [NavMeshGraphEditor](https://arongranberg.com/astar/docs/navmeshgrapheditor.html) [NavmeshPrefab](https://arongranberg.com/astar/docs/navmeshprefab.html) Stores a set of navmesh tiles which can be placed on a recast graph. [NavmeshPrefabEditor](https://arongranberg.com/astar/docs/navmeshprefabeditor.html) Editor for the [NavmeshPrefab](https://arongranberg.com/astar/docs/navmeshprefab.html) component. [NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) Constraint for the [AstarPath.GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html) method. [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) Nearest node constraint. [NNConstraintGraphUpdateObjectProxy](https://arongranberg.com/astar/docs/nnconstraintgraphupdateobjectproxy.html) Helper proxy for handling compatibility with the old [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) API. [NNConstraintPathProxy](https://arongranberg.com/astar/docs/nnconstraintpathproxy.html) Helper proxy for handling compatibility with the old [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) API. [NNInfo](https://arongranberg.com/astar/docs/nninfo.html) Result of a nearest node query. [NodeLink](https://arongranberg.com/astar/docs/nodelink.html) Connects two nodes with a direct connection. [NodeLink2](https://arongranberg.com/astar/docs/nodelink2.html) Connects two nodes using an off-mesh link. [NodeLink2Editor](https://arongranberg.com/astar/docs/nodelink2editor.html) [NodeLink3](https://arongranberg.com/astar/docs/nodelink3.html) Connects two TriangleMeshNodes (recast/navmesh graphs) as if they had shared an edge. [NodeLink3Node](https://arongranberg.com/astar/docs/nodelink3node.html) [OffMeshLinks](https://arongranberg.com/astar/docs/offmeshlinks.html) Manager for off-mesh links. [OptimizationHandler](https://arongranberg.com/astar/docs/optimizationhandler.html) Helper for enabling or disabling compiler directives. [Path](https://arongranberg.com/astar/docs/path.html) Base class for all path types. [PathEndingCondition](https://arongranberg.com/astar/docs/pathendingcondition.html) Customized ending condition for a path. [PathfindingEditorSettings](https://arongranberg.com/astar/docs/pathfindingeditorsettings.html) [PathfindingTag](https://arongranberg.com/astar/docs/pathfindingtag.html) Represents a single pathfinding tag. [PathfindingTagDrawer](https://arongranberg.com/astar/docs/pathfindingtagdrawer.html) [PathHandler](https://arongranberg.com/astar/docs/pathhandler.html) Handles thread specific path data. [PathModifier](https://arongranberg.com/astar/docs/pathmodifier.html) Base class for path modifiers which are not attached to GameObjects. [PathNNConstraint](https://arongranberg.com/astar/docs/pathnnconstraint.html) A special [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) which can use different logic for the start node and end node in a path. [PathNode](https://arongranberg.com/astar/docs/pathnode.html) Stores temporary node data for a single pathfinding request. [PathProcessor](https://arongranberg.com/astar/docs/pathprocessor.html) [PathRequestSettings](https://arongranberg.com/astar/docs/pathrequestsettings.html) Settings for how an agent searches for paths. [PathReturnQueue](https://arongranberg.com/astar/docs/pathreturnqueue.html) [PathTracer](https://arongranberg.com/astar/docs/pathtracer.html) Helper for following a path. [PathUtilities](https://arongranberg.com/astar/docs/pathutilities.html) Contains useful functions for working with paths and nodes. [Patrol](https://arongranberg.com/astar/docs/patrol.html) Simple patrol behavior. [PointGraph](https://arongranberg.com/astar/docs/pointgraph.html) Graph consisting of a set of points. [PointGraphEditor](https://arongranberg.com/astar/docs/pointgrapheditor.html) [PointKDTree](https://arongranberg.com/astar/docs/pointkdtree.html) Represents a collection of GraphNodes. [PointNode](https://arongranberg.com/astar/docs/pointnode.html) Node used for the [PointGraph](https://arongranberg.com/astar/docs/pointgraph.html) . [Polygon](https://arongranberg.com/astar/docs/polygon.html) Utility functions for working with polygons, lines, and other vector math. [ProceduralGraphMover](https://arongranberg.com/astar/docs/proceduralgraphmover.html) Moves a grid or recast graph to follow a target. [ProceduralGridMover](https://arongranberg.com/astar/docs/proceduralgridmover.html) This class has been renamed to [ProceduralGraphMover](https://arongranberg.com/astar/docs/proceduralgraphmover.html) . [ProceduralGridMoverEditor](https://arongranberg.com/astar/docs/proceduralgridmovereditor.html) [Progress](https://arongranberg.com/astar/docs/progress.html) [Progress](https://arongranberg.com/astar/docs/progress.html) info for e.g a progressbar. [RadiusModifier](https://arongranberg.com/astar/docs/radiusmodifier.html) Radius path modifier for offsetting paths. [RandomPath](https://arongranberg.com/astar/docs/randompath.html) Finds a path in a random direction from the start node. [RaycastModifier](https://arongranberg.com/astar/docs/raycastmodifier.html) Simplifies a path using raycasting. [RaycastModifierEditor](https://arongranberg.com/astar/docs/raycastmodifiereditor.html) [RecastGraph](https://arongranberg.com/astar/docs/recastgraph.html) Automatically generates navmesh graphs based on world geometry. [RecastGraphEditor](https://arongranberg.com/astar/docs/recastgrapheditor.html) Editor for the [RecastGraph](https://arongranberg.com/astar/docs/recastgraph.html) . [RecastMeshObj](https://arongranberg.com/astar/docs/recastmeshobj.html) Explicit mesh object for recast graphs. [RecastNavmeshModifier](https://arongranberg.com/astar/docs/recastnavmeshmodifier.html) Overrides navmesh generation settings for a single mesh or collider. [RecastNavmeshModifierEditor](https://arongranberg.com/astar/docs/recastnavmeshmodifiereditor.html) [RecastTileUpdate](https://arongranberg.com/astar/docs/recasttileupdate.html) Updates the recast tile(s) it is in at start, needs [RecastTileUpdateHandler](https://arongranberg.com/astar/docs/recasttileupdatehandler.html) . [RecastTileUpdateHandler](https://arongranberg.com/astar/docs/recasttileupdatehandler.html) Helper for easier fast updates to recast graphs. [RichAI](https://arongranberg.com/astar/docs/richai.html) Advanced AI for navmesh based graphs. [RichFunnel](https://arongranberg.com/astar/docs/richfunnel.html) [RichPath](https://arongranberg.com/astar/docs/richpath.html) [RichPathPart](https://arongranberg.com/astar/docs/richpathpart.html) [RichSpecial](https://arongranberg.com/astar/docs/richspecial.html) [RuleAnglePenaltyEditor](https://arongranberg.com/astar/docs/ruleanglepenaltyeditor.html) Editor for the [RuleAnglePenalty](https://arongranberg.com/astar/docs/ruleanglepenalty.html) rule. [RuleElevationPenaltyEditor](https://arongranberg.com/astar/docs/ruleelevationpenaltyeditor.html) Editor for the [RuleElevationPenalty](https://arongranberg.com/astar/docs/ruleelevationpenalty.html) rule. [RulePerLayerModificationsEditor](https://arongranberg.com/astar/docs/ruleperlayermodificationseditor.html) Editor for the [RulePerLayerModifications](https://arongranberg.com/astar/docs/ruleperlayermodifications.html) rule. [RuleTextureEditor](https://arongranberg.com/astar/docs/ruletextureeditor.html) Editor for the [RuleTexture](https://arongranberg.com/astar/docs/ruletexture.html) rule. [RVONavmeshEditor](https://arongranberg.com/astar/docs/rvonavmesheditor.html) [RVOSimulatorEditor](https://arongranberg.com/astar/docs/rvosimulatoreditor.html) [RVOSquareObstacleEditor](https://arongranberg.com/astar/docs/rvosquareobstacleeditor.html) [Seeker](https://arongranberg.com/astar/docs/seeker.html) Handles path calls for a single unit. [SeekerEditor](https://arongranberg.com/astar/docs/seekereditor.html) [SimpleSmoothModifier](https://arongranberg.com/astar/docs/simplesmoothmodifier.html) Modifier which smooths the path. [SingleNodeBlocker](https://arongranberg.com/astar/docs/singlenodeblocker.html) Blocks single nodes in a graph. [SmoothModifierEditor](https://arongranberg.com/astar/docs/smoothmodifiereditor.html) [StartEndModifier](https://arongranberg.com/astar/docs/startendmodifier.html) Adjusts start and end points of a path. [TargetMover](https://arongranberg.com/astar/docs/targetmover.html) Moves the target in example scenes. [TemporaryNode](https://arongranberg.com/astar/docs/temporarynode.html) [ThreadCountExtensions](https://arongranberg.com/astar/docs/threadcountextensions.html) [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint.html) Specifies which nodes are traversable and which are not. [TraversalCosts](https://arongranberg.com/astar/docs/traversalcosts.html) Defines the cost of traversing specific nodes when pathfinding. [TriangleMeshNode](https://arongranberg.com/astar/docs/trianglemeshnode.html) Node represented by a triangle. [UniqueComponentAttribute](https://arongranberg.com/astar/docs/uniquecomponentattribute.html) [UnityReferenceHelper](https://arongranberg.com/astar/docs/unityreferencehelper.html) Helper class to keep track of references to GameObjects. [Vector2IntExtensions](https://arongranberg.com/astar/docs/vector2intextensions.html) [VectorMath](https://arongranberg.com/astar/docs/vectormath.html) Various vector math utility functions. [VersionedMonoBehaviour](https://arongranberg.com/astar/docs/versionedmonobehaviour.html) Base class for all components in the package. [WelcomeScreen](https://arongranberg.com/astar/docs/welcomescreen.html) [WorkItemProcessor](https://arongranberg.com/astar/docs/workitemprocessor.html) [XPath](https://arongranberg.com/astar/docs/xpath.html) Extended [Path](https://arongranberg.com/astar/docs/path.html) . Public Methods -------------- OnGraphDelegate (graph) ##### delegate void OnGraphDelegate ( | | | | | --- | --- | --- | | [NavGraph](https://arongranberg.com/astar/docs/navgraph.html) | graph | | ) OnPathDelegate (p) Delegate with on [Path](https://arongranberg.com/astar/docs/path.html) object as parameter. ##### delegate void OnPathDelegate ( | | | | | --- | --- | --- | | [Path](https://arongranberg.com/astar/docs/path.html) | p | | ) Delegate with on [Path](https://arongranberg.com/astar/docs/path.html) object as parameter. This is used for callbacks for when a path has been calculated. OnScanDelegate (script) ##### delegate void OnScanDelegate ( | | | | | --- | --- | --- | | [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) | script | | ) Public Enums ------------ CloseToDestinationMode What to do when the character is close to the destination. ##### CloseToDestinationMode | | | | --- | --- | | Stop | The character will stop as quickly as possible when within **endReachedDistance** (field that exist on most movement scripts) units from the destination. | | ContinueToExactDestination | The character will continue to the exact position of the destination. | What to do when the character is close to the destination. GraphDebugMode How to visualize the graphs in the editor. ##### GraphDebugMode | | | | --- | --- | | SolidColor | Draw the graphs with a single solid color. | | G | Use the G score of the last calculated paths to color the graph.

The G score is the cost from the start node to the given node.

See

[https://en.wikipedia.org/wiki/A](https://en.wikipedia.org/wiki/A)
\*\_search\_algorithm | | H | Use the H score (heuristic) of the last calculated paths to color the graph.

The H score is the estimated cost from the current node to the target.

See

[https://en.wikipedia.org/wiki/A](https://en.wikipedia.org/wiki/A)
\*\_search\_algorithm | | F | Use the F score of the last calculated paths to color the graph.

The F score is the G score + the H score, or in other words the estimated cost total cost of the path.

See

[https://en.wikipedia.org/wiki/A](https://en.wikipedia.org/wiki/A)
\*\_search\_algorithm | | Penalty | Use the penalty of each node to color the graph.

This does not show penalties added by tags.

See

[Graph Updates during Runtime](https://arongranberg.com/astar/docs/graphupdates.html)

[Pathfinding.GraphNode.Penalty](https://arongranberg.com/astar/docs/graphnode.html#Penalty) | | Areas | Visualize the connected components of the graph.

A node with a given color can reach any other node with the same color.

See

[Pathfinding.HierarchicalGraph](https://arongranberg.com/astar/docs/hierarchicalgraph.html)

[https://en.wikipedia.org/wiki/Connected\_component\_(graph\_theory)](https://en.wikipedia.org/wiki/Connected_component_(graph_theory)) | | Tags | Use the tag of each node to color the graph.

See

[Working with tags](https://arongranberg.com/astar/docs/tags.html)

[Pathfinding.GraphNode.Tag](https://arongranberg.com/astar/docs/graphnode.html#Tag) | | HierarchicalNode | Visualize the hierarchical graph structure of the graph.

This is mostly for internal use.

See

[Pathfinding.HierarchicalGraph](https://arongranberg.com/astar/docs/hierarchicalgraph.html) | | NavmeshBorderObstacles | Visualize the obstacles generated from the navmesh border.

These obstacles are used for local avoidance, as well as for the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html)
in its internal navigation.

The graph will be colored the same as for [GraphDebugMode.HierarchicalNode](https://arongranberg.com/astar/docs/pathfinding.html#HierarchicalNode)
. | How to visualize the graphs in the editor. GraphUpdateDebugMode How to visualize graph updates in the editor. ##### GraphUpdateDebugMode | | | | --- | --- | | Nothing= 0 | | | VisualizeOriginalBounds= 1 << 0 | Visualize the original bounds of graph updates.

This is the volume which was specified in the [GraphUpdateObject](https://arongranberg.com/astar/docs/graphupdateobject.html)
.

In the screenshot, it is visualized as a yellow box. ![](https://arongranberg.com/astar/docs/images/graph_update_debug_mode.png)

See

[GraphUpdateObject.bounds](https://arongranberg.com/astar/docs/graphupdateobject.html#bounds) | | VisualizeAffectedBounds= 1 << 1 | Visualize the affected regions of graph updates.

This is typically larger than the original bounds. For recast graphs, it will be the bounds of the tiles that were updated. For grid graphs, it will be the bounds of a rectangle of nodes a bit larger than the original bounds.

In the screenshot, it is visualized as an orange box. ![](https://arongranberg.com/astar/docs/images/graph_update_debug_mode.png)

See

[GraphUpdateObject.bounds](https://arongranberg.com/astar/docs/graphupdateobject.html#bounds) | | VisualizeOverTime= 1 << 2 | If enabled, the visualizations will stick around for a second or so, to make it easier to see what is happening.

If disabled, the visualizations will only be shown for a single frame. | How to visualize graph updates in the editor. This is used to visualize the bounds of graph updates, and how they affect the graph. See [GraphUpdateObject](https://arongranberg.com/astar/docs/graphupdateobject.html) [AstarPath.graphUpdateDebugMode](https://arongranberg.com/astar/docs/astarpath.html#graphUpdateDebugMode) GraphUpdateStage Info about if a graph update has been applied or not. ##### GraphUpdateStage | | | | --- | --- | | Created | The graph update object has been created, but not used for anything yet.

This is the default value. | | Pending | The graph update has been sent to the pathfinding system and is scheduled to be applied to the graphs. | | Applied | The graph update has been applied to all graphs. | | Aborted | The graph update has been aborted and will not be applied.

This can happen if the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html)
component is destroyed while a graph update is queued to be applied. | Info about if a graph update has been applied or not. GraphUpdateThreading ##### GraphUpdateThreading | | | | --- | --- | | UnityThread= 0 | Call UpdateArea in the unity thread.

This is the default value. | | UnityInit= 1 << 1 | Calls UpdateAreaInit in the Unity thread before everything else. | | UnityPost= 1 << 2 | Calls UpdateAreaPost in the Unity thread after everything else. | Heuristic How to estimate the cost of moving to the destination during pathfinding. ##### Heuristic | | | | --- | --- | | Manhattan | Manhattan distance.

See

[https://en.wikipedia.org/wiki/Taxicab\_geometry](https://en.wikipedia.org/wiki/Taxicab_geometry) | | DiagonalManhattan | Manhattan distance, but allowing diagonal movement as well.

Note

This option is currently hard coded for the XZ plane. It will be equivalent to Manhattan distance if you try to use it in the XY plane (i.e for a 2D game). | | Euclidean | Ordinary distance.

See

[https://en.wikipedia.org/wiki/Euclidean\_distance](https://en.wikipedia.org/wiki/Euclidean_distance) | | None | Use no heuristic at all.

This reduces the pathfinding algorithm to Dijkstra's algorithm. This is usually significantly slower compared to using a heuristic, which is why the A\* algorithm is usually preferred over Dijkstra's algorithm. You may have to use this if you have a very non-standard graph. For example a world with a [wraparound playfield](https://en.wikipedia.org/wiki/Wraparound_(video_games))
(think Civilization or Asteroids) and you have custom links with a zero cost from one end of the map to the other end. Usually the A\* algorithm wouldn't find the wraparound links because it wouldn't think to look in that direction.

See

[https://en.wikipedia.org/wiki/Dijkstra%27s\_algorithm](https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm) | How to estimate the cost of moving to the destination during pathfinding. The heuristic is the estimated cost from the current node to the target. The different heuristics have roughly the same performance except not using any heuristic at all ( [Heuristic.None](https://arongranberg.com/astar/docs/pathfinding.html#None) ) which is usually significantly slower. In the image below you can see a comparison of the different heuristic options for an 8-connected grid and for a 4-connected grid. Note that all paths within the green area will all have the same length. The only difference between the heuristics is which of those paths of the same length that will be chosen. Note that while the Diagonal Manhattan and Manhattan options seem to behave very differently on an 8-connected grid they only do it in this case because of very small rounding errors. Usually they behave almost identically on 8-connected grids. ![](https://arongranberg.com/astar/docs/images/heuristic.png) Generally for a 4-connected grid graph the Manhattan option should be used as it is the true distance on a 4-connected grid. For an 8-connected grid graph the Diagonal Manhattan option is the mathematically most correct option, however the Euclidean option is often preferred, especially if you are simplifying the path afterwards using modifiers. For any graph that is not grid based the Euclidean option is the best one to use. See [Wikipedia: A\* search\_algorithm](https://en.wikipedia.org/wiki/A*_search_algorithm) InspectorGridHexagonNodeSize ##### InspectorGridHexagonNodeSize | | | | --- | --- | | Width | Value is the distance between two opposing sides in the hexagon. | | Diameter | Value is the distance between two opposing vertices in the hexagon. | | NodeSize | Value is the raw node size of the grid. | InspectorGridMode ##### InspectorGridMode | | | | --- | --- | | Grid | | | IsometricGrid | | | Hexagonal | | | Advanced | | NumNeighbours Number of neighbours for a single grid node. ##### NumNeighbours | | | | --- | --- | | Four | | | Eight | | | Six | | Number of neighbours for a single grid node. Since The 'Six' item was added in 3.6.1 OrientationMode Determines which direction the agent moves in. ##### OrientationMode | | | | --- | --- | | ZAxisForward | | | YAxisForward | | Determines which direction the agent moves in. For 3D games you most likely want the ZAxisIsForward option as that is the convention for 3D games. For 2D games you most likely want the YAxisIsForward option as that is the convention for 2D games. PathCompleteState State of a path request. ##### PathCompleteState | | | | --- | --- | | NotCalculated= 0 | The path has not been calculated yet.

See

[Path.IsDone](https://arongranberg.com/astar/docs/path/isdone.html#IsDone) | | Error= 1 | The path calculation is done, but it failed.

See

[Path.error](https://arongranberg.com/astar/docs/path.html#error) | | Complete= 2 | The path has been successfully calculated.

Warning

Do not use this to check if the path has been calculated yet, as this is set on a separate thread before the state of the path is finalized. Use [Path.IsDone](https://arongranberg.com/astar/docs/path/isdone.html#IsDone)
, callbacks, [Path.WaitForPath](https://arongranberg.com/astar/docs/path/waitforpath.html#WaitForPath)
or [Path.BlockUntilCalculated](https://arongranberg.com/astar/docs/path/blockuntilcalculated.html#BlockUntilCalculated)
instead. You'll run into race conditions if you use this to check if the path has been calculated.

See

[Searching for paths](https://arongranberg.com/astar/docs/callingpathfinding.html) | | Partial= 3 | The path has been calculated, but only a partial path could be found.

See

[ABPath.calculatePartial](https://arongranberg.com/astar/docs/abpath.html#calculatePartial) | State of a path request. PathLog How path results are logged by the system. ##### PathLog | | | | --- | --- | | None | Does not log anything.

This is recommended for release since logging path results has a performance overhead. | | Normal | Logs basic info about the paths. | | Heavy | Includes additional info. | | InGame | Same as heavy, but displays the info in-game using GUI. | | OnlyErrors | Same as normal, but logs only paths which returned an error. | How path results are logged by the system. PathState Internal state of a path in the pipeline. ##### PathState | | | | --- | --- | | Created= 0 | [Path](https://arongranberg.com/astar/docs/path.html)
has been created but not yet scheduled. | | PathQueue= 1 | [Path](https://arongranberg.com/astar/docs/path.html)
is waiting to be calculated. | | Processing= 2 | [Path](https://arongranberg.com/astar/docs/path.html)
is being calculated. | | ReturnQueue= 3 | [Path](https://arongranberg.com/astar/docs/path.html)
is calculated and is waiting to have its callback called. | | Returning= 4 | The path callback is being called right now (only set inside the callback itself) | | Returned= 5 | The path has been calculated and its callback has been called. | Internal state of a path in the pipeline. ScanningStage Info about where in the scanning process a graph is. ##### ScanningStage | | | | --- | --- | | PreProcessingGraphs | | | PreProcessingGraph | | | ScanningGraph | | | PostProcessingGraph | | | FinishingScans | | Info about where in the scanning process a graph is. Side Indicates the side of a line that a point lies on. ##### Side | | | | --- | --- | | Colinear= 0 | The point lies exactly on the line. | | Left= 1 | The point lies on the left side of the line. | | Right= 2 | The point lies on the right side of the line. | Indicates the side of a line that a point lies on. TemporaryNodeType ##### TemporaryNodeType | | | | --- | --- | | Start | | | End | | | Ignore | | ThreadCount Number of threads to use. ##### ThreadCount | | | | --- | --- | | AutomaticLowLoad= -1 | | | AutomaticHighLoad= -2 | | | None= 0 | | | One= 1 | | | Two | | | Three | | | Four | | | Five | | | Six | | | Seven | | | Eight | | Number of threads to use. Public Typedefs --------------- Math ##### System.Math Math Thread ##### System.Threading.Thread Thread --- # Graph Types - A* Pathfinding Project Group Graph Types ================= Collection of the most used graph types. [GridGraph](https://arongranberg.com/astar/docs/gridgraph.html) Generates a grid of nodes. [LayerGridGraph](https://arongranberg.com/astar/docs/layergridgraph.html) Grid Graph, supports layered worlds. [NavMeshGraph](https://arongranberg.com/astar/docs/navmeshgraph.html) Generates graphs based on navmeshes. [PointGraph](https://arongranberg.com/astar/docs/pointgraph.html) Graph consisting of a set of points. [RecastGraph](https://arongranberg.com/astar/docs/recastgraph.html) Automatically generates navmesh graphs based on world geometry. --- # Node - A* Pathfinding Project Struct Node =========== Private Public Variables ---------------- bounds Public ##### [Bounds](https://docs.unity3d.com/ScriptReference/Bounds.html) bounds flags Public ##### uint flags isAllocated Public ##### bool? isAllocated isLeaf Public ##### bool isLeaf left Public ##### int left parent Public ##### int parent right Public ##### int right subtreePartiallyTagged Public ##### bool? subtreePartiallyTagged value Public ##### T value wholeSubtreeTagged Public ##### bool? wholeSubtreeTagged Public Static Variables ----------------------- AllocatedBit Public Static ##### const uint AllocatedBit = 1u << 29 InvalidParent Public Static ##### const int InvalidParent = (int)[ParentMask](https://arongranberg.com/astar/docs/node.html#ParentMask) ParentMask Public Static ##### const uint ParentMask = ~([TagInsideBit](https://arongranberg.com/astar/docs/node.html#TagInsideBit) | [TagPartiallyInsideBit](https://arongranberg.com/astar/docs/node.html#TagPartiallyInsideBit) | [AllocatedBit](https://arongranberg.com/astar/docs/node.html#AllocatedBit) ) TagInsideBit Public Static ##### const uint TagInsideBit = 1u << 30 TagPartiallyInsideBit Public Static ##### const uint TagPartiallyInsideBit = 1u << 31 --- # NNConstraint - A* Pathfinding Project Class NNConstraint ================== Public Nearest node constraint. Constrains which nodes will be returned by the [GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) function. Deprecated Use [NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) instead. This class is deprecated and will be removed in a future version. Public Methods -------------- [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint/nnconstraint.html#NNConstraint) () Default constructor. [Suitable](https://arongranberg.com/astar/docs/nnconstraint/suitable.html#Suitable) (node) Returns whether or not the node conforms to this [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) 's rules. [SuitableGraph](https://arongranberg.com/astar/docs/nnconstraint/suitablegraph.html#SuitableGraph) (graphIndex, graph) Returns whether or not the graph conforms to this [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) 's rules. [ToNearestNodeConstraint](https://arongranberg.com/astar/docs/nnconstraint/tonearestnodeconstraint.html#ToNearestNodeConstraint) () [ToTraversalConstraint](https://arongranberg.com/astar/docs/nnconstraint/totraversalconstraint.html#ToTraversalConstraint) () [UseSettings](https://arongranberg.com/astar/docs/nnconstraint/usesettings.html#UseSettings) (settings) Public Variables ---------------- area Area ID to constrain to. Public ##### int area = -1 Area ID to constrain to. Will not affect anything if less than 0 (zero) or if [constrainArea](https://arongranberg.com/astar/docs/nnconstraint.html#constrainArea) is false constrainArea Only treat nodes in the area [area](https://arongranberg.com/astar/docs/nnconstraint.html#area) as suitable. Public ##### bool constrainArea Only treat nodes in the area [area](https://arongranberg.com/astar/docs/nnconstraint.html#area) as suitable. Does not affect anything if [area](https://arongranberg.com/astar/docs/nnconstraint.html#area) is less than 0 (zero) constrainDistance Constrain distance to node. Public ##### bool constrainDistance = true Constrain distance to node. Uses distance from [AstarPath.maxNearestNodeDistance](https://arongranberg.com/astar/docs/astarpath.html#maxNearestNodeDistance) . If this is false, it will completely ignore the distance limit. If there are no suitable nodes within the distance limit then the search will terminate with a null node as a result. Note This value is not used in this class, it is used by the [AstarPath.GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) function. constrainTags Sets if tags should be constrained. Public ##### bool constrainTags = true Sets if tags should be constrained. See [tags](https://arongranberg.com/astar/docs/nnconstraint.html#tags) constrainWalkability Constrain the search to only walkable or unwalkable nodes depending on [walkable](https://arongranberg.com/astar/docs/nnconstraint.html#walkable) . Public ##### bool constrainWalkability = true Constrain the search to only walkable or unwalkable nodes depending on [walkable](https://arongranberg.com/astar/docs/nnconstraint.html#walkable) . distanceMetric Determines how to measure distances to the navmesh. Public ##### [DistanceMetric](https://arongranberg.com/astar/docs/distancemetric.html) distanceMetric Determines how to measure distances to the navmesh. The default is a euclidean distance, which works well for most things. See [DistanceMetric](https://arongranberg.com/astar/docs/distancemetric.html) graphMask [Graphs](https://arongranberg.com/astar/docs/graphs2.html) treated as valid to search on. Public ##### [GraphMask](https://arongranberg.com/astar/docs/graphmask.html) graphMask = [GraphMask.everything](https://arongranberg.com/astar/docs/graphmask.html#everything) [Graphs](https://arongranberg.com/astar/docs/graphs2.html) treated as valid to search on. This is a bitmask meaning that bit 0 specifies whether or not the first graph in the graphs list should be able to be included in the search, bit 1 specifies whether or not the second graph should be included and so on. `// Enables the first and third graphs to be included, but not the rest myNNConstraint.graphMask = (1 << 0) | (1 << 2); ``GraphMask mask1 = GraphMask.FromGraphName("My Grid Graph"); GraphMask mask2 = GraphMask.FromGraphName("My Other Grid Graph"); NearestNodeConstraint nn = NearestNodeConstraint.Walkable; nn.graphMask = mask1 | mask2; // Find the node closest to somePoint which is either in 'My Grid Graph' OR in 'My Other Grid Graph' var info = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (somePoint, nn); ` Note This does only affect which nodes are returned from a [GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) call, if a valid graph is connected to an invalid graph using a node link then it might be searched anyway. See [AstarPath.GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) [SuitableGraph](https://arongranberg.com/astar/docs/nnconstraint/suitablegraph.html#SuitableGraph) [Bitmask Tutorial](https://arongranberg.com/astar/docs/bitmasks.html) tags Nodes which have any of these tags set are suitable. Public ##### int tags = -1 Nodes which have any of these tags set are suitable. This is a bitmask, i.e bit 0 indicates that tag 0 is good, bit 3 indicates tag 3 is good etc. See [constrainTags](https://arongranberg.com/astar/docs/nnconstraint.html#constrainTags) [graphMask](https://arongranberg.com/astar/docs/nnconstraint.html#graphMask) [Bitmask Tutorial](https://arongranberg.com/astar/docs/bitmasks.html) walkable Only search for walkable or unwalkable nodes if [constrainWalkability](https://arongranberg.com/astar/docs/nnconstraint.html#constrainWalkability) is enabled. Public ##### bool walkable = true Only search for walkable or unwalkable nodes if [constrainWalkability](https://arongranberg.com/astar/docs/nnconstraint.html#constrainWalkability) is enabled. If true, only walkable nodes will be searched for, otherwise only unwalkable nodes will be searched for. Does not affect anything if [constrainWalkability](https://arongranberg.com/astar/docs/nnconstraint.html#constrainWalkability) if false. Public Static Variables ----------------------- None Returns a constraint which does not filter the results. Public Static ##### [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) None Returns a constraint which does not filter the results. Walkable An [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) which filters out unwalkable nodes. Public Static ##### [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) Walkable An [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) which filters out unwalkable nodes. This is the most commonly used [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) . It also constrains the nearest node to be within the distance set by A\* Inspector -> Settings -> Max Nearest Node Distance Deprecated Members ------------------ Default The default [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) . Public Static ##### [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) Default The default [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) . Equivalent to new [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) (). This [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) has settings which works for most, it only finds walkable nodes and it constrains distance set by A\* Inspector -> Settings -> Max Nearest Node Distance Deprecated Use [NNConstraint.Walkable](https://arongranberg.com/astar/docs/nnconstraint.html#Walkable) instead. It is equivalent, but the name is more descriptive. distanceXZ if available, do an XZ check instead of checking on all axes. Public ##### bool distanceXZ if available, do an XZ check instead of checking on all axes. The navmesh/recast graph as well as the grid/layered grid graph supports this. This can be important on sloped surfaces. See the image below in which the closest point for each blue point is queried for: ![](https://arongranberg.com/astar/docs/images/distanceXZ2.png) Deprecated Use [distanceMetric](https://arongranberg.com/astar/docs/nnconstraint.html#distanceMetric) = [DistanceMetric.ClosestAsSeenFromAbove()](https://arongranberg.com/astar/docs/distancemetric/closestasseenfromabove.html#ClosestAsSeenFromAbove) instead --- # CloseNode - A* Pathfinding Project Struct CloseNode ================ Public Public Variables ---------------- closestPointOnNode Public ##### float3 closestPointOnNode distanceSq Public ##### float distanceSq node Public ##### int node tieBreakingDistance Public ##### float tieBreakingDistance --- # BBTreeBox - A* Pathfinding Project Struct BBTreeBox ================ Public Public Methods -------------- [BBTreeBox](https://arongranberg.com/astar/docs/bbtreebox/bbtreebox.html#BBTreeBox) (rect) Public Variables ---------------- IsLeaf Public ##### bool IsLeaf left Public ##### int left nodeOffset Public ##### int nodeOffset rect Public ##### [IntRect](https://arongranberg.com/astar/docs/intrect.html) rect right Public ##### int right --- # NearestNodeConstraint - A* Pathfinding Project Struct NearestNodeConstraint ============================ Public Constraint for the [AstarPath.GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html) method. This is used to filter out nodes you are not interested in. For example, you can use this to only find walkable nodes, or only nodes with a specific tag. See [AstarPath.GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html) **Why is this struct passed around with the ref keyword all the time?** Structs are passed by value in C#, and copying them can be expensive when they are large (like this one at around 44 bytes). Using the ref keyword allows it to be passed by reference instead, which is much faster. **But then why is it not a class?** Firstly, because classes involve the garbage collector, and since this struct is created very often (often many times per frame), we want to avoid that. Garbage collections are very expensive operations, and can cause stuttering in the game. Public Methods -------------- [Suitable](https://arongranberg.com/astar/docs/nearestnodeconstraint/suitable.html#Suitable) (node) True if the node is ok with respect to the constraints set in this struct. Public Variables ---------------- allNodesAreSuitable True if all nodes are suitable with respect to the constraints set in this struct. Public ##### bool allNodesAreSuitable True if all nodes are suitable with respect to the constraints set in this struct. The [Suitable](https://arongranberg.com/astar/docs/nearestnodeconstraint/suitable.html#Suitable) method will return true for all nodes if this is true. area Area ID to constrain to. Public ##### int area Area ID to constrain to. Will not affect anything if negative. See [GraphNode.Area](https://arongranberg.com/astar/docs/graphnode.html#Area) distanceMetric Determines how to measure distances to the navmesh. Public ##### [DistanceMetric](https://arongranberg.com/astar/docs/distancemetric.html) distanceMetric Determines how to measure distances to the navmesh. The default is a euclidean distance, which works well for most things. See [DistanceMetric](https://arongranberg.com/astar/docs/distancemetric.html) filter Allow only nodes which the given filter function returns true for. Public ##### System.Func<[GraphNode](https://arongranberg.com/astar/docs/graphnode.html) , bool> filter Allow only nodes which the given filter function returns true for. The other constraints on this struct will still apply, in addition to the filter function. Note Either an [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) ([traversalProvider](https://arongranberg.com/astar/docs/nearestnodeconstraint.html#traversalProvider) ) or a filter function can be set, but not both. Setting this will clear [traversalProvider](https://arongranberg.com/astar/docs/nearestnodeconstraint.html#traversalProvider) , and vice versa. `var nearestNodeConstraint = NearestNodeConstraint.None; // Set a custom filter. This can be an arbitrary function which takes a GraphNode and returns true or false. nearestNodeConstraint.filter = (GraphNode node) => ((Vector3)node.position).y > 50; // Find the closest node to our position which is above y=50 var nearest = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (transform.position, nearestNodeConstraint); ` See [traversalProvider](https://arongranberg.com/astar/docs/nearestnodeconstraint.html#traversalProvider) graphMask Graphs which are traversable. Public ##### [GraphMask](https://arongranberg.com/astar/docs/graphmask.html) graphMask Graphs which are traversable. This is a bitmask, meaning that bit 0 specifies whether or not the first graph in the graphs list should be included in the search, bit 1 specifies whether or not the second graph should be included, and so on. `var traversalConstraint = [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint/traversalconstraint.html#TraversalConstraint2) .None; // Allows the first and fourth graphs to be searched, but not the rest traversalConstraint.graphMask = GraphMask.FromGraphIndex(0) | GraphMask.FromGraphIndex(3); // Allows the two named graphs to be searched, but not the rest traversalConstraint.graphMask = GraphMask.FromGraphName("My Custom Graph Name") | GraphMask.FromGraphName("My Other Graph"); ` Note When used for pathfinding, this does only affects which nodes the path starts and ends on. If a valid graph is connected to an "invalid" graph, it may get searched anyway. See [AstarPath.GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html) [GraphMask](https://arongranberg.com/astar/docs/graphmask.html) [Bitmask Tutorial](https://arongranberg.com/astar/docs/bitmasks.html) maxDistance The maximum distance to the navmesh to search before the search fails. Public ##### float??? maxDistance The maximum distance to the navmesh to search before the search fails. This is the maximum distance from the query point to the closest point on the navmesh. If null (the default), the default limit set on the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component will be used ( [AstarPath.maxNearestNodeDistance](https://arongranberg.com/astar/docs/astarpath.html#maxNearestNodeDistance) ). Positive infinity is a valid value, meaning it will search for the closest node regardless of distance. 0 is also a valid value, but it usually only makes sense with a different distance metric than the default. Note The distance depends on the distance metric used. See [AstarPath::maxNearestNodeDistance](https://arongranberg.com/astar/docs/astarpath.html#maxNearestNodeDistance) [distanceMetric](https://arongranberg.com/astar/docs/nearestnodeconstraint.html#distanceMetric) maxDistanceSqr Squared [maxDistance](https://arongranberg.com/astar/docs/nearestnodeconstraint.html#maxDistance) . Public ##### float maxDistanceSqr Squared [maxDistance](https://arongranberg.com/astar/docs/nearestnodeconstraint.html#maxDistance) . Negative value means to use the default A\* limit ( [AstarPath.maxNearestNodeDistance](https://arongranberg.com/astar/docs/astarpath.html#maxNearestNodeDistance) ). Positive value means to use a custom limit. Typically you'll modify [maxDistance](https://arongranberg.com/astar/docs/nearestnodeconstraint.html#maxDistance) instead of this. See [maxDistance](https://arongranberg.com/astar/docs/nearestnodeconstraint.html#maxDistance) tags Set of tags which are traversable. Public ##### int tags Set of tags which are traversable. This is a bitmask, i.e bit 0 indicates that tag 0 is traversable, bit 3 indicates tag 3 is traversable etc. By default all tags are traversable, which corresponds to the value -1. `var traversalConstraint = [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint/traversalconstraint.html#TraversalConstraint2) .None; // Allows the first and third tags to be searched, but not the rest traversalConstraint.tags = (1 << 0) | (1 << 2); // Allows the two named tags to be searched, but not the rest traversalConstraint.tags = PathfindingTag.FromName("Grass").ToMask() | PathfindingTag.FromName("Lava").ToMask(); `If you are using the [Seeker](https://arongranberg.com/astar/docs/seeker.html) or [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) components, you can access this in the inspector via the tags foldout: ![](https://arongranberg.com/astar/docs/images/tagpopup@2x.png) See [graphMask](https://arongranberg.com/astar/docs/traversalconstraint.html#graphMask) [Working with tags](https://arongranberg.com/astar/docs/tags.html) [Bitmask Tutorial](https://arongranberg.com/astar/docs/bitmasks.html) [PathfindingTag.ToMask](https://arongranberg.com/astar/docs/pathfindingtag/tomask.html#ToMask) traversalProvider Allow traversing only nodes that are also traversable by the given [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) . Public ##### [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) traversalProvider Allow traversing only nodes that are also traversable by the given [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) . The other constraints on this struct will still apply, in addition to the [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) . Note Either an [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) or a callback filter ( [filter](https://arongranberg.com/astar/docs/nearestnodeconstraint.html#filter) ) can be set, but not both. Setting this will clear [filter](https://arongranberg.com/astar/docs/traversalconstraint.html#filter) , and vice versa. See [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) [Agent-Specific Pathfinding](https://arongranberg.com/astar/docs/traversal_provider.html) [filter](https://arongranberg.com/astar/docs/traversalconstraint.html#filter) walkable Constraint to only search only walkable nodes, only unwalkable nodes, or both. Public ##### [WalkabilityConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html#WalkabilityConstraint) walkable Constraint to only search only walkable nodes, only unwalkable nodes, or both. See [GraphNode.Walkable](https://arongranberg.com/astar/docs/graphnode.html#Walkable) Public Static Variables ----------------------- None Constraint which allows all nodes. Public Static Readonly ##### [NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) None = new [NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) { [traversal](https://arongranberg.com/astar/docs/nearestnodeconstraint.html#traversal) = TraversalConstraint.None, [distanceMetric](https://arongranberg.com/astar/docs/nearestnodeconstraint.html#distanceMetric) = [DistanceMetric.Euclidean](https://arongranberg.com/astar/docs/distancemetric.html#Euclidean) , [area](https://arongranberg.com/astar/docs/nearestnodeconstraint.html#area) = -1, [maxDistanceSqr](https://arongranberg.com/astar/docs/nearestnodeconstraint.html#maxDistanceSqr) = -1, [walkable](https://arongranberg.com/astar/docs/nearestnodeconstraint.html#walkable) = WalkabilityConstraint.DontCare, } Constraint which allows all nodes. Walkable Constraint which filters out all unwalkable nodes. Public Static Readonly ##### [NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) Walkable = new [NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) { [traversal](https://arongranberg.com/astar/docs/nearestnodeconstraint.html#traversal) = [TraversalConstraint.None](https://arongranberg.com/astar/docs/traversalconstraint.html#None) , [distanceMetric](https://arongranberg.com/astar/docs/nearestnodeconstraint.html#distanceMetric) = [DistanceMetric.Euclidean](https://arongranberg.com/astar/docs/distancemetric.html#Euclidean) , [area](https://arongranberg.com/astar/docs/nearestnodeconstraint.html#area) = -1, [maxDistanceSqr](https://arongranberg.com/astar/docs/nearestnodeconstraint.html#maxDistanceSqr) = -1, [walkable](https://arongranberg.com/astar/docs/nearestnodeconstraint.html#walkable) = WalkabilityConstraint.Walkable, } Constraint which filters out all unwalkable nodes. Public Enums ------------ WalkabilityConstraint Public ##### WalkabilityConstraint | | | | --- | --- | | Walkable | | | Unwalkable | | | DontCare | | Private/Protected Members ------------------------- [maxDistanceSqrOrDefault](https://arongranberg.com/astar/docs/nearestnodeconstraint/maxdistancesqrordef.html#maxDistanceSqrOrDefault) (astar) traversal Sub-filter with more constraints. Internal ##### [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint.html) traversal Sub-filter with more constraints. --- # GetNearest - A* Pathfinding Project Function [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .GetNearest ==================================================================================== GetNearest ([Ray](https://docs.unity3d.com/ScriptReference/Ray.html) ray) Returns the nearest node to a ray (slow). Public ##### [GraphNode](https://arongranberg.com/astar/docs/graphnode.html) GetNearest ( | | | | | --- | --- | --- | | [Ray](https://docs.unity3d.com/ScriptReference/Ray.html) | ray | | ) Returns the nearest node to a ray (slow). Warning This function is brute-force and very slow, use with caution GetNearest ([Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) position) Returns the nearest node to a point. Public ##### [NNInfo](https://arongranberg.com/astar/docs/nninfo.html) GetNearest ( | | | | | --- | --- | --- | | [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) | position | | ) Returns the nearest node to a point. This method will search through all graphs and query them for the closest node (walkable or unwalkable) to this position. Equivalent to GetNearest(position, NearestNodeConstraint.None). `// Find the closest node to this GameObject's position GraphNode node = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (transform.position).node; if (node.Walkable) { // Yay, the node is walkable, we can place a tower here or something } ` See [NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) GetNearest ([Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) position, [NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) constraint) Returns the nearest node to a point using the specified NearestNodeConstraint. Public ##### [NNInfo](https://arongranberg.com/astar/docs/nninfo.html) GetNearest ( | | | | | --- | --- | --- | | [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) | position | The point to find nodes close to | | [NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) | constraint | The constraint which determines which graphs and nodes are acceptable to search on. | ) Returns the nearest node to a point using the specified NearestNodeConstraint. Searches through all graphs for their nearest nodes to the specified position and picks the closest one. The [NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) can be used to specify constraints on which nodes can be chosen, such as only picking walkable nodes. `GraphNode node = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (transform.position, NearestNodeConstraint.Walkable).node; ``var constraint = NearestNodeConstraint.None; // Constrain the search to walkable nodes only constraint.walkable = NearestNodeConstraint.WalkabilityConstraint.Walkable; // Constrain the search to only nodes with tag 3 or tag 5 // The 'tags' field is a bitmask constraint.tags = (1 << 3) | (1 << 5); var info = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (transform.position, constraint); var node = info.node; var closestPoint = info.position; ` See [NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) GetNearest ([Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) position, ref[NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) constraint) Internal ##### [NNInfo](https://arongranberg.com/astar/docs/nninfo.html) GetNearest ( | | | | | --- | --- | --- | | [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) | position | | | ref[NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) | constraint | | ) GetNearest ([Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) position, [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) constraint) Returns the nearest node to a point using the specified NNConstraint. Public ##### [NNInfo](https://arongranberg.com/astar/docs/nninfo.html) GetNearest ( | | | | | --- | --- | --- | | [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) | position | The point to find nodes close to | | [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) | constraint | The constraint which determines which graphs and nodes are acceptable to search on. May be null, in which case all nodes will be considered acceptable. | ) Returns the nearest node to a point using the specified NNConstraint. Searches through all graphs for their nearest nodes to the specified position and picks the closest one. The NNConstraint can be used to specify constraints on which nodes can be chosen, such as only picking walkable nodes. `GraphNode node = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (transform.position, NearestNodeConstraint.Walkable).node; ``var constraint = NearestNodeConstraint.None; // Constrain the search to walkable nodes only constraint.walkable = NearestNodeConstraint.WalkabilityConstraint.Walkable; // Constrain the search to only nodes with tag 3 or tag 5 // The 'tags' field is a bitmask constraint.tags = (1 << 3) | (1 << 5); var info = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (transform.position, constraint); var node = info.node; var closestPoint = info.position; ` See [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) Deprecated This method is obsolete. Use the overload that takes a NearestNodeConstraint instead. --- # Wandering AI Tutorial - A* Pathfinding Project Wandering AI Tutorial ===================== Tutorial on how to make a wandering AI. There are several methods for making a wandering AI. They differ in both quality and performance. There is no obvious best solution; different methods will suit different games better. For each method, I have listed some advantages and disadvantages. * [Method 1: Random point inside a circle](https://arongranberg.com/astar/docs/wander.html#method1) * [Method 2: Random point in the whole graph](https://arongranberg.com/astar/docs/wander.html#method2_2) * [Method 3: The RandomPath type](https://arongranberg.com/astar/docs/wander.html#method2) * [Method 4: The ConstantPath type](https://arongranberg.com/astar/docs/wander.html#method3) * [Method 5: Breadth-first search](https://arongranberg.com/astar/docs/wander.html#method4) Method 1: Random point inside a circle -------------------------------------- The easiest method for picking a point to move to is simply to pick a random point within a specific distance around the character. `Vector3 PickRandomPoint () { var point = Random.insideUnitSphere * radius; point.y = 0; point += transform.position; return point; } `If you are using one of the included movement scripts, you can, for example, change the destination of the AI whenever it has reached the end of its current path: `using UnityEngine; using System.Collections; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) ; public class WanderingDestinationSetter : MonoBehaviour { public float radius = 20; IAstarAI ai; void Start () { ai = GetComponent(); } Vector3 PickRandomPoint () { var point = Random.insideUnitSphere * radius; point.y = 0; point += ai.position; return point; } void Update () { // Update the destination of the AI if // the AI is not already calculating a path and // the ai has reached the end of the path or it has no path at all if (!ai.pathPending && (ai.reachedEndOfPath || !ai.hasPath)) { ai.destination = PickRandomPoint(); ai.SearchPath(); } } } ` You can attach the script above to any GameObject with one of the built-in movement scripts (e.g., AIPath/RichAI/AILerp). Note Make sure that you do not have any other components attached that also try to set the destination of the AI (e.g., the [AIDestinationSetter](https://arongranberg.com/astar/docs/aidestinationsetter.html) component). Your browser does not support the video tag. Your browser does not support the video tag. See [Pathfinding.IAstarAI](https://arongranberg.com/astar/docs/iastarai.html) [Random.insideUnitSphere](https://docs.unity3d.com/ScriptReference/Random-insideUnitSphere.html) Advantages * Very fast. * Simple code. * Works reasonably well for all graph types. Disadvantages * Ignores the actual distance to the point, which means it can produce very long paths if the world is not very open (see the video above). * Has a slight bias towards points close to walls/obstacles as any points that were generated inside the obstacles would have to be snapped to the closest point on the graph. Misc * Ignores penalties when picking points (penalties will be taken into account when searching for a path to the point though). Method 2: Random point in the whole graph ----------------------------------------- Sometimes you just want something very simple. Instead of picking a node around the current position, you can just pick a random node in the graph and try to walk towards the position of that node. `// Pick a random walkable point on the graph, sampled uniformly over the graph's surface var sample = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[graphs](https://arongranberg.com/astar/docs/astarpath.html#graphs) [0].RandomPointOnSurface(NearestNodeConstraint.Walkable); // Use a random point on the surface of the node as the destination. var destination1 = sample.position; // Or use the center of the node as the destination var destination2 = (Vector3)sample.node.position; ` See [NavGraph.RandomPointOnSurface](https://arongranberg.com/astar/docs/navgraph/randompointonsurface.html) Depending on what you want to use this for, you may want to pass in an [NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) to restrict which nodes can be returned: * Check if the node is walkable (see [NearestNodeConstraint.Walkable](https://arongranberg.com/astar/docs/nearestnodeconstraint.html#Walkable) ) * Check if the node can be reached from the AI (see [NearestNodeConstraint.area](https://arongranberg.com/astar/docs/nearestnodeconstraint.html#area) ) Advantages * Fast in most cases (sampling points on navmesh/recast graphs is slower, and it can also be slow to find a valid point if the NearestNodeConstraint is very restrictive). * Simple code Disadvantages * Very little control over the length of the path. Misc * Ignores penalties when picking points (penalties will be taken into account when searching for a path to the point though). Method 3: The RandomPath type ----------------------------- The RandomPath type is a path type that, in contrast to the normal paths which calculate a path from a specific point to another specific point, calculates a random path away from a starting point. If you are using one of the built-in movement scripts (see [Movement scripts](https://arongranberg.com/astar/docs/movementscripts.html) ) you can do something like this: `// Disable the agent's internal automatic path recalculation ai.canSearch = false; RandomPath path = RandomPath.Construct(transform.position, searchLength); path.spread = spread; // Give the agent a path to calculate and follow ai.SetPath(path); `If you are using a custom movement script, you will have to pass it to the seeker manually. `RandomPath path = RandomPath.Construct(transform.position, searchLength); path.spread = spread; seeker.StartPath(path); ` See [Searching for paths](https://arongranberg.com/astar/docs/callingpathfinding.html) Your browser does not support the video tag. Advantages * Picks a point and calculates a path in one go. * Every node that is considered has the same probability of being chosen; no bias towards being near obstacles like in [Method 1: Random point inside a circle](https://arongranberg.com/astar/docs/wander.html#method1) . * A minimum path cost can be set (searchLength). Disadvantages * Can be slow for long paths. * Does not work that well for navmesh/recast graphs as every node has the same probability of being chosen, which will cause a bias towards regions with a lot of detail (and thus more and smaller nodes). Misc * Takes penalties into account. See [Pathfinding.RandomPath](https://arongranberg.com/astar/docs/randompath.html) Method 4: The ConstantPath type ------------------------------- The ConstantPath type is a path type which will find **all** nodes which can be reached from the start point with a cost at most equal to a particular value. After all those nodes have been found, we can pick one or more random points on the surface of those nodes. `ConstantPath path = ConstantPath.Construct(transform.position, searchLength); [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[StartPath](https://arongranberg.com/astar/docs/astarpath/startpath.html#StartPath) (path); path.BlockUntilCalculated(); var singleRandomPoint = PathUtilities.GetPointsOnNodes(path.allNodes, 1)[0]; var multipleRandomPoints = PathUtilities.GetPointsOnNodes(path.allNodes, 100); `If you want to feed this to a built-in movement script, you can use the same approach as in [Method 1: Random point inside a circle](https://arongranberg.com/astar/docs/wander.html#method1) . Your browser does not support the video tag. See [Pathfinding.ConstantPath](https://arongranberg.com/astar/docs/constantpath.html) [Pathfinding.PathUtilities.GetPointsOnNodes](https://arongranberg.com/astar/docs/pathutilities/getpointsonnodes.html#GetPointsOnNodes) Advantages * Can pick multiple random points with just a single path request. * The probability of choosing a node is proportional to its surface area (so if all nodes have the same size, e.g., when using a grid graph, then every node that is considered has the same probability of being chosen). There is no bias towards being near obstacles like in [Method 1: Random point inside a circle](https://arongranberg.com/astar/docs/wander.html#method1) . * Possible to do custom filtering of the nodes afterwards if that should be necessary. * Usually slightly faster than [Method 3: The RandomPath type](https://arongranberg.com/astar/docs/wander.html#method2) . * Works reasonably well for navmesh/recast graphs. Disadvantages * Can be slow when having to search a lot of nodes. Misc * Takes penalties into account. Method 5: Breadth-first search ------------------------------ A [breadth-first search](https://en.wikipedia.org/wiki/Breadth-first_search) is a simple search that searches outwards from the starting node a single node at a time. It doesn't take penalties or any other types of costs into account. This means, for example, that moving diagonally on a grid graph has the same cost as moving along one of the 4 non-diagonal connections. The way you use it is very similar to what is done in [Method 4: The ConstantPath type](https://arongranberg.com/astar/docs/wander.html#method3) . `// Find closest walkable node var startNode = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (transform.position, NearestNodeConstraint.Walkable).node; var nodes = PathUtilities.BFS(startNode, nodeDistance); var singleRandomPoint = PathUtilities.GetPointsOnNodes(nodes, 1)[0]; var multipleRandomPoints = PathUtilities.GetPointsOnNodes(nodes, 100); `If you want to feed this to a built-in movement script, you can use the same approach as in [Method 1: Random point inside a circle](https://arongranberg.com/astar/docs/wander.html#method1) . Your browser does not support the video tag. See [Pathfinding.PathUtilities.BFS](https://arongranberg.com/astar/docs/pathutilities/bfs.html#BFS) [Pathfinding.PathUtilities.GetPointsOnNodes](https://arongranberg.com/astar/docs/pathutilities/getpointsonnodes.html#GetPointsOnNodes) Advantages * Can pick multiple random points, not just one. * The probability of choosing a node is proportional to its surface area (so if all nodes have the same size, e.g., when using a grid graph, then every node that is considered has the same probability of being chosen). There is no bias towards being near obstacles like in [Method 1: Random point inside a circle](https://arongranberg.com/astar/docs/wander.html#method1) . * Possible to do custom filtering of the nodes afterwards if that should be necessary. * No round trip to the pathfinding system necessary, which can save some overhead. * Usually slightly faster than [Method 4: The ConstantPath type](https://arongranberg.com/astar/docs/wander.html#method3) and [Method 3: The RandomPath type](https://arongranberg.com/astar/docs/wander.html#method2) . Disadvantages * Can be slow when having to search a lot of nodes. * Does not use the pathfinding threads, so you lose the ability to easily offload it from the main Unity thread. * Does not work particularly well for navmesh/recast graphs as the paths will have a large variation in length depending on the detail of the navmesh (more and smaller nodes means the BFS will not reach as far). Misc * Does not take penalties or any other costs into account; only the number of nodes traversed is relevant. --- # Multiple agent types - A* Pathfinding Project Multiple agent types ==================== This page explains how to handle different agent types, such as agents of different sizes. When you have agents of different sizes, they usually cannot take the same routes to the target. Fortunately, it is easy to solve this problem. The easiest way is to create multiple graphs, one for each type of agent. If you have a lot of different agent types, or perhaps even a continuous spectrum, you may want to group them as having a large number of graphs will increase memory usage and scanning will take longer. On the [Seeker](https://arongranberg.com/astar/docs/seeker.html) component it is possible to set which graphs that the Seeker can use. See [Seeker.graphMask](https://arongranberg.com/astar/docs/seeker.html#graphMask) [TraversalConstraint.graphMask](https://arongranberg.com/astar/docs/traversalconstraint.html#graphMask) For grid graphs, there are also two additional methods that can be used; they are explained in the [Other approaches for grid graphs](https://arongranberg.com/astar/docs/multipleagenttypes.html#grid-shape) section. Example ------- Let's say we have these two agents: ![](https://arongranberg.com/astar/docs/images/multiple_agents/agents.png) In the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) inspector we can then create 2 different graphs, with the only difference being the character radius that is used (any other parameters can of course be changed if necessary). In this example, a recast graph has been used, but this can just as easily be done with another graph type. | | | | --- | --- | | ![](https://arongranberg.com/astar/docs/images/multiple_agents/small_graph@2x.png) | ![](https://arongranberg.com/astar/docs/images/multiple_agents/large_graph@2x.png) | When scanning these graphs we will get a result that looks something like this. With the graph for the smaller agent in blue and the graph for the larger agent in purple (depending on your graph coloring settings, the colors may differ). ![](https://arongranberg.com/astar/docs/images/multiple_agents/graph_visualization.png) On the Seeker component we can then set which graph each agent should use: ![](https://arongranberg.com/astar/docs/images/multiple_agents/seeker.png) Now both agents will use graphs appropriate for their size: Your browser does not support the video tag. Other approaches for grid graphs -------------------------------- As an alternative method on grid graphs, it is possible to make the graph generate different [tags](https://arongranberg.com/astar/docs/tags.html) depending on the distance to the nearest obstacle. This only requires a single graph. See [Pathfinding.GridGraph.erosionUseTags](https://arongranberg.com/astar/docs/gridgraph.html#erosionUseTags) There is also another approach that is very flexible, but unfortunately has a higher computational cost. For a path request, one can supply an [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) object (see also this tutorial: [Agent-Specific Pathfinding](https://arongranberg.com/astar/docs/traversal_provider.html) ) which allows your code to determine exactly which nodes should not be traversable. Using this, we can add custom code to, instead of just checking if the current node is traversable, check all nodes around it as well in, for example, a 3x3 or 5x5 square (with the default being equivalent to a 1x1 square). In the below image, you can see it used with a 3x3 square. Note that it does not want to traverse the nodes right next to obstacles even though they are walkable, because it checks in a 3x3 square around it. ![](https://arongranberg.com/astar/docs/images/grid_shape_traversal.png) The major advantage of the ITraversalProvider approach is that it will handle all things that can make a node not be traversable. For example, you might use different tags to restrict agent movement; however, even if you use multiple graphs, the different agents will still be able to walk right up to a region that is not traversable because of its tag, even if the agent has a very large size. With this approach, it will not be able to move as close to it because the nodes with another tag will be detected as not traversable and the NxN nodes around the agent must all be traversable. The ITraversalProvider can be implemented like this: `class GridShapeTraversalProvider : ITraversalProvider { Vector2Int[] shape; public static GridShapeTraversalProvider SquareShape (int width) { if ((width % 2) != 1) throw new System.ArgumentException("only odd widths are supported"); var shape = new GridShapeTraversalProvider(); shape.shape = new Vector2Int[width*width]; // Create an array containing all integer points within a width*width square int i = 0; for (int x = -width/2; x <= width/2; x++) { for (int z = -width/2; z <= width/2; z++) { shape.shape[i] = new Vector2Int(x, z); i++; } } return shape; } public bool CanTraverse (ref TraversalConstraint traversalConstraint, GraphNode node) { GridNodeBase gridNode = node as GridNodeBase; // Don't do anything special for non-grid nodes if (gridNode == null) return true; int x0 = gridNode.XCoordinateInGrid; int z0 = gridNode.ZCoordinateInGrid; var grid = gridNode.Graph as GridGraph; // Iterate through all the nodes in the shape around the current node // and check if those nodes are also traversable. // Skip the user filter (this ITraversalProvider) since that will just lead to infinite recursion. for (int i = 0; i < shape.Length; i++) { var inShapeNode = grid.GetNode(x0 + shape[i].x, z0 + shape[i].y); if (inShapeNode == null || !traversalConstraint.CanTraverseSkipUserFilter(inShapeNode)) return false; } return true; } public float GetTraversalCostMultiplier (ref TraversalCosts traversalCosts, GraphNode node) { // Use the default traversal cost. // Optionally this could be modified to e.g taking the average of the costs inside the shape. return DefaultITraversalProvider.GetTraversalCostMultiplier(ref traversalCosts, node); } } ` Note This implementation only works for grid graphs, not layered grid graphs and can be used like this `ABPath path = ABPath.Construct(currentPosition, destination, null); path.traversalConstraint.traversalProvider = GridShapeTraversalProvider.SquareShape(3); // If you are writing your own movement script seeker.StartPath(path); // If you are using an existing movement script (you may also want to set ai.canSearch to false) // ai.SetPath(path); `Note that a drawback with both of the grid-specific approaches is that if you happen to try to request a path to a destination that cannot be reached, then the path will fail completely instead of making the AI move to the closest point it could get. You can solve this for some cases by setting the [calculatePartial](https://arongranberg.com/astar/docs/abpath.html#calculatePartial) field to true before you start calculating the path: `path.calculatePartial = true; `This will make it go to the closest node it can get to as long as the target node is a traversable node according to the ITraversalProvider. --- # Recast graph in a 2D game - A* Pathfinding Project Recast graph in a 2D game ========================= Example scene which demonstrates a recast graph in a 2D level. ![](https://arongranberg.com/astar/docs/images/generated/scenes/Recast2D/overview.png) This example shows how to use a recast graph in a 2D level, utilizing both sprites and tilemaps. You can click to move the character around in the scene. Contents -------- * [Graph setup](https://arongranberg.com/astar/docs/example_recast2d.html#example_recast2d_graph) * [Tilemaps](https://arongranberg.com/astar/docs/example_recast2d.html#example_recast2d_graph_tilemaps) * [Door](https://arongranberg.com/astar/docs/example_recast2d.html#example_recast2d_door) * [Chest](https://arongranberg.com/astar/docs/example_recast2d.html#example_recast2d_chest) * [Character animation](https://arongranberg.com/astar/docs/example_recast2d.html#exampl_recast2d_character_animation) Graph setup ----------- ![](https://arongranberg.com/astar/docs/images/generated/scenes/Recast2D/graphsettings@2x.png) To use a recast graph in 2D mode, the dimensions field is changed to "2D". Additionally, the [RecastGraph.rasterizeColliders](https://arongranberg.com/astar/docs/recastgraph.html#rasterizeColliders) option must be enabled, as in 2D mode, the recast graph can only rasterize colliders, not meshes. After the graph has been oriented correctly and dimensioned to fit the scene, the graph can be scanned. The most notable changes that have been made to the graph configuration are: * The graph has been changed to 2D mode. * The cell size of the graph has been reduced a bit to make it represent the world more accurately. * The character radius has also been changed to reflect the size of the agents that will be used in the scene. * The bounding box of the graph has been changed to fit the world. * The graph has been changed to rasterize colliders, instead of meshes, which is the default. * The 'Background Traversability' setting on the recast graph has been set to "Walkable". This is because we want everything that is not an obstacle to be walkable. ### Tilemaps Tilemaps are supported by the recast graph as long as you attach a TilemapCollider2D component to the tilemap GameObject, and the object is included in the recast graph's layer mask. See [Tilemaps and Recast Graph](https://arongranberg.com/astar/docs/tilemaps.html#tilemaps_recast_graph) Door ---- Your browser does not support the video tag. There's a door that can be opened by clicking on the red button connected to it. This will move the agent there and play an animation that opens the door. The logic is handled by the [Interactable](https://arongranberg.com/astar/docs/interactable.html) component. It will first move the agent to the button, and then play the animation on the door. ![](https://arongranberg.com/astar/docs/images/generated/scenes/Recast2D/doorinteractable@2x.png) The opening animation will disable the collider on the door, and this will, in turn, make the [DynamicObstacle](https://arongranberg.com/astar/docs/dynamicobstacle.html) component (also attached to the door) recalculate the graph around the door from scratch. Chest ----- Your browser does not support the video tag. There's a chest that can be opened by clicking on it. This will move the agent there and play an animation that opens the chest. Chests are described in more detail in [Chests](https://arongranberg.com/astar/docs/example_recast3d.html#example_recast3d_chests) . Character animation ------------------- The character animation is handled by the [MecanimBridge2D](https://arongranberg.com/astar/docs/mecanimbridge2d.html) script. ![](https://arongranberg.com/astar/docs/images/generated/scenes/Recast2D/mecanimbridge2d@2x.png) velocitySmoothing How much to smooth the velocity of the agent. The velocity will be smoothed out over approximately this number of seconds. A value of zero indicates no smoothing. See This setting corresponds to the member [MecanimBridge2D.velocitySmoothing](https://arongranberg.com/astar/docs/mecanimbridge2d.html#velocitySmoothing) naturalSpeed The natural movement speed is the speed that the animations are designed for. One can for example configure the animator to speed up the animation if the agent moves faster than this, or slow it down if the agent moves slower than this. See This setting corresponds to the member [MecanimBridge2D.naturalSpeed](https://arongranberg.com/astar/docs/mecanimbridge2d.html#naturalSpeed) rotationMode How the agent's rotation is handled. See [RotationMode](https://arongranberg.com/astar/docs/mecanimbridge2d.html#RotationMode) See This setting corresponds to the member [MecanimBridge2D.rotationMode](https://arongranberg.com/astar/docs/mecanimbridge2d.html#rotationMode) For this agent, we set the rotation mode to **Hide**, because we don't want the agent's transform to rotate. Instead, different sprites are used to indicate which direction the agent is facing. The [MecanimBridge2D](https://arongranberg.com/astar/docs/mecanimbridge2d.html) script will forward the movement velocity to the animator component using the following animator parameters: * **InputMagnitude:** Movement speed, normalized by the agent's natural speed. 1 if the agent is moving at its natural speed, and 0 if it is standing still. * **X:** Horizontal movement speed, normalized by the agent's natural speed. * **Y:** Vertical movement speed, normalized by the agent's natural speed. In the animator controller, the root has two states: **Moving** and **Idle**. These are two blend trees that are transitioned between, depending on if the **InputMagnitude** is high enough. ![](https://arongranberg.com/astar/docs/images/scenes/Recast2D/character_animation_root.png) The **Moving** blend tree blends between different animations depending on the **X** and **Y** parameters. Each animation plays back a sequence of sprites to animate the character. When Unity blends between the clips, it will use the sprite which is given the highest weight in the blend tree. The **Moving** blend tree is also configured to multiply its speed by the **InputMagnitude** parameter, so that the animation will play faster or slower depending on how fast the agent is moving. ![](https://arongranberg.com/astar/docs/images/scenes/Recast2D/character_animation.png) The **Idle** blend tree looks much the same, except that the animations are different. --- # BBTree - A* Pathfinding Project Struct BBTree Extends IDisposable ================================= Public Axis Aligned Bounding Box Tree. Holds a bounding box tree of triangles. Inner Types ----------- [BBTreeBox](https://arongranberg.com/astar/docs/bbtreebox.html) [CloseNode](https://arongranberg.com/astar/docs/closenode.html) [NearbyNodesIterator](https://arongranberg.com/astar/docs/nearbynodesiterator.html) [ProjectionParams](https://arongranberg.com/astar/docs/projectionparams.html) Public Methods -------------- [BBTree](https://arongranberg.com/astar/docs/bbtree/bbtree.html#BBTree) (triangles, vertices) Build a [BBTree](https://arongranberg.com/astar/docs/bbtree.html) from a list of triangles. [Dispose](https://arongranberg.com/astar/docs/bbtree/dispose.html#Dispose) () [DistanceSqrLowerBound](https://arongranberg.com/astar/docs/bbtree/distancesqrlowerbound.html#DistanceSqrLowerBound) (p, projection) [DrawGizmos](https://arongranberg.com/astar/docs/bbtree/drawgizmos.html) (draw, \[boxi, depth\]) [QueryClosest](https://arongranberg.com/astar/docs/bbtree/queryclosest.html#QueryClosest) (p, constraint, projection, distanceSqr, previous, nodes, triangles, vertices) Queries the tree for the closest node to **p** constrained by the [NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) trying to improve an existing solution. Public Static Methods --------------------- [Build](https://arongranberg.com/astar/docs/bbtree/build.html#Build) (triangles, vertices, bbTree) [BuildSubtree](https://arongranberg.com/astar/docs/bbtree/buildsubtree.html#BuildSubtree) (permutation, nodeBounds, nodes, tree, from, to, odd, depth) [NodeBounds](https://arongranberg.com/astar/docs/bbtree/nodebounds.html#NodeBounds) (permutation, nodeBounds, from, to) Calculates the bounding box in XZ space of all nodes between **from** (inclusive) and **to** (exclusive) [SplitByX](https://arongranberg.com/astar/docs/bbtree/splitbyx.html#SplitByX) (nodesBounds, permutation, from, to, divider) [SplitByZ](https://arongranberg.com/astar/docs/bbtree/splitbyz.html#SplitByZ) (nodesBounds, permutation, from, to, divider) Public Variables ---------------- Size Public ##### [IntRect](https://arongranberg.com/astar/docs/intrect.html) Size nodePermutation Public ##### UnsafeList nodePermutation tree Holds all tree nodes. Public ##### UnsafeList<[BBTreeBox](https://arongranberg.com/astar/docs/bbtreebox.html) \> tree Holds all tree nodes. Public Static Variables ----------------------- MAX\_TREE\_HEIGHT Public Static ##### const int MAX\_TREE\_HEIGHT = 26 MaximumLeafSize Public Static ##### const int MaximumLeafSize = 4 Public Enums ------------ DistanceMetric Public ##### DistanceMetric | | | | --- | --- | | Euclidean | | | ScaledManhattan | | --- # Recast graph with off-mesh links - A* Pathfinding Project Recast graph with off-mesh links ================================ Example scene which demonstrates off-mesh links. Your browser does not support the video tag. Overview -------- This scene demonstrates how to use off-mesh links to implement special movement logic such as jumping, climbing, teleporters and other things. This example scene is the basis for the [Off-mesh links](https://arongranberg.com/astar/docs/offmeshlinks2.html) tutorial, so check that page for more details. In the example scene, the agent can: * Jump off a ledge. * Jump up to a ledge. * Open a door. * Use a teleporter to shorten its path. * Open an interactable chest. See [Chests](https://arongranberg.com/astar/docs/example_recast3d.html#example_recast3d_chests) for more details. See [Off-mesh links](https://arongranberg.com/astar/docs/offmeshlinks2.html) Graph setup ----------- This example uses a recast graph. A grid graph could also have been used with pretty much identical results, though some things would require modification. For example, the door uses a [NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) component, which only works on recast/navmesh graphs. --- # Infinite procedurally generated world - A* Pathfinding Project Infinite procedurally generated world ===================================== Example scene which demonstrates how to make a graph follow the player around in an infinite world. ![](https://arongranberg.com/astar/docs/images/generated/scenes/InfiniteWorld/overview.png) Your browser does not support the video tag. Your browser does not support the video tag. Contents -------- * [Graph setup](https://arongranberg.com/astar/docs/example_infinite_world.html#example_infinite_world_graph) * [Procedural world generation](https://arongranberg.com/astar/docs/example_infinite_world.html#_example_infinite_world_procedural) Graph setup ----------- ![](https://arongranberg.com/astar/docs/images/generated/scenes/InfiniteWorld/graphsettings@2x.png) This example uses a smallish grid graph which follows the player around. In an infinite world, one cannot generate the whole graph at once, so instead we only generate a graph around the player and then move it as the player moves. We ensure that the graph has enough resolution to represent the obstacles in the world, and that it is large enough to cover a decent sized area around the player. A smaller graph would result in less overhead as it moves, but then the player would not be able to plan paths around large obstacles. See You can read more about this in the tutorial [Large worlds](https://arongranberg.com/astar/docs/largeworlds.html) . Note When testing how well the scene performs, make sure that you hide the graph visualization, as updating the graph visualization can be much slower than updating the graph itself. Procedural world generation --------------------------- The **ProceduralWorld** GameObject contains the configuration for the world generation. The [ProceduralWorld](https://arongranberg.com/astar/docs/proceduralworld.html) component is a simple script based on [perlin noise](https://en.wikipedia.org/wiki/Perlin_noise) , which it uses to randomly place trees, bushes and rocks in the world. As the player moves around, it will also remove old objects behind the player and add new ones in front of the player. In a nutshell, what it does is generate a grid of tiles, and inside each tile it generates a number of objects based on the perlin noise density. The perlin noise can be scaled up to produce smoother variations in the number of objects, or scaled down to produce noisier variations. This kind of noise-based world generation algorithm is used in many games (e.g., Minecraft) to generate terrain and other objects in the world. Though, in a real game these algorithms are often much more complex and have more features, like caves, rivers, biomes, etc. --- # BoxWithDist - A* Pathfinding Project Struct BoxWithDist ================== Public Public Variables ---------------- distSqr Public ##### float distSqr index Public ##### int index --- # Saving and Loading Graphs - A* Pathfinding Project Saving and Loading Graphs ========================= How to precalculate graphs and store that data. All graphs can be saved and loaded from files. This is actually what the editor does all the time; barely any Unity serialization is used. Instead, all graph settings are serialized and stored in a byte array. However, not only settings can be saved. Once calculated, a graph can save all nodes to a compact byte array representation, which can then be saved to a file and loaded somewhere else. In the A\* inspector, under the Save & Load tab, there are two buttons named "Save to file" and "Load from file". These can be used to save and load graph files. Caching Graph Calculation ------------------------- Recalculating the graphs at startup is usually what you want, but sometimes - especially if you are using the RecastGraph or developing for mobile - the lag at the start can get very annoying. It might also be the case that you cannot calculate the graph at startup for some reason. In that case, graph caching is great. It enables you to scan the graph in the editor and save it to an external file which will be loaded at startup. It is a lot faster than scanning the graphs in most cases and you know exactly how the graph will look. To create a cache, open the Save & Load tab in the A\* inspector and click Generate Cache. It will also ask you if you want to rescan the graph before saving. Now the graph you saved will be loaded with all node info intact at startup, with no calculation time necessary. ![](https://arongranberg.com/astar/docs/images/inspector/saveloadtab@2x.png) Saving Graphs to File and Loading them -------------------------------------- You might also want to save the graphs to a file which you can load later. You can even load it during runtime from a server, for example. If you want to save your graphs, open the Save & Load tab, and click the Save to file button. You can either include only the settings, or include settings as well as node data. If you only include settings, then after the graph has been loaded, you will need to recalculate it before any characters can use it for navigation. You can recalculate all graphs using: `[AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) (); `When you want to load the graphs again, simply press the Load from file button and locate the file. Note that this will replace your current graphs. ### Loading and Saving using Code If you want to load or save graphs during runtime, you cannot use the editor interface for obvious reasons. There is an easy-to-use API for saving and loading files. This will serialize graph settings to a byte array. By default, only settings are included. `byte[] bytes = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .SerializeGraphs(); `If you want to save node data too, then call: `byte[] bytes = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .SerializeGraphs([Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) .[Serialization](https://arongranberg.com/astar/docs/serialization.html) .[SerializeSettings](https://arongranberg.com/astar/docs/serializesettings.html) .[NodesAndSettings](https://arongranberg.com/astar/docs/serializesettings.html#NodesAndSettings) ); `To load the saved data you can call: `[AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .DeserializeGraphs(bytes); `If you only load settings, you may want to call Scan after you have loaded the settings: `[AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .DeserializeGraphs(bytes); [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) (); ` ### Additive Loading Instead of replacing the currently loaded graphs, you can additively load graphs using `[AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .DeserializeGraphsAdditive(bytes); `You can unload graphs using `var data = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) ; var myGraph = data.gridGraph; data.RemoveGraph(myGraph); ` ### Including Data in a TextAsset Graph data can be included in textassets for easier inclusion in the build. When you have saved the data to a file, rename that file to something like "myGraph.bytes" and place it in your Unity Project. This will tell Unity to handle it as binary information. With an extension like .txt, the data would get corrupted because Unity would try to read it as text. Some operating systems like to hide the extension, so if Unity doesn't seem to recognize the file with the .bytes extension, make sure it really has a .bytes extension; the .zip (or other) extension might just be hidden. Then you can load the graph from a text asset by referencing it in a variable, and accessing the .bytes field. `using UnityEngine; using System.Collections; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) ; public class TestLoader : MonoBehaviour { public TextAsset graphData; // Load the graph when the game starts void Start () { [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .DeserializeGraphs(graphData.bytes); } } ` Internal Data Structure ----------------------- All settings are serialized to JSON. This is a good way to keep it forwards and backwards compatible. All files referred to below are compressed into a single zip file to make the size smaller and make it easier to handle the data. This means you can actually open the zip file and edit the settings manually. ![](https://arongranberg.com/astar/docs/images/serializedInternal.png) Note Many of the files mentioned below are not always included in the zip. If it is determined that a file would not contain any relevant information (such as saving user created connections, but no connections have been created), it is left out. Meta ---- A meta.json file is present in all serializations. This file contains information which is not connected to a specific graph, or is needed to load the other graphs. The meta file contains: * Version number for the system * Number of graphs which are saved * GUID values for each graph, to identify them * Type of each graph Below is an example of a meta.json file: `{ "version": "3.0.9.5", "graphs": 1, "guids": [ "0d83c93fc4928934-8362a8662ec4fb9d" ], "typeNames": [ "Pathfinding.GridGraph" ] } ` Graph Settings -------------- Settings for each graph are stored as "graph#.json" where # is the graph number. Here is an example of serialized settings for a grid graph (with some settings removed to keep the length down): `{ "aspectRatio":1, "rotation":{ "x":0, "y":0, "z":0 }, "center":{ "x":0, "y":-0.1, "z":0 }, "unclampedSize":{ "x":100, "y":100 }, "nodeSize":1, "maxClimb":0.4, "maxClimbAxis":1, "maxSlope":90, "erodeIterations":0, "autoLinkGrids":false, "autoLinkDistLimit":10, "neighbours":"Eight", "cutCorners":true, "penaltyPositionOffset":0, "penaltyPosition":false, "penaltyPositionFactor":1, "penaltyAngle":false, "penaltyAngleFactor":100, "open":true, "infoScreenOpen":false ... } ` Node information (if included in the serialized data) would take too much space to be included as JSON; instead, it is written as binary data. Each graph type has its own code for serializing node data. This is handled by the SerializeExtraInfo and DeserializeExtraInfo methods on each graph. ### User Created Connections If you use any [NodeLink2](https://arongranberg.com/astar/docs/nodelink2.html) components in the scene, keep in mind that they are not serialized with the graph data. If you want to preserve them, you will have to save them separately. --- # Working with tags - A* Pathfinding Project Working with tags ================= Explains how tags can be used to restrict and influence where different agents can walk. Contents -------- * [Introduction](https://arongranberg.com/astar/docs/tags.html#tags-intro) * [Examples](https://arongranberg.com/astar/docs/tags.html#tags-examples) * [How to apply tags](https://arongranberg.com/astar/docs/tags.html#tags-howto) * [How to make agents use tags](https://arongranberg.com/astar/docs/tags.html#tags-pathfinding-settings) * [Setting tag preferences in code](https://arongranberg.com/astar/docs/tags.html#tags-path-settings) * [Visualizing tags](https://arongranberg.com/astar/docs/tags.html#tags-visualize) * [Performance implications](https://arongranberg.com/astar/docs/tags.html#tags-performance) * [Separating large regions by non-traversable tags](https://arongranberg.com/astar/docs/tags.html#tags-performance-floodfill) * [Higher pathfinding cost for larger traversal costs](https://arongranberg.com/astar/docs/tags.html#tags-performance-costs) * [More control](https://arongranberg.com/astar/docs/tags.html#tags-more-control) Introduction ------------ Tagging nodes and regions is a powerful feature. It is used to restrict which agents can walk on what ground, or how costly different types of ground are to walk on for different agents. Imagine, for example, that you have some critters, a player, and some AIs in your world. Both the AIs and the critters pathfind randomly around in the world, but you wouldn't want the critters to enter houses (they make such a mess). Tagging is a great way to solve this. You can tag all indoor areas with a tag named "Indoors" and make sure no critters can walk on those nodes by changing their pathfinding settings. Your browser does not support the video tag. In the video, the blue agent will avoid the black region as it has been configured with a high cost for traversing it. Instead, it takes a short detour via the corridor to the right. The red agent, however, has no such restrictions, so it can walk through the black region without issue. Examples -------- Tags are demonstrated in the following example scenes: * [Recast graph with tags](https://arongranberg.com/astar/docs/example_recast_tags.html) * [Recast graph on a terrain](https://arongranberg.com/astar/docs/example_recast_terrain.html) How to apply tags ----------------- Each node, wheather it is a grid node, a point node, or a navmesh node, has a tag. By default, all nodes have tag 0 (called "Basic Ground", if you haven't changed it). You can apply tags to nodes in several ways. Here they are listed in rough order of preference: * Using the grid graph rule [RulePerLayerModifications](https://arongranberg.com/astar/docs/ruleperlayermodifications.html) , which allows you to apply a tag to ground objects in a specific layer. * Using the recast graph's [per layer modifications](https://arongranberg.com/astar/docs/recastgraph.html#perLayerModifications) setting, which allows you to apply tags to objects in specific layers. * Using the recast graph's [per terrain layer modifications](https://arongranberg.com/astar/docs/recastgraph.html#perTerrainLayerModifications) setting, which allows you to apply tags to specific textures painted on a terrain. * Using the [RecastNavmeshModifier](https://arongranberg.com/astar/docs/recastnavmeshmodifier.html) component, which allows you to modify the tags of nodes on specific meshes. Only works for recast graphs. * Using the [GraphUpdateScene](https://arongranberg.com/astar/docs/graphupdatescene.html) component, which allows you to modify the tags of nodes inside a polygon. * Using the [AstarPath.active.UpdateGraphs](https://arongranberg.com/astar/docs/astarpath/updategraphs.html) method, which allows you to modify the tags of nodes in code, similar to how the [GraphUpdateScene](https://arongranberg.com/astar/docs/graphupdatescene.html) component works. * Directly modifying the tags of nodes in code, using the [GraphNode.Tag](https://arongranberg.com/astar/docs/graphnode.html#Tag) property. This is only recommended if none of the other options work well. See [Graph Updates during Runtime](https://arongranberg.com/astar/docs/graphupdates.html) for more details on how to update graphs. How to make agents use tags --------------------------- Agents will, by default, not care about tags. To make them treat different tags in different ways you'll need to to expand the Seeker → Tags foldout, or if you are using the FollowerEntity component: FollowerEntity → Pathfinding → Tags foldout. It looks like this: ![](https://arongranberg.com/astar/docs/images/tagpopup@2x.png) Here you can select which tags the agent should be able to traverse, and if they should have any costs associated with them. Note If you are using a recast or navmesh graph, the "Cost Per Node" column will be hidden, since it is not particularly useful for those graphs. The default cost of moving 1 world unit is 1000, so if you want to, for example, make a tag that is 2x or 3x as costly to traverse, you can set the "Cost per world unit" for that tag to 2000 or 3000. Since these settings are per-agent, you can have different agents traverse the same tags in different ways. ### Setting tag preferences in code If you want to set tag settings for an agent via code, you can use: **Seeker** * [Seeker.traversableTags](https://arongranberg.com/astar/docs/seeker.html#traversableTags) * [Seeker.tagCostMultipliers](https://arongranberg.com/astar/docs/seeker.html#tagCostMultipliers) * [Seeker.tagEntryCosts](https://arongranberg.com/astar/docs/seeker.html#tagEntryCosts) **FollowerEntity** * [FollowerEntity.pathfindingSettings.traversableTags](https://arongranberg.com/astar/docs/pathrequestsettings.html#traversableTags) * [FollowerEntity.pathfindingSettings.tagCostMultipliers](https://arongranberg.com/astar/docs/pathrequestsettings.html#tagCostMultipliers) * [FollowerEntity.pathfindingSettings.tagEntryCosts](https://arongranberg.com/astar/docs/pathrequestsettings.html#tagEntryCosts) **Custom path request** * [Path.traversalConstraint.tags](https://arongranberg.com/astar/docs/traversalconstraint.html#tags) * [Path.traversalCosts.tagCostMultipliers](https://arongranberg.com/astar/docs/traversalcosts.html#tagCostMultipliers) * [Path.traversalCosts.tagEntryCosts](https://arongranberg.com/astar/docs/traversalcosts.html#tagEntryCosts) Visualizing tags ---------------- ![](https://arongranberg.com/astar/docs/images/tag_graph_coloring@2x.png) You can visualize tags in the scene view by changing the debug mode to **Tags** in A\* Inspector → Settings → Debug → Graph Coloring (and make sure Show Graphs is toggled). The graph will be colored so that each tag gets a specific color, which allows you to easily see which nodes have which tags. ![](https://arongranberg.com/astar/docs/images/generated/scenes/RecastTags/overviewwithtagvisualization.png) In the image, you can see that most ground is grey (tag 0), but the corridors have different colors (meaning different tags), and there is a colored rectangle further away as well, which has yet another tag. If you want, you can tweak the tag colors in the A\* Inspector → Settings → Colors → Custom Area Colors section. ![](https://arongranberg.com/astar/docs/images/tagNames@2x.png) Tags can also be named under A\* Inspector → Settings → Tags. This allows you to more easily organize your tags. Performance implications ------------------------ Using tags typically has a very low performance overhead directly, but it can lead to performance cliffs in some situations. ### Separating large regions by non-traversable tags The package optimizes pathfinding by flood-filling areas of the graph, so that it can very quickly determine if a path exists between two points. This can only be done based on walkability, and not tags, however. This means that if you have two regions which are separated by a tag that an agent cannot traverse (for example, a door), but everything is otherwise walkable, they will be considered part of the same flood-filling area, or [connected component](https://en.wikipedia.org/wiki/Component_(graph_theory)) in graph theory terminology. If you try to find a path between two points in those regions, it will, correctly, not be able to find one, but it also cannot prove that no such path exists before it has searched every single node it can reach, and this can take a lot of time for large graphs. This is why it can sometimes be better to use two (or more) separate graphs instead of using tags. For example, if you have humans who walk on land, and ships which sail on water, it's much more reasonable to use two separate graphs for them, instead of using tags to restrict the humans to land and the ships to water. See [Multiple agent types](https://arongranberg.com/astar/docs/multipleagenttypes.html) for more information on how to use multiple graphs for different agent types. ### Higher pathfinding cost for larger traversal costs If you just use tags to apply costs to different areas, then you will not run into to the problem in the previous section. However, the pathfinding search may have to search more nodes when traversing costlier nodes, in order to guarantee an optimal path, which can lead to longer pathfinding times. ![](https://arongranberg.com/astar/docs/images/generated/scenes/TagSearchCost/cost1.png) Searched nodes with the default traversal cost per world unit of **1000**. ![](https://arongranberg.com/astar/docs/images/generated/scenes/TagSearchCost/cost2.png) Searched nodes with a traversal cost per world unit of **2000**. ![](https://arongranberg.com/astar/docs/images/generated/scenes/TagSearchCost/cost10.png) Searched nodes with a traversal cost per world unit of **10000**. Note You can check how long each pathfinding request takes by setting [AstarPath.logPathResults](https://arongranberg.com/astar/docs/astarpath.html#logPathResults) to Normal or higher in the A\* Inspector → Settings → Debug section. ![](https://arongranberg.com/astar/docs/images/path_logging@2x.png) More control ------------ If you feel like tags are a bit limiting, you can instead check out [The ITraversalProvider interface](https://arongranberg.com/astar/docs/traversal_provider.html#provider) , which allows full control over path costs and traversability. --- # Accessing graph data - A* Pathfinding Project Accessing graph data ==================== How to access graphs and nodes. All data in the graphs can be accessed. There are, for example, many cases where the API expects a GraphNode as a parameter, so you need to be able to find those. And there can be other cases where you need to extensively modify the graph data to suit your game. For example, you might have your own custom-made tilemap generator and you need to pass that data to the grid graph. See [Graph Updates during Runtime](https://arongranberg.com/astar/docs/graphupdates.html) . For info on how to search for nodes close to a point, take a look at [Using nodes](https://arongranberg.com/astar/docs/usingnodes.html) Accessing graphs ---------------- All graphs are stored in the [Pathfinding.AstarData](https://arongranberg.com/astar/docs/astardata.html) class. It contains an array with all the graphs and there are a bunch of convenience methods for finding graphs in it. The quickest way, however, is to use the shortcuts that are provided. For each type of built-in graph, there is a field which points to the first graph of that type. `GridGraph gridGraph = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .gridGraph; PointGraph pointGraph = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .pointGraph; NavMeshGraph navmeshGraph = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .navmeshGraph; RecastGraph recastGraph = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .recastGraph; LayerGridGraph layerGridGraph = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .layerGridGraph; NavGraph[] allGraphs = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .graphs; // You can set the name of a graph in the graph inspector var graph = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .FindGraph(g => g.name == "My Custom Graph Name"); ` Getting nodes in a graph ------------------------ The different graph types store their nodes in different ways. The grid graph, for example, stores all nodes in a huge array which can be indexed to easily get a node at a specific cell index. The recast graph stores all nodes in arrays in separate tiles. The generic, very high-level way to get all nodes in a graph is by using the GetNodes method which exists on all types of graphs. It takes a callback which will be invoked for each node. The reason it uses a callback instead of an iterator is because callbacks are significantly faster than iterators, and for large graphs that does make a difference. `var gg = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .gridGraph; gg.GetNodes(node => { // Here is a node Debug.Log("I found a node at position " + (Vector3)node.position); }); ` Warning Do not update the data in the nodes. This can interfere with pathfinding that might be running at the same time (especially if using multithreading). To safely update node data, you need to do that inside a safe callback. You can request a safe callback using [AstarPath.AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) . See [Graph Updates during Runtime](https://arongranberg.com/astar/docs/graphupdates.html) ### GridGraph Grid graph nodes are stored in [a large array](https://arongranberg.com/astar/docs/gridgraph.html#nodes) . It is indexed by the coordinates of the node so they can be accessed easily. There are also convenience methods for accessing the nodes: `var gg = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .gridGraph; int x = 5; int z = 8; GridNodeBase node = gg.GetNode(x, z); `There are some cases where you want to change the size of a grid graph during runtime. Then you can modify the unclampedSize field, which is the size of the grid in world units. Or you can use the SetDimensions method. After you have changed the width or depth of the graph, you need to recalculate it using [AstarPath.Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) . `var gg = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .gridGraph; var width = 80; var depth = 60; var nodeSize = 1.0f; gg.SetDimensions(width, depth, nodeSize); // Recalculate the graph [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) (); `It is also possible to move the grid graph without recalculating it using the [RelocateNodes](https://arongranberg.com/astar/docs/gridgraph/relocatenodes.html#RelocateNodes2) method. The same method is also available for other graphs, but then you have to calculate the necessary matrix yourself. ### Layered Grid Graph The layered grid graph works almost like the grid graph. However, since layered grid graphs can contain several layers, an additional layer coordinate is needed. `var gg = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .layerGridGraph; int x = 5; int z = 8; int layer = 0; GridNodeBase node = gg.GetNode(x, z, layer); ` ### NavmeshGraph/RecastGraph Recast graphs divide the nodes into a number of tiles. The individual tiles are stored in an array in the same way as the grid graph stores its nodes. Inside each tile, the nodes are stored in an array without any inherent order. However, all nodes are also added to an axis-aligned bounding box tree (AABB Tree) in order to be able to query for the closest node to a point in an efficient manner. Navmesh graphs work exactly the same as recast graphs; however, they always use a single tile. `var graph = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .recastGraph; int tileX = 5; int tileZ = 8; NavmeshTile tile = graph.GetTile(tileX, tileZ); for (int i = 0; i < tile.nodes.Length; i++) { // ... } // or you can access the nodes like this: tile.GetNodes(node => { // ... }); ` ### PointGraph Point graphs simply store the nodes in an array without any inherent order. Point graph nodes also contain a field for the GameObject they were created from (if any), which can be useful for all kinds of purposes. `var node = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (transform.position).node; var pointNode = node as PointNode; if (pointNode != null) { Debug.Log("That node was created from the GameObject named " + pointNode.gameObject.name); } else { Debug.Log("That node is not a PointNode"); } `You can also add nodes to a point graph during runtime: `[AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) (() => { var graph = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .pointGraph; // Add 2 nodes and connect them var node1 = graph.AddNode((Int3)transform.position); var node2 = graph.AddNode((Int3)(transform.position + Vector3.right)); var cost = (uint)(node2.position - node1.position).costMagnitude; GraphNode.Connect(node1, node2, cost); }); ` See [Graph Updates during Runtime](https://arongranberg.com/astar/docs/graphupdates.html) --- # NearbyNodesIterator - A* Pathfinding Project Struct NearbyNodesIterator Extends IEnumerator ========================================================= Public Inner Types ----------- [BoxWithDist](https://arongranberg.com/astar/docs/boxwithdist.html) Public Methods -------------- [Dispose](https://arongranberg.com/astar/docs/nearbynodesiterator/dispose.html#Dispose) () [MoveNext](https://arongranberg.com/astar/docs/nearbynodesiterator/movenext.html) (\[...\]) [Reset](https://arongranberg.com/astar/docs/nearbynodesiterator/reset.html#Reset) () Public Variables ---------------- Current Public ##### [CloseNode](https://arongranberg.com/astar/docs/closenode.html) Current Current Public ##### object Current distanceThresholdSqr Public ##### float distanceThresholdSqr indexInLeaf Public ##### int indexInLeaf nodes Public ##### [UnsafeSpan](https://arongranberg.com/astar/docs/unsafespan.html) nodes point Public ##### float3 point projection Public ##### [ProjectionParams](https://arongranberg.com/astar/docs/projectionparams.html) projection stack Public ##### [UnsafeSpan](https://arongranberg.com/astar/docs/unsafespan.html) <[BoxWithDist](https://arongranberg.com/astar/docs/boxwithdist.html) \> stack stackSize Public ##### int stackSize tieBreakingDistanceThreshold Public ##### float tieBreakingDistanceThreshold tree Public ##### [UnsafeSpan](https://arongranberg.com/astar/docs/unsafespan.html) <[BBTreeBox](https://arongranberg.com/astar/docs/bbtreebox.html) \> tree triangles Public ##### [UnsafeSpan](https://arongranberg.com/astar/docs/unsafespan.html) triangles vertices Public ##### [UnsafeSpan](https://arongranberg.com/astar/docs/unsafespan.html) <[Int3](https://arongranberg.com/astar/docs/int3.html) \> vertices Private/Protected Members ------------------------- current Internal ##### [CloseNode](https://arongranberg.com/astar/docs/closenode.html) current --- # TraversalCosts - A* Pathfinding Project Struct TraversalCosts ===================== Public Defines the cost of traversing specific nodes when pathfinding. To make agents avoid certain nodes, you can set a high penalty for traversing them. This will make the pathfinding algorithm prefer other nodes instead. You can set costs based on the node's tag, or you can use a custom traversal provider to set costs based on other criteria with completely custom logic. `var traversalCosts = new TraversalCosts(); // Make tags 1 and 4 have a higher penalty var [tagCostMultipliers](https://arongranberg.com/astar/docs/traversalcosts.html#tagCostMultipliers) = new float[32]; [tagCostMultipliers](https://arongranberg.com/astar/docs/traversalcosts.html#tagCostMultipliers) [1] = 2.5f; [tagCostMultipliers](https://arongranberg.com/astar/docs/traversalcosts.html#tagCostMultipliers) [4] = 5.0f; traversalCosts.tagCostMultipliers = [tagCostMultipliers](https://arongranberg.com/astar/docs/traversalcosts.html#tagCostMultipliers) ; var path = ABPath.Construct(Vector3.zero, Vector3.one); path.traversalCosts = traversalCosts; `**Traversal cost calculation** Assume we have a path with 3 nodes: A, B, and C. The path spends 1 meters inside node A, 3 meters inside node B, and 2 meters inside node C. The total cost of traversing the path is: `var totalCost = 0f; totalCost += costs.GetTraversalCostMultiplier(A) * 1000; // 1 meter in A totalCost += costs.GetConnectionCost(A, B); // cost of moving from A to B totalCost += costs.GetTraversalCostMultiplier(B) * 3000; // 3 meters in B totalCost += costs.GetConnectionCost(B, C); // cost of moving from B to C totalCost += costs.GetTraversalCostMultiplier(C) * 2000; // 2 meters in C `or, assuming no traversal provider is set: `var totalCost = 0f; totalCost += costs.tagCostMultipliers[A.Tag] * 1000; // 1 meter in A totalCost += costs.tagEntryCosts[B.Tag] + B.Penalty; // cost of moving from A to B totalCost += costs.tagCostMultipliers[B.Tag] * 3000; // 3 meters in B totalCost += costs.tagEntryCosts[C.Tag] + C.Penalty; // cost of moving from B to C totalCost += costs.tagCostMultipliers[C.Tag] * 2000; // 2 meters in C ` Note On navmesh/recast graphs, the distance the path moves inside each node (triangle) is approximated. It cannot be exactly calculated for performance reasons. Typically it averages out to around 10-20% higher than the actual distance. This is usually not a problem in practice, but you should keep this in mind and not rely on exact values. See [Working with tags](https://arongranberg.com/astar/docs/tags.html) [Agent-Specific Pathfinding](https://arongranberg.com/astar/docs/traversal_provider.html) [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) [PathfindingTag](https://arongranberg.com/astar/docs/pathfindingtag.html) [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint.html) [Path.traversalCosts](https://arongranberg.com/astar/docs/path.html#traversalCosts) Public Methods -------------- [GetConnectionCost](https://arongranberg.com/astar/docs/traversalcosts/getconnectioncost.html#GetConnectionCost) (from, to) Instantaneous cost for moving between **from** and **to**. [GetDefaultConnectionCost](https://arongranberg.com/astar/docs/traversalcosts/getdefaultconnectioncost.html#GetDefaultConnectionCost) (from, to) Cost for traversing the given node, ignoring any [traversalProvider](https://arongranberg.com/astar/docs/traversalcosts.html#traversalProvider) that may be set. [GetDefaultTraversalCostMultiplier](https://arongranberg.com/astar/docs/traversalcosts/getdefaulttraversalcostmul.html#GetDefaultTraversalCostMultiplier) (node) Like GetTraversalCostMultiplier, but ignores any [traversalProvider](https://arongranberg.com/astar/docs/traversalcosts.html#traversalProvider) that may be set. [GetTagEntryCost](https://arongranberg.com/astar/docs/traversalcosts/gettagentrycost.html#GetTagEntryCost) (tag) Cost for entering a node with the given tag. [GetTraversalCost](https://arongranberg.com/astar/docs/traversalcosts/gettraversalcost.html#GetTraversalCost) (node) Cost for traversing the given node. [GetTraversalCostMultiplier](https://arongranberg.com/astar/docs/traversalcosts/gettraversalcostmultiplier.html#GetTraversalCostMultiplier) (node) Multiplier for the cost of traversing some distance across the given node. Public Variables ---------------- hasCosts True if traversal costs might be non-default, and false if they are guaranteed to be default for all nodes. Public ##### bool hasCosts True if traversal costs might be non-default, and false if they are guaranteed to be default for all nodes. If false, then [GetTraversalCostMultiplier](https://arongranberg.com/astar/docs/traversalcosts/gettraversalcostmultiplier.html#GetTraversalCostMultiplier) will always return 1, and GetConnectionCost will always return the node's penalty. tagCostMultipliers Multiplier for the cost of moving some distance across a node with a given tag. Public ##### float\[\] tagCostMultipliers Multiplier for the cost of moving some distance across a node with a given tag. This will be multiplied by the traversed distance in millimeters (see [Int3.Precision](https://arongranberg.com/astar/docs/int3.html#Precision) ) to get the final cost. The default value is 1, which means that the cost will be the same as the distance. If you set this to 2, the cost will be twice as high as the distance. For example, moving 1 world unit across a node with tag 0 will cost 1000 \* tagCostMultipliers\[0\] units of movement cost. If null (the default), all tags will be treated as having a multiplier of 1. Note Prefer to make tags more costly (cost multiplier >1), rather than making them cheaper than the default (cost multiplier <1). If you set any cost multiplier to less than 1, you'll also need to reduce [AstarPath.heuristicScale](https://arongranberg.com/astar/docs/astarpath.html#heuristicScale) to the lowest cost multiplier that you use in the project, otherwise the pathfinding algorithm may not find the optimal path. Alternatively you could compensate with a higher [tagEntryCosts](https://arongranberg.com/astar/docs/traversalcosts.html#tagEntryCosts) value, so that the agent can never move to the target with a lower cost than the default. See [https://en.wikipedia.org/wiki/Admissible\_heuristic](https://en.wikipedia.org/wiki/Admissible_heuristic) . This array must be of length 32. In the inspector, this value is displayed as "Cost per world unit", and is shown as multiplied by 1000 ( [Int3.Precision](https://arongranberg.com/astar/docs/int3.html#Precision) ), to make it the cost per world unit. While in code, it is a multiplier of the default cost. ![](https://arongranberg.com/astar/docs/images/tagpopup@2x.png) `var traversalCosts = new TraversalCosts(); // Make tags 1 and 4 have a higher penalty var [tagCostMultipliers](https://arongranberg.com/astar/docs/traversalcosts.html#tagCostMultipliers) = new float[32]; [tagCostMultipliers](https://arongranberg.com/astar/docs/traversalcosts.html#tagCostMultipliers) [1] = 2.5f; [tagCostMultipliers](https://arongranberg.com/astar/docs/traversalcosts.html#tagCostMultipliers) [4] = 5.0f; traversalCosts.tagCostMultipliers = [tagCostMultipliers](https://arongranberg.com/astar/docs/traversalcosts.html#tagCostMultipliers) ; var path = ABPath.Construct(Vector3.zero, Vector3.one); path.traversalCosts = traversalCosts; ` See [TraversalCosts.GetTraversalCostMultiplier](https://arongranberg.com/astar/docs/traversalcosts/gettraversalcostmultiplier.html#GetTraversalCostMultiplier) [TraversalCosts.tagEntryCosts](https://arongranberg.com/astar/docs/traversalcosts.html#tagEntryCosts) [Seeker.tagCostMultipliers](https://arongranberg.com/astar/docs/seeker.html#tagCostMultipliers) [PathRequestSettings.tagCostMultipliers](https://arongranberg.com/astar/docs/pathrequestsettings.html#tagCostMultipliers) tagCostMultipliersInternal Public ##### float\[\] tagCostMultipliersInternal tagEntryCosts How much it costs to enter a node with a given tag. Public ##### uint\[\] tagEntryCosts How much it costs to enter a node with a given tag. This can be used to make agents avoid, or prefer, nodes with certain tags. For example, every time a path enters tag 0 (which is the default tag), it will cost an extra tagEntryCosts\[0\]. For most pathfinding purposes, you can think of this as just the additional cost of traversing a node with the given tag. The distinction between entering and exiting a node is a very small one, and will not make a difference in most cases. The index in the array corresponds to the tag. All entry costs are positive values since the A\* algorithm cannot handle negative costs. If null (the default), all tags will be treated as having an entry cost of zero. However, the path will still receive cost from the [tagCostMultipliers](https://arongranberg.com/astar/docs/traversalcosts.html#tagCostMultipliers) field. This cost will be applied for every node that is entered, regardless of if the previous node had the same tag or not. Note This array must be of length 32. `var traversalCosts = new TraversalCosts(); // Make tags 1 and 4 have a higher penalty var [tagEntryCosts](https://arongranberg.com/astar/docs/traversalcosts.html#tagEntryCosts) = new uint[32]; [tagEntryCosts](https://arongranberg.com/astar/docs/traversalcosts.html#tagEntryCosts) [1] = 1000; [tagEntryCosts](https://arongranberg.com/astar/docs/traversalcosts.html#tagEntryCosts) [4] = 20000; traversalCosts.tagEntryCosts = [tagEntryCosts](https://arongranberg.com/astar/docs/traversalcosts.html#tagEntryCosts) ; var path = ABPath.Construct(Vector3.zero, Vector3.one); path.traversalCosts = traversalCosts; `In the [Seeker](https://arongranberg.com/astar/docs/seeker.html) and [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) inspectors, this field (called "Cost per node") is hidden if your scene only contains navmesh/recast graphs, since using per-node costs on those graphs is not recommended due to the significant differences in node sizes and shapes that they have. Use [tagCostMultipliers](https://arongranberg.com/astar/docs/traversalcosts.html#tagCostMultipliers) instead. ![](https://arongranberg.com/astar/docs/images/tagpopup@2x.png) See [TraversalCosts.GetConnectionCost](https://arongranberg.com/astar/docs/traversalcosts/getconnectioncost.html#GetConnectionCost) [TraversalCosts.tagCostMultipliers](https://arongranberg.com/astar/docs/traversalcosts.html#tagCostMultipliers) [Working with tags](https://arongranberg.com/astar/docs/tags.html) tagEntryCostsInternal Public ##### uint\[\] tagEntryCostsInternal traversalProvider Traversal provider to forward all cost calculations to. Public ##### [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) traversalProvider Traversal provider to forward all cost calculations to. If not null, this will override the [GetTraversalCost](https://arongranberg.com/astar/docs/traversalcosts/gettraversalcost.html#GetTraversalCost) method's output completely. The traversal provider will be called for each node that is explored by a path search. --- # ITraversalProvider - A* Pathfinding Project Interface ITraversalProvider ============================ Public Provides additional traversal information to a path request. The [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) interface is something you can implement to be able to control exactly which nodes are traversable, how costly it is to traverse them, and how costly it is to traverse connections between nodes. This enables a lot of flexibility in how you can control pathfinding, and is useful for many different scenarios. For example, you can use it to: * Make some agents prefer to walk on roads, while others prefer grass. * Create restricted doors, which only some agents can pass through. * In a turn based game, add additional cost for moving across a river between two tiles. * Etc. Example implementation: `public class MyCustomTraversalProvider : ITraversalProvider { public bool [CanTraverse](https://arongranberg.com/astar/docs/itraversalprovider/cantraverse.html#CanTraverse) (ref TraversalConstraint traversalConstraint, GraphNode node) { // If, for example, your agents are afraid of heights, prevent your agents from going above 50 world units return ((Vector3)node.position).y < 50; } public bool [CanTraverse](https://arongranberg.com/astar/docs/itraversalprovider/cantraverse.html#CanTraverse) (ref TraversalConstraint traversalConstraint, GraphNode from, GraphNode to) { // Connections between nodes can be filtered too. // If you don't have any special rules for this, just forward the call to checking if the 'to' node is traversable. // (or just skip this method, as the default implementation will do the same) // We can, for example, prevent the agent from going directly from a node with tag 2 to a node with tag 3 if (from.Tag == 2 && to.Tag == 3) return false; return [CanTraverse](https://arongranberg.com/astar/docs/itraversalprovider/cantraverse.html#CanTraverse) (ref traversalConstraint, to); } public float [GetTraversalCostMultiplier](https://arongranberg.com/astar/docs/itraversalprovider/gettraversalcostmultip.html#GetTraversalCostMultiplier) (ref TraversalCosts traversalCosts, GraphNode node) { // For example, if your agent is afraid of heights, you can make nodes high up be 10 times more expensive to traverse if (((Vector3)node.position).y > 30) return 10.0f; return DefaultITraversalProvider.GetTraversalCostMultiplier(ref traversalCosts, node); } public uint [GetConnectionCost](https://arongranberg.com/astar/docs/itraversalprovider/getconnectioncost.html#GetConnectionCost) (ref TraversalCosts traversalCosts, GraphNode from, GraphNode to) { // The traversal cost is, by default, the sum of the penalty of the node's tag and the node's penalty return traversalCosts.GetTagEntryCost(to.Tag) + to.Penalty; // alternatively: // return DefaultITraversalProvider.GetConnectionCost(ref traversalCosts, from, to); } } `You can use it with a [Seeker](https://arongranberg.com/astar/docs/seeker.html) : `seeker.traversalProvider = new MyCustomTraversalProvider(); `Or with a [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) `followerEntity.pathfindingSettings.traversalProvider = new MyCustomTraversalProvider(); `Or with a path instance: `var path = ABPath.Construct(Vector3.zero, Vector3.one); var traversalProvider = new MyCustomTraversalProvider(); // Use the same provider for both traversability and costs path.traversalConstraint.traversalProvider = traversalProvider; path.traversalCosts.traversalProvider = traversalProvider; ` Warning Your implementation of this interface may be called from separate threads if pathfinding multithreading is enabled, or if you are using the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component. You must ensure that your implementation is thread-safe. It is recommended to make each [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) instance immutable, so that it can be shared between threads without any issues. Note The [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) may continue to be used by the movement script after the path has been calculated, in order to repair or simplify its path. See [Agent-Specific Pathfinding](https://arongranberg.com/astar/docs/traversal_provider.html) [Working with tags](https://arongranberg.com/astar/docs/tags.html) Public Methods -------------- [CanTraverse](https://arongranberg.com/astar/docs/itraversalprovider/cantraverse.html) (...) ... [GetConnectionCost](https://arongranberg.com/astar/docs/itraversalprovider/getconnectioncost.html#GetConnectionCost) (traversalCosts, from, to) Cost of entering a given node from another node. [GetTraversalCostMultiplier](https://arongranberg.com/astar/docs/itraversalprovider/gettraversalcostmultip.html#GetTraversalCostMultiplier) (traversalCosts, node) Multiplier for the cost of traversing some distance across the given node. Public Variables ---------------- filterDiagonalGridConnections Filter diagonal connections using [GridGraph.cutCorners](https://arongranberg.com/astar/docs/gridgraph.html#cutCorners) for effects applied by this [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) . Public ##### bool filterDiagonalGridConnections Filter diagonal connections using [GridGraph.cutCorners](https://arongranberg.com/astar/docs/gridgraph.html#cutCorners) for effects applied by this [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) . This includes tags and other effects that this [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) controls. This only has an effect if [GridGraph.cutCorners](https://arongranberg.com/astar/docs/gridgraph.html#cutCorners) is set to false and your grid has [GridGraph.neighbours](https://arongranberg.com/astar/docs/gridgraph.html#neighbours) set to Eight. Take this example, the grid is completely walkable, but an [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) is used to make the nodes marked with '#' as unwalkable. The agent 'S' is in the middle. `.......... ....#..... ...#S#.... ....#..... .......... ` If **filterDiagonalGridConnections** is false the agent will be free to use the diagonal connections to move away from that spot. However, if **filterDiagonalGridConnections** is true (the default) then the diagonal connections will be disabled and the agent will be stuck. Typically, there are a few common use cases: * If your [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) makes walls and obstacles and you want it to behave identically to obstacles included in the original grid graph scan, then this should be true. * If your [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) is used for agent to agent avoidance and you want them to be able to move around each other more freely, then this should be false. See [GridNode](https://arongranberg.com/astar/docs/gridnode.html) Deprecated Members ------------------ [GetTraversalCost](https://arongranberg.com/astar/docs/itraversalprovider/gettraversalcost.html#GetTraversalCost) (path, node) Cost of traversing the given node. --- # GraphMask - A* Pathfinding Project Struct GraphMask ================ Public A combination of graphs. Represents a set of graphs, which is usually used to filter which graphs to use for pathfinding, or which graphs to apply an update to. This mask can hold any subset of small graph indices (up to graph index 30), but only a combination of at most 3 graphs of large graph indices (larger than 30). Almost all games will use only one or a few graphs, so you can think of this as being able to represent any combination of graphs. `[GraphMask](https://arongranberg.com/astar/docs/graphmask/graphmask.html#GraphMask) mask1 = [GraphMask](https://arongranberg.com/astar/docs/graphmask/graphmask.html#GraphMask) .FromGraphName("My Grid Graph"); [GraphMask](https://arongranberg.com/astar/docs/graphmask/graphmask.html#GraphMask) mask2 = [GraphMask](https://arongranberg.com/astar/docs/graphmask/graphmask.html#GraphMask) .FromGraphName("My Other Grid Graph"); NearestNodeConstraint nn = NearestNodeConstraint.Walkable; nn.graphMask = mask1 | mask2; // Find the node closest to somePoint which is either in 'My Grid Graph' OR in 'My Other Grid Graph' var info = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (somePoint, nn); ` See [Bitmask Tutorial](https://arongranberg.com/astar/docs/bitmasks.html) Public Methods -------------- [Contains](https://arongranberg.com/astar/docs/graphmask/contains.html) (...) True if this mask contains the g... [Equals](https://arongranberg.com/astar/docs/graphmask/equals.html#Equals) (obj) [GetHashCode](https://arongranberg.com/astar/docs/graphmask/gethashcode.html#GetHashCode) () [GraphMask](https://arongranberg.com/astar/docs/graphmask/graphmask.html#GraphMask) (value) [ToString](https://arongranberg.com/astar/docs/graphmask/tostring.html#ToString) () Public Static Methods --------------------- [FromGraph](https://arongranberg.com/astar/docs/graphmask/fromgraph.html#FromGraph) (graph) A bitmask containing the given graph. [FromGraphIndex](https://arongranberg.com/astar/docs/graphmask/fromgraphindex.html#FromGraphIndex) (graphIndex) A bitmask containing the given graph index. [FromGraphName](https://arongranberg.com/astar/docs/graphmask/fromgraphname.html#FromGraphName) (graphName) A bitmask containing the first graph with the given name. [InsertMask](https://arongranberg.com/astar/docs/graphmask/insertmask.html#InsertMask) (indices, cnt, mask) [InsertSorted](https://arongranberg.com/astar/docs/graphmask/insertsorted.html#InsertSorted) (indices, cnt, value) Insert one item, as part of an insertion-sort. [operator!=](https://arongranberg.com/astar/docs/graphmask/operator.html#operator) (lhs, rhs) [operator==](https://arongranberg.com/astar/docs/graphmask/operator2.html#operator) (lhs, rhs) [operator|](https://arongranberg.com/astar/docs/graphmask/operator3.html#operator) (lhs, rhs) Combines two masks to form the union of them. [operator~](https://arongranberg.com/astar/docs/graphmask/operator4.html#operator) (lhs) Inverts the mask. Public Variables ---------------- containsAllGraphs True if the mask contains all graphs, i.e. Public ##### bool containsAllGraphs True if the mask contains all graphs, i.e. if it is equal to [GraphMask.everything](https://arongranberg.com/astar/docs/graphmask.html#everything) isPureBitmask Public ##### bool isPureBitmask Public Static Variables ----------------------- Everything Public Static ##### const uint Everything = ~0U InvertedBit Public Static ##### const uint InvertedBit = 1U << 30 LargeGraphIndicesBit Public Static ##### const uint LargeGraphIndicesBit = 1U << 31 RemainingGraphIndicesBit Public Static ##### const uint RemainingGraphIndicesBit = 1U << 30 SmallestLargeGraphIndex Public Static ##### const uint SmallestLargeGraphIndex = 30 everything A mask containing every graph. Public Static ##### [GraphMask](https://arongranberg.com/astar/docs/graphmask.html) everything A mask containing every graph. Private/Protected Members ------------------------- value Internal representation of the mask. Private ##### int value Internal representation of the mask. Depending on LargeGraphIndicesBit (bit 31) the mask is in one of two modes: * If LargeGraphIndicesBit is set, then the lower 3x8 bits are used to store indices of 3 graphs (0-254, 255 represents no graph). The InvertedBit (bit 30) is used to indicate if the mask is inverted. * If LargeGraphIndicesBit is not set, then the lower 30 bits are a normal bitmask for the first 30 graphs, and bit 30 (RemainingGraphIndicesBit) represents all graph indices larger or equal to 30. Combining two masks is not trivial and can actually throw an exception if you try to combine too many large graph indices. Fortunately, hitting this limit is very rare, and will never happen in normal use. There are technically two representations that contain all graphs. All bits set, and all bits except the LargeGraphIndicesBit. However, we prevent the latter from being created, to avoid confusion. Note Has to stay an int, and not an uint, because Unity will refuse to deserialize old values like -1 otherwise, and we really want to keep backwards compatibility. --- # Agent-Specific Pathfinding - A* Pathfinding Project Agent-Specific Pathfinding ========================== Sometimes you need to customize pathfinding on an agent-by-agent basis. For example, you may want to make some agents avoid water, or perhaps you want to make some agents prefer walking on roads. In some games, you may even need unique pathfinding rules for every single agent. This page will guide you through different options for doing this, as they each have their pros and cons. * [Alternatives](https://arongranberg.com/astar/docs/traversal_provider.html#alternatives) * [The ITraversalProvider interface](https://arongranberg.com/astar/docs/traversal_provider.html#provider) * [Using the ITraversalProvider with a movement script](https://arongranberg.com/astar/docs/traversal_provider.html#traversal-provider-usage) * [Case Studies](https://arongranberg.com/astar/docs/traversal_provider.html#case-studies) * [Ships and peasants](https://arongranberg.com/astar/docs/traversal_provider.html#water) * [Turn-based games](https://arongranberg.com/astar/docs/traversal_provider.html#case-turnbased) * [Multiple agent sizes](https://arongranberg.com/astar/docs/traversal_provider.html#multiple-agent-sizes) * [Preferring roads](https://arongranberg.com/astar/docs/traversal_provider.html#roads) Alternatives ------------ There are a few options you can take: * Use tags. All nodes can be assigned a single tag from 0 through 31. You can decide for each agent if a particular tag should be walkable or not, and how costly it should be to traverse it. Read more about tags here: [Working with tags](https://arongranberg.com/astar/docs/tags.html) . This is a very simple way of customizing pathfinding, but it is also very limited in what it can do. * Use multiple graphs. If different agents require drastically different navmeshes, using different graphs can be a good option. However, this is only reasonable if you only need a small number of different graphs, as it can be quite cumbersome to manage many graphs, not to mention the memory and performance overhead. It is a very robust option though, and it gives you maximum flexibility by trading away some memory and performance. Read more about multiple graphs here: [Multiple agent types](https://arongranberg.com/astar/docs/multipleagenttypes.html) . * Use the [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) interface to get full control over the walkability and penalty of each node individually for each pathfinding request. This is a very flexible option, but also the most complex one, as it requires you to write some code. Read more about it below. The ITraversalProvider interface -------------------------------- The [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) interface is something you can implement to be able to control exactly which nodes are traversable, how costly it is to traverse them, and how costly it is to traverse connections between nodes. This enables a lot of flexibility in how you can control pathfinding, significantly more than using the built-in tag system. Any path can be assigned a traversal provider, which has four methods that you can override CanTraverse (traversalConstraint, node) True if **node** should be able to be traversed by the path. If you are implementing a custom [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) , you should override this method and do whatever checks you need to do to determine if the node is traversable. When used, the [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) will pretty much always be wrapped in a [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint.html) struct. The [TraversalConstraint.CanTraverse(GraphNode)](https://arongranberg.com/astar/docs/traversalconstraint/cantraverse.html#CanTraverse) method will then do its own checks first, and call this method to do additional filtering. This means that the [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) is always at least as strict as the [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint.html) . Note This also means that returning true from this method does not necessarily mean that the node is traversable by a path. The [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint.html) may have additional filters, and in particular it always checks that the node is [walkable](https://arongranberg.com/astar/docs/graphnode.html#Walkable) . `public bool [CanTraverse](https://arongranberg.com/astar/docs/itraversalprovider/cantraverse.html#CanTraverse) (ref TraversalConstraint traversalConstraint, GraphNode node) { // If, for example, your agents are afraid of heights, prevent your agents from going above 50 world units return ((Vector3)node.position).y < 50; } ` See [TraversalConstraint.CanTraverse(GraphNode)](https://arongranberg.com/astar/docs/traversalconstraint/cantraverse.html#CanTraverse) See This setting corresponds to the member [ITraversalProvider.CanTraverse(TraversalConstraint,GraphNode)](https://arongranberg.com/astar/docs/itraversalprovider/cantraverse.html#CanTraverse) CanTraverse (traversalConstraint, from, to) True if the path can traverse a connection between **from** and **to**, and if **to** can be traversed itself. This can be used to block movement between specific nodes. If this method returns true then a call to CanTraverse(traversalConstraint,to) must also return true. Thus this method is a more flexible version of [CanTraverse(TraversalConstraint,GraphNode)](https://arongranberg.com/astar/docs/itraversalprovider/cantraverse.html#CanTraverse) . The default implementation will just call [CanTraverse(traversalConstraint,to)](https://arongranberg.com/astar/docs/itraversalprovider/cantraverse.html#CanTraverse) `public bool [CanTraverse](https://arongranberg.com/astar/docs/itraversalprovider/cantraverse.html#CanTraverse) (ref TraversalConstraint traversalConstraint, GraphNode from, GraphNode to) { // Connections between nodes can be filtered too. // If you don't have any special rules for this, just forward the call to checking if the 'to' node is traversable. // (or just skip this method, as the default implementation will do the same) // We can, for example, prevent the agent from going directly from a node with tag 2 to a node with tag 3 if (from.Tag == 2 && to.Tag == 3) return false; return [CanTraverse](https://arongranberg.com/astar/docs/itraversalprovider/cantraverse.html#CanTraverse) (ref traversalConstraint, to); } ` See [TraversalConstraint.CanTraverse(GraphNode,GraphNode)](https://arongranberg.com/astar/docs/traversalconstraint/cantraverse.html#CanTraverse2) See This setting corresponds to the member [ITraversalProvider.CanTraverse(TraversalConstraint,GraphNode,GraphNode)](https://arongranberg.com/astar/docs/itraversalprovider/cantraverse.html#CanTraverse4) GetTraversalCostMultiplier (traversalCosts, node) Multiplier for the cost of traversing some distance across the given node. Returns a float representing how costly it is to move across the node, with 1.0 being the default, and, for example, 2.0 being twice as costly. The value will be multiplied by the traversed distance in millimeters (see [Int3.Precision](https://arongranberg.com/astar/docs/int3.html#Precision) ) to get the final cost. For the default multiplier of 1.0, this means that the cost will be the same as the distance in millimeters. Note Prefer to make traversal more costly (cost multiplier >1), rather than making it cheaper than the default (cost multiplier <1). If you return any cost multiplier less than 1, you'll also need to reduce [AstarPath.heuristicScale](https://arongranberg.com/astar/docs/astarpath.html#heuristicScale) to the lowest cost multiplier that you use in the project, otherwise the pathfinding algorithm may not find the optimal path. Alternatively you could compensate with a higher connection cost value, so that the agent can never move to the target with a lower cost than the default. See [https://en.wikipedia.org/wiki/Admissible\_heuristic](https://en.wikipedia.org/wiki/Admissible_heuristic) . `public float [GetTraversalCostMultiplier](https://arongranberg.com/astar/docs/itraversalprovider/gettraversalcostmultip.html#GetTraversalCostMultiplier) (ref TraversalCosts traversalCosts, GraphNode node) { // For example, if your agent is afraid of heights, you can make nodes high up be 10 times more expensive to traverse if (((Vector3)node.position).y > 30) return 10.0f; return DefaultITraversalProvider.GetTraversalCostMultiplier(ref traversalCosts, node); } ` See [TraversalCosts.GetTraversalCostMultiplier(GraphNode)](https://arongranberg.com/astar/docs/traversalcosts/gettraversalcostmultiplier.html#GetTraversalCostMultiplier) See This setting corresponds to the member [ITraversalProvider.GetTraversalCostMultiplier(TraversalCosts,GraphNode)](https://arongranberg.com/astar/docs/itraversalprovider/gettraversalcostmultip.html#GetTraversalCostMultiplier) GetConnectionCost (traversalCosts, from, to) Cost of entering a given node from another node. Should return the additional cost for moving between **from** and **to**. By default, if no tags or penalties are used, then the connection cost is zero. A cost of 1000 corresponds roughly to the cost of moving 1 world unit. This cost is not scaled by the distance between the two nodes. This cost is also not affected by the [traversal cost multiplier](https://arongranberg.com/astar/docs/itraversalprovider/gettraversalcostmultip.html#GetTraversalCostMultiplier) . The default implementation returns 0, and all cost comes from the [GetTraversalCostMultiplier](https://arongranberg.com/astar/docs/itraversalprovider/gettraversalcostmultip.html#GetTraversalCostMultiplier) method instead. `public uint [GetConnectionCost](https://arongranberg.com/astar/docs/itraversalprovider/getconnectioncost.html#GetConnectionCost) (ref TraversalCosts traversalCosts, GraphNode from, GraphNode to) { // The traversal cost is, by default, the sum of the penalty of the node's tag and the node's penalty return traversalCosts.GetTagEntryCost(to.Tag) + to.Penalty; // alternatively: // return DefaultITraversalProvider.GetConnectionCost(ref traversalCosts, from, to); } ` See [TraversalCosts.GetConnectionCost(GraphNode,GraphNode)](https://arongranberg.com/astar/docs/traversalcosts/getconnectioncost.html#GetConnectionCost) See This setting corresponds to the member [ITraversalProvider.GetConnectionCost(TraversalCosts,GraphNode,GraphNode)](https://arongranberg.com/astar/docs/itraversalprovider/getconnectioncost.html#GetConnectionCost) Note The [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint.html) 's own settings will always be used before the traversal provider is consulted, so you cannot make nodes traversable that would not be traversable without using a traversal provider. As a reference, here's one implementation: `public class MyCustomTraversalProvider : ITraversalProvider { public bool CanTraverse (ref TraversalConstraint traversalConstraint, GraphNode node) { // If, for example, your agents are afraid of heights, prevent your agents from going above 50 world units return ((Vector3)node.position).y < 50; } public bool CanTraverse (ref TraversalConstraint traversalConstraint, GraphNode from, GraphNode to) { // Connections between nodes can be filtered too. // If you don't have any special rules for this, just forward the call to checking if the 'to' node is traversable. // (or just skip this method, as the default implementation will do the same) // We can, for example, prevent the agent from going directly from a node with tag 2 to a node with tag 3 if (from.Tag == 2 && to.Tag == 3) return false; return CanTraverse(ref traversalConstraint, to); } public float GetTraversalCostMultiplier (ref TraversalCosts traversalCosts, GraphNode node) { // For example, if your agent is afraid of heights, you can make nodes high up be 10 times more expensive to traverse if (((Vector3)node.position).y > 30) return 10.0f; return DefaultITraversalProvider.GetTraversalCostMultiplier(ref traversalCosts, node); } public uint GetConnectionCost (ref TraversalCosts traversalCosts, GraphNode from, GraphNode to) { // The traversal cost is, by default, the sum of the penalty of the node's tag and the node's penalty return traversalCosts.GetTagEntryCost(to.Tag) + to.Penalty; // alternatively: // return DefaultITraversalProvider.GetConnectionCost(ref traversalCosts, from, to); } } `By implementing a custom [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) you can change the penalties however you want to suit your game's rules. Warning If multithreading is enabled, or if you are using the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) , the ITraversalProvider's methods will be called from separate threads. This means you cannot use any part of the Unity API (except things like math) and you need to make sure your code is thread safe. ### Using the ITraversalProvider with a movement script When you have implemented an ITraversalProvider, you can use it with any built-in movement script, or in your own path requests. **Seeker** If you use the Seeker component, assigning a traversal provider to it will make all requests made through it use that provider. `seeker.traversalProvider = new MyCustomTraversalProvider(); `**FollowerEntity** If you use the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component, you can set the traversal provider in its pathfinding settings: `followerEntity.pathfindingSettings.traversalProvider = new MyCustomTraversalProvider(); `**Custom path request** Or if you create your own path requests, you can set it directly on the path: `var path = ABPath.Construct(Vector3.zero, Vector3.one); var traversalProvider = new MyCustomTraversalProvider(); // Use the same provider for both traversability and costs path.traversalConstraint.traversalProvider = traversalProvider; path.traversalCosts.traversalProvider = traversalProvider; ` See For simpler use cases you can provide a filter function instead. You can find an example of that here: [CircuitBoardExample.cs](https://arongranberg.com/astar/docs/circuitboardexamplecs.html) Case Studies ------------ Here follow a few case studies of common scenarios and how to solve them. ### Ships and peasants Assume you have a nice medieval game with peasants farming the land in an archipelago, and cargo ships sailing the seas. The peasants should be able to walk on land, but not on water. The ships should be able to sail on water, but not on land. For this case, I would recommend using multiple graphs. One for land and one for water. Then you can choose which one the agents use by selecting the appropriate graph in the [Seeker](https://arongranberg.com/astar/docs/seeker.html) inspector. The reason is that the ships and the peasants cannot move over any common surfaces, so having separate graphs for them makes sense. This will also make it easier to tailor the graphs to suit each agent type. For example, you probably don't want to allow ships to move really close to the shore, but a peasant should be able to walk a fraction of a meter from an obstacle without issue. If you use a grid graph, you can also solve this instead by using tags to restrict the peasants to the islands, and the ships to the water. This will work, but it will be a bit more cumbersome to set up. ### Turn-based games In a turn-based game, you often want to prevent units from standing on the same tile. But you also want to allow a unit itself to stand on the tile it is currently on. Turn-based games also often have different movement costs for different units, the rules of which can be quite complex. This is a clear case for using the [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) interface to implement this logic. Fortunately, there are some convenient helpers already implemented for this case. Take a look at [Utilities for turn-based games](https://arongranberg.com/astar/docs/turnbased.html) . ### Multiple agent sizes In some games, you have agents with a wide range of sizes. This case is common enough that it has its own page! Check it out here: [Multiple agent types](https://arongranberg.com/astar/docs/multipleagenttypes.html) . ### Preferring roads In some games, you want to make units prefer walking on roads, but still allow them to walk on other surfaces if they need to. This can be done by using tags to mark the roads and then using a tag-based penalty to make units try to avoid other surfaces. Note that tag penalties cannot be negative, so you cannot make units prefer roads by using a negative penalty. Instead, we apply a positive penalty to all nodes that are **not** roads. You can find an example of this in the [Recast graph on a terrain](https://arongranberg.com/astar/docs/example_recast_terrain.html) example scene. --- # ProjectionParams - A* Pathfinding Project Struct ProjectionParams ======================= Public Public Methods -------------- [ProjectionParams](https://arongranberg.com/astar/docs/projectionparams/projectionparams.html#ProjectionParams) (distanceMetric, graphTransform) [SquaredRectPointDistanceOnPlane](https://arongranberg.com/astar/docs/projectionparams/squaredrectpointdistance.html) (\[projection\], rect, p) Public Variables ---------------- alignedWithXZPlane Public ##### bool alignedWithXZPlane alignedWithXZPlaneBacking Public Readonly ##### byte alignedWithXZPlaneBacking distanceMetricType Public Readonly ##### [DistanceMetric](https://arongranberg.com/astar/docs/bbtree.html#DistanceMetric) distanceMetricType distanceScaleAlongProjectionAxis Public Readonly ##### float distanceScaleAlongProjectionAxis planeProjection Public Readonly ##### float2x3 planeProjection projectedUpNormalized Public Readonly ##### float2 projectedUpNormalized projectionAxis Public Readonly ##### float3 projectionAxis --- # PathfindingTag - A* Pathfinding Project Struct PathfindingTag ===================== Public Represents a single pathfinding tag. Values of this type will be automatically displayed in the unity inspector as a dropdown list of all the pathfinding tags. Note The tag refers to a pathfinding tag, not a unity tag that is applied to GameObjects, or any other kind of tag. See [Working with tags](https://arongranberg.com/astar/docs/tags.html) Public Methods -------------- [PathfindingTag](https://arongranberg.com/astar/docs/pathfindingtag/pathfindingtag.html#PathfindingTag) (value) [ToMask](https://arongranberg.com/astar/docs/pathfindingtag/tomask.html#ToMask) () Converts the tag value to a bitmask of tags. [ToString](https://arongranberg.com/astar/docs/pathfindingtag/tostring.html#ToString) () Public Static Methods --------------------- [FromName](https://arongranberg.com/astar/docs/pathfindingtag/fromname.html#FromName) (tagName) Get the value of the [PathfindingTag](https://arongranberg.com/astar/docs/pathfindingtag.html) with the given name. [operator PathfindingTag](https://arongranberg.com/astar/docs/pathfindingtag/operator_pathfindingtag.html#operatorPathfindingTag) (tag) [operator uint](https://arongranberg.com/astar/docs/pathfindingtag/operator_uint.html#operatoruint) (tag) Public Variables ---------------- value Underlaying tag value. Public ##### uint value Underlaying tag value. Should always be between 0 and [GraphNode.MaxTagIndex](https://arongranberg.com/astar/docs/graphnode.html#MaxTagIndex) (inclusive). --- # Pathfinding in 2D - A* Pathfinding Project Pathfinding in 2D ================= This page shows how to get pathfinding working in a 2D game. ![](https://arongranberg.com/astar/docs/images/2d/grid_2d.png) Contents -------- * [Introduction](https://arongranberg.com/astar/docs/pathfinding2d.html#intro-2d) * [Graph support](https://arongranberg.com/astar/docs/pathfinding2d.html#graph-support) * [Grid graphs](https://arongranberg.com/astar/docs/pathfinding2d.html#graph-support-grid) * [Point graphs](https://arongranberg.com/astar/docs/pathfinding2d.html#graph-support-point) * [Recast graphs](https://arongranberg.com/astar/docs/pathfinding2d.html#graph-support-recast) * [Navmesh graphs](https://arongranberg.com/astar/docs/pathfinding2d.html#graph-support-navmesh) * [Tilemaps](https://arongranberg.com/astar/docs/pathfinding2d.html#tilemaps_2d) * [Graph updates](https://arongranberg.com/astar/docs/pathfinding2d.html#updates) * [Navmesh Cutting](https://arongranberg.com/astar/docs/pathfinding2d.html#navmesh-cutting) * [Graph updates and 2D Colliders](https://arongranberg.com/astar/docs/pathfinding2d.html#colliders-2d) * [Movement scripts](https://arongranberg.com/astar/docs/pathfinding2d.html#movement-scripts) * [2D Movement on Point Graphs](https://arongranberg.com/astar/docs/pathfinding2d.html#movement-scripts-point) * [Local avoidance](https://arongranberg.com/astar/docs/pathfinding2d.html#local-avoidance-2d) Introduction ------------ The package contains 2 example scenes that show 2D setups. They are called **Example15\_2D** and **Example16\_RVO** 2D. There are many types of pathfinding one could want to do in 2D games. Primarily there are 2 types: * Top-down pathfinding. Used in games in which one looks down on the world from above. This is the case in the image above. * Platformer pathfinding. Similar to classic Super Mario, for example. This package unfortunately does not, at the moment, support this type of pathfinding. One can do quite a lot with point graphs and creating custom connections, but it is not supported out of the box. This video will walk you through how to create a simple 2D scene with pathfinding. Graph support ------------- All graphs support pathfinding in the XY plane and support 2D physics. ### Grid graphs The grid graph and layered grid graph have good support for working in the XY plane. In fact, grid graphs can be rotated in any direction and they will still work. For 2D games, you should check the '2D' toggle on the grid graph which will rotate the graph so that it lines up with the XY plane. If you are using 2D colliders, you will also want to enable the 'Use 2D Physics' checkbox. ### Point graphs Point graphs support pathfinding in the XY plane. Similarly to grid graphs, you will want to enable the 'Use 2D Physics' checkbox if you have the 'Raycast' setting enabled and you are using 2D colliders. ### Recast graphs Recast graphs can be rotated to work in the XY plane (and any other orientation). If you want to use 2D colliders, you can change the [dimensions](https://arongranberg.com/astar/docs/recastgraph.html#dimensionMode) field to 2D. The recast graph supports rasterizing normal 3D meshes, 3D colliders, and 2D colliders. It does not support rasterizing sprites as meshes at the moment. ### Navmesh graphs Navmesh graphs can similarly be rotated to work in any orientation. However, you must take care so that the 'up' direction of the graph corresponds to the desired up direction. For example, if you want to use a navmesh graph in the XY plane, you need to set the rotation field to (-90,0,0); you cannot simply rotate the mesh in Maya or Blender. ### Tilemaps Both grid graphs and recast graphs have support for tilemaps. Take a look at [Pathfinding on tilemaps](https://arongranberg.com/astar/docs/tilemaps.html) to learn how to use them for pathfinding. Graph updates ------------- Graph updates work basically the same in 2D games as in 3D games; however, there are a few things that are good to think about. ### Navmesh Cutting Navmesh cutting, which can be used to update recast and navmesh graphs, works in 2D and any other orientation. Note If you are using one of the legacy navmesh cut modes (rectangle/circle), or your own custom mesh, then you need to make sure that the navmesh cuts are rotated correctly. Legacy navmesh cuts are represented as 2D outlines that are projected down on the graph's surface. If a legacy navmesh cut is rotated incorrectly, the 2D outline could be projected down to just a single line, and that wouldn't cut the graph in the way you want it to (see the image below). The [useRotationAndScale](https://arongranberg.com/astar/docs/navmeshcut.html#useRotationAndScale) checkbox must always be enabled when using navmesh cutting with a graph that is not horizontal. ![](https://arongranberg.com/astar/docs/images/2d/navmeshcut_2d.png) ### Graph updates and 2D Colliders A common way of performing a graph update in 3D games is something like: `var guo = new GraphUpdateObject(GetComponent().bounds); guo.updatePhysics = false; guo.modifyWalkability = true; guo.setWalkability = false; AstarPath.active.UpdateGraphs(guo); `For 2D games, the code requires some minor adjustments before it can work. The reason is that 2D colliders are infinitely thin, so the bounds will have a zero volume. Since the graphs check if the nodes' positions are inside the bounds, they will never update a single node because no node can be inside something that is infinitely thin. To solve this, you can extend the bounds along the Z axis to make sure you cover all nodes. `var bounds = GetComponent().bounds; // Expand the bounds along the Z axis bounds.Expand(Vector3.forward*1000); var guo = new GraphUpdateObject(bounds); // change some settings on the object AstarPath.active.UpdateGraphs(guo); ` Movement scripts ---------------- The included movement scripts have varying support for different graph orientations. * The [AIPath](https://arongranberg.com/astar/docs/aipath.html) movement script supports movement in any graph orientation for grid graphs, navmesh graphs, and recast graphs; it will orient itself automatically. You may want to disable the 'gravity' setting to prevent the agent from falling off the map. * The [AILerp](https://arongranberg.com/astar/docs/ailerp.html) movement script supports movement in any graph orientation. For many 2D games, you may want the +Y axis to be the forwards direction of the agent instead of the +Z axis as is common in 3D games. If so, you can enable the [AILerp.orientation](https://arongranberg.com/astar/docs/ailerp.html#orientation) checkbox. * The [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) movement script supports movement in any graph orientation; it will orient itself automatically to the graph. You may want to disable the 'gravity' setting to prevent the agent from falling off the map. * The [RichAI](https://arongranberg.com/astar/docs/richai.html) movement script does not support any orientation other than the XZ plane at the moment. However, a large part of the work to make it support it has already been done, and I expect it to be included in a future update. ### 2D Movement on Point Graphs Point graphs have no well-defined **up** direction, so the AIPath script cannot know how it is supposed to orient itself. If you know the orientation that you want to use, you can subclass the AIPath component and override the UpdateMovementPlane method to force it to use a particular orientation. `class AIPathSub : AIPath { protected override void UpdateMovementPlane () { var graphRotation = new Vector3(-90, 0, 0); movementPlane = new SimpleMovementPlane(Quaternion.Euler(graphRotation)); } } `The graphRotation variable could, of course, be changed to any rotation you wish. Local avoidance --------------- Local avoidance works in the XY plane. The only thing you have to do is change the [movementPlane](https://arongranberg.com/astar/docs/rvosimulator.html#movementPlane) setting on the RVOSimulator component to [XY](https://arongranberg.com/astar/docs/rvo2.html#MovementPlane) . You can take a look at the example scene called "RVO 2D" which shows an example of how to configure it. --- # TraversalConstraint - A* Pathfinding Project Struct TraversalConstraint ========================== Public Specifies which nodes are traversable and which are not. This struct is used to specify which nodes are traversable when searching for paths and when doing linecasts on graphs, among other things. It can be used to filter out nodes based on their tags, or even using completely custom filters. Note For performance reasons, this struct is often passed by reference (using the **ref** keyword). It's a moderately large struct, and it is often used in performance-critical code. Passing it by reference avoids copying the struct, and gives us some moderate performance improvements. `// Custom filter var traversalConstraint = new [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint/traversalconstraint.html#TraversalConstraint2) ((GraphNode node) => ((Vector3)node.position).y > 50); traversalConstraint.tags = 1 << 3; // Only allow traversing nodes with tag 3 // Convert to nearest node constraint var nearestNodeConstraint = traversalConstraint.ToNearestNodeConstraint(); var node = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (transform.position, nearestNodeConstraint).node; // Check if the node is traversable traversalConstraint.CanTraverse(node); // True ``var graph = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .recastGraph; var start = transform.position; var end = start + Vector3.forward * 10; var trace = new List(); var traversalConstraint = [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint/traversalconstraint.html#TraversalConstraint2) .None; traversalConstraint.tags = 1 << 3; // Only allow traversing nodes with tag 3 if (graph.Linecast(start, end, out GraphHitInfo hit, ref traversalConstraint, trace)) { Debug.Log("Linecast traversed " + trace.Count + " nodes before hitting an obstacle"); Debug.DrawLine(start, hit.point, Color.red); Debug.DrawLine(hit.point, end, Color.blue); } else { Debug.Log("Linecast traversed " + trace.Count + " nodes"); Debug.DrawLine(start, end, Color.green); } ``ABPath path = ABPath.Construct(currentPosition, destination, null); path.traversalConstraint.traversalProvider = GridShapeTraversalProvider.SquareShape(3); // If you are writing your own movement script seeker.StartPath(path); // If you are using an existing movement script (you may also want to set ai.canSearch to false) // ai.SetPath(path); ` See [Path.traversalConstraint](https://arongranberg.com/astar/docs/path.html#traversalConstraint) [IRaycastableGraph](https://arongranberg.com/astar/docs/iraycastablegraph.html) [NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) Public Methods -------------- [CanTraverse](https://arongranberg.com/astar/docs/traversalconstraint/cantraverse.html) (...) True if the... [CanTraverseSkipUserFilter](https://arongranberg.com/astar/docs/traversalconstraint/cantraverseskipuserfi.html#CanTraverseSkipUserFilter) (node) True if the node is traversable with respect to the constraints set in this struct, but without checking the [filter](https://arongranberg.com/astar/docs/traversalconstraint.html#filter) or the [traversalProvider](https://arongranberg.com/astar/docs/traversalconstraint.html#traversalProvider) . [ToNearestNodeConstraint](https://arongranberg.com/astar/docs/traversalconstraint/tonearestnodeconstrai.html#ToNearestNodeConstraint) () A nearest node constraint which uses the same settings as this traversal constraint. [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint/traversalconstraint.html) (...) Create a new traversal constraint... Public Variables ---------------- filter Allow traversing only nodes which the given filter function returns true for. Public ##### System.Func<[GraphNode](https://arongranberg.com/astar/docs/graphnode.html) , bool >? filter Allow traversing only nodes which the given filter function returns true for. The other constraints on this struct will still apply, in addition to the filter function. Note Either an [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) ([traversalProvider](https://arongranberg.com/astar/docs/traversalconstraint.html#traversalProvider) ) or a filter function can be set, but not both. Setting this will clear [traversalProvider](https://arongranberg.com/astar/docs/traversalconstraint.html#traversalProvider) , and vice versa. `var traversalConstraint = [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint/traversalconstraint.html#TraversalConstraint2) .None; // Set a custom filter. This can be an arbitrary function which takes a GraphNode and returns true or false. traversalConstraint.filter = (GraphNode node) => ((Vector3)node.position).y > 50; // Search for a path which only traverses nodes above y=50 var path = ABPath.Construct(transform.position, transform.position + Vector3.forward * 10); path.traversalConstraint = traversalConstraint; [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[StartPath](https://arongranberg.com/astar/docs/astarpath/startpath.html#StartPath) (path); ` See [traversalProvider](https://arongranberg.com/astar/docs/traversalconstraint.html#traversalProvider) filterDiagonalGridConnections Filter diagonal connections on grid graphs using [GridGraph.cutCorners](https://arongranberg.com/astar/docs/gridgraph.html#cutCorners) for effects applied by any assigned [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) . Public ##### bool filterDiagonalGridConnections Filter diagonal connections on grid graphs using [GridGraph.cutCorners](https://arongranberg.com/astar/docs/gridgraph.html#cutCorners) for effects applied by any assigned [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) . If a traversal provider is used, returns [ITraversalProvider.filterDiagonalGridConnections](https://arongranberg.com/astar/docs/itraversalprovider.html#filterDiagonalGridConnections) for it. Otherwise returns true. See [ITraversalProvider.filterDiagonalGridConnections](https://arongranberg.com/astar/docs/itraversalprovider.html#filterDiagonalGridConnections) graphMask Graphs which are traversable. Public ##### [GraphMask](https://arongranberg.com/astar/docs/graphmask.html) graphMask Graphs which are traversable. This is a bitmask, meaning that bit 0 specifies whether or not the first graph in the graphs list should be included in the search, bit 1 specifies whether or not the second graph should be included, and so on. `var traversalConstraint = [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint/traversalconstraint.html#TraversalConstraint2) .None; // Allows the first and fourth graphs to be searched, but not the rest traversalConstraint.graphMask = GraphMask.FromGraphIndex(0) | GraphMask.FromGraphIndex(3); // Allows the two named graphs to be searched, but not the rest traversalConstraint.graphMask = GraphMask.FromGraphName("My Custom Graph Name") | GraphMask.FromGraphName("My Other Graph"); ` Note When used for pathfinding, this does only affects which nodes the path starts and ends on. If a valid graph is connected to an "invalid" graph, it may get searched anyway. See [AstarPath.GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html) [GraphMask](https://arongranberg.com/astar/docs/graphmask.html) [Bitmask Tutorial](https://arongranberg.com/astar/docs/bitmasks.html) tags Set of tags which are traversable. Public ##### int tags Set of tags which are traversable. This is a bitmask, i.e bit 0 indicates that tag 0 is traversable, bit 3 indicates tag 3 is traversable etc. By default all tags are traversable, which corresponds to the value -1. `var traversalConstraint = [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint/traversalconstraint.html#TraversalConstraint2) .None; // Allows the first and third tags to be searched, but not the rest traversalConstraint.tags = (1 << 0) | (1 << 2); // Allows the two named tags to be searched, but not the rest traversalConstraint.tags = PathfindingTag.FromName("Grass").ToMask() | PathfindingTag.FromName("Lava").ToMask(); `If you are using the [Seeker](https://arongranberg.com/astar/docs/seeker.html) or [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) components, you can access this in the inspector via the tags foldout: ![](https://arongranberg.com/astar/docs/images/tagpopup@2x.png) See [graphMask](https://arongranberg.com/astar/docs/traversalconstraint.html#graphMask) [Working with tags](https://arongranberg.com/astar/docs/tags.html) [Bitmask Tutorial](https://arongranberg.com/astar/docs/bitmasks.html) [PathfindingTag.ToMask](https://arongranberg.com/astar/docs/pathfindingtag/tomask.html#ToMask) traversalProvider Allow traversing only nodes that are also traversable by the given [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) . Public ##### [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) ? traversalProvider Allow traversing only nodes that are also traversable by the given [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) . The other constraints on this struct will still apply, in addition to the [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) . Note Either an [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) or a callback filter ( [filter](https://arongranberg.com/astar/docs/traversalconstraint.html#filter) ) can be set, but not both. Setting this will clear [filter](https://arongranberg.com/astar/docs/traversalconstraint.html#filter) , and vice versa. See [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) [Agent-Specific Pathfinding](https://arongranberg.com/astar/docs/traversal_provider.html) [filter](https://arongranberg.com/astar/docs/traversalconstraint.html#filter) Public Static Variables ----------------------- None Traversal constraint which allows all (walkable) nodes on all graphs to be traversed. Public Static Readonly ##### [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint.html) None = new [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint.html) { [tags](https://arongranberg.com/astar/docs/traversalconstraint.html#tags) = ~0, [graphMask](https://arongranberg.com/astar/docs/traversalconstraint.html#graphMask) = [GraphMask.everything](https://arongranberg.com/astar/docs/graphmask.html#everything) } Traversal constraint which allows all (walkable) nodes on all graphs to be traversed. Note Unwalkable ( [GraphNode.Walkable](https://arongranberg.com/astar/docs/graphnode.html#Walkable) ) nodes can never be traversed, regardless of the settings in this struct. The returned struct's [CanTraverse(GraphNode)](https://arongranberg.com/astar/docs/traversalconstraint/cantraverse.html#CanTraverse) method will return true for all nodes except those with the [GraphNode.Walkable](https://arongranberg.com/astar/docs/graphnode.html#Walkable) property set to false. Private/Protected Members ------------------------- FilterType Internal ##### FilterType | | | | --- | --- | | None | | | TraversalProvider | | | Func | | filterObj Internal ##### object filterObj filterType Internal ##### [FilterType](https://arongranberg.com/astar/docs/traversalconstraint.html#FilterType) filterType --- # Lightweight Local Avoidance Simulation - A* Pathfinding Project Lightweight Local Avoidance Simulation ====================================== Example scene which demonstrates local avoidance without any pathfinding and minimal rendering. ![](https://arongranberg.com/astar/docs/images/rvo/rvo_stress_30000_white.png) This example scene demonstrates how to use local avoidance without any movement scripts, pathfinding, GameObjects, or any other overhead that is not strictly necessary for local avoidance. It is useful if you want to gauge the performance of the local avoidance system without any other systems interfering. The scene contains the [LightweightRVO](https://arongranberg.com/astar/docs/lightweightrvo.html) component, which allows you to simulate between 10 and 30,000 agents in various configurations. The agents can be configured with different goals: * Circle: Agents are spawned randomly in a circle and try to reach the opposite side of the circle. * Line: Agents are spawned in two parallel lines and try to reach the corresponding point on the other line. This goal works best with fewer agents. * Point: Agents are spawned randomly in a circle and try to reach the center of the circle. * Random streams: Agents are spawned randomly in a disc and try to reach another random point. * Crossing: Agents are spawned in a star pattern and try to reach the point on the opposite side of the center. This goal works best with fewer agents. The [LightweightRVO](https://arongranberg.com/astar/docs/lightweightrvo.html) component uses the Entity Component System to create one entity for each agent. Then it uses two custom systems to move the agents and to render them into a single mesh. It also uses the already running [RVOSystem](https://arongranberg.com/astar/docs/rvosystem.html) to simulate the local avoidance. It works very much like the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component, but with a lot less complexity for movement and pathfinding. See [Local Avoidance](https://arongranberg.com/astar/docs/localavoidance.html) for more details about local avoidance --- # Large worlds - A* Pathfinding Project Large worlds ============ How to deal with pathfinding in large worlds. Contents -------- * [Introduction](https://arongranberg.com/astar/docs/largeworlds.html#large-world-intro) * [Constraints](https://arongranberg.com/astar/docs/largeworlds.html#large-world-constraints) * [Graph type](https://arongranberg.com/astar/docs/largeworlds.html#large-world-graph) * [Solutions](https://arongranberg.com/astar/docs/largeworlds.html#large-world-solutions) * [A single recast graph](https://arongranberg.com/astar/docs/largeworlds.html#large-recast) * [A single large grid graph](https://arongranberg.com/astar/docs/largeworlds.html#large-grid) * [A small moving graph](https://arongranberg.com/astar/docs/largeworlds.html#moving-grid) * [Conclusion](https://arongranberg.com/astar/docs/largeworlds.html#large-conclusion) Introduction ------------ Large worlds can strain pathfinding, especially if you make the wrong choice of how to set it up. In this tutorial, you will learn about the most common trade-offs when it comes to large worlds, and what solutions there are for dealing with them. Constraints ----------- It is important to first take a look at what requirements your game has that any solution will have to fulfill. Different solutions suit different games. Take a look at this list of constraints and ask yourself what applies to your game: * Is there more than 1 character? * Are there many agents spread out over the whole world that need pathfinding simultaneously? * Is all pathfinding centered around a single point/character? * Do you need to update the graph while the game is running? * Is the whole world known at build time, or is it procedurally generated? * Does the game need penalties and/or tags? Graph type ---------- When it comes to large worlds, the primary choice is between a [GridGraph](https://arongranberg.com/astar/docs/gridgraph.html) or a [RecastGraph](https://arongranberg.com/astar/docs/recastgraph.html) . Recast graphs are in general better for large worlds, since they typically require many fewer nodes to represent a world with good precision. Grid graphs can scale up to decently sized worlds, but large grid graphs have a large memory and performance overhead since you end up with so many nodes. A grid graph of 500x500 nodes is already large, and I do not recommend trying to go over 1000x1000 nodes since the memory usage becomes prohibitively large. If, however, you don't need pathfinding in the whole world at the same time (e.g. when everything is centered on a single player character) then you can still use a grid or recast graph which moves around the world as the player moves. Solutions --------- Here follows a few common setups, together with their pros and cons. ### A single recast graph A single large recast graph can be an excellent choice out of the box. A recast graph can represent both large empty regions and small details very well. You will want to make sure tiling is enabled in the recast graph settings since this will make generating and updating the large graph much faster. ![](https://arongranberg.com/astar/docs/images/largeworld/large_recast.png) Pros: * It's simple to set up. * It represents both small and large details well. * It has comparatively low memory usage. * Pathfinding on it is fast due to the low node count. * The whole map exists in memory at the same time, so many characters can traverse different parts of the world simultaneously. * [Navmesh cutting](https://arongranberg.com/astar/docs/navmeshcutting.html) can be used for pretty fast graph updates. Cons: * Full graph updates are slower than grid graphs (navmesh cutting is faster). * Recast graphs are bad at representing tags and penalties. * Large undulating empty regions, like a hill without any trees or obstacles, can be hard for the recast graph to represent well. Though, enabling tiling can help break up the large nodes. * Scanning a very large recast graph can take a lot of time. This means it's often not ideal for procedural worlds unless you can generate them piece by piece over time. See [Recast graph in a 3D game](https://arongranberg.com/astar/docs/example_recast3d.html) ### A single large grid graph A single large grid graph can work really well if you stay below the limits where a grid graph doesn't scale well. A grid graph scales decently up to 500x500 nodes, and you can go up to 1000x1000 nodes if you really need to. Larger than that is not recommended. ![](https://arongranberg.com/astar/docs/images/largeworld/large_grid.png) Pros: * It's simple to set up. * Grid graphs work well with penalties and tags. * Graph updates are fast. * Scanning the graph is comparatively fast (scanning a 1000x1000 graph can still take a bit of time). * The whole map exists in memory at the same time, so many characters can traverse different parts of the world simultaneously. Cons: * Memory usage is higher than a recast graph. * Pathfinding over long distances can be much slower than on a recast graph. * It doesn't scale to very large worlds. Note You can find an example of a grid graph in the example scene called "Example2". ### A small moving graph If your pathfinding is centered around a single point or character (e.g. the player) then you may be able to use a moving grid or recast graph. A moving grid/recast graph is one that utilizes the [ProceduralGraphMover](https://arongranberg.com/astar/docs/proceduralgraphmover.html) script. The idea is that you have a smallish grid graph (e.g. 100x100) or recast graph that is always centered on a character. As the character moves around, the [ProceduralGraphMover](https://arongranberg.com/astar/docs/proceduralgraphmover.html) will move the graph and scan the new parts that come into view, and discard the old parts. You can even extend this to several small graphs if you need to. Each small graph is centered on a different point or character. However, past 2-4 such graphs, the overhead of moving and updating all the graphs can become sizable. Your browser does not support the video tag. Recast graphs can also be used. In that case, the [ProceduralGraphMover](https://arongranberg.com/astar/docs/proceduralgraphmover.html) will work with a tile granularity. Your browser does not support the video tag. Pros: * You can use a grid graph, which works well with penalties and tags, or a recast graph, which can capture small details well. * Graph updates are fast, as long as the graph is kept reasonably small. * Scanning the graph is comparatively fast. * You can easily support a very large, or even an infinitely large world with this setup. * Memory usage is low. Cons: * Pathfinding can only happen in the vicinity of a given character/point. * Long distance pathfinding is not possible, which can make it hard to find paths around large obstacles like mountain chains. * There is a constant overhead when the character/point moves, since the graph has to be updated regularly. * Slightly more complicated to set up. See [Infinite procedurally generated world](https://arongranberg.com/astar/docs/example_infinite_world.html) Conclusion ---------- In this tutorial, we have gone through what to think of when you want pathfinding in a large world, and some example setups that you can use in your own game. For more information on different graph types, take a look at [Graph Types](https://arongranberg.com/astar/docs/graphtypes.html) . --- # Utilities for turn-based games - A* Pathfinding Project Utilities for turn-based games ============================== Contents -------- * [Introduction](https://arongranberg.com/astar/docs/turnbased.html#introduction) * [Blocking nodes](https://arongranberg.com/astar/docs/turnbased.html#blocks) * [ITraversalProvider](https://arongranberg.com/astar/docs/turnbased.html#turnbased-ITraversalProvider) Introduction ------------ Note It is recommended that you read the [Get Started](https://arongranberg.com/astar/docs/getstarted.html) tutorial before progressing with this tutorial. Turn-based games often require more detailed control over which nodes units can traverse as well as the cost for traversing those nodes, which may vary between units. On the other hand, maximum pathfinding performance is not always needed since most units will be stationary at any one time. It is possible to update all movement costs and similar attributes for nodes in the graph before every path request; however, this is not a particularly clean solution, so this package provides some other ways to do this. If you need even more control, you can take a look at the [ITraversalProvider](https://arongranberg.com/astar/docs/turnbased.html#turnbased-ITraversalProvider) section. Blocking nodes -------------- The most common scenario is that one wants to block certain nodes from being traversed by some units but not by others. For example, in a turn-based game, one usually wants to prevent units from standing on the same tile; however, a unit should obviously not be blocked by itself. For this purpose, the BlockManager component and the accompanying SingleNodeBlocker component exist. The SingleNodeBlocker is intended to be used as an easy way of blocking specific nodes where each SingleNodeBlocker component blocks exactly one node. The BlockManager component will keep track of all the SingleNodeBlocker components and allows the creation of TraversalProvider instances which can be used in paths to specify additional nodes that are blocked. Note A separate example of this can be viewed in the example scene called [Hexagonal Turn Based](https://arongranberg.com/astar/docs/example_turn_based.html) . This example scene depends on pro features, however, so it is not included in the free version of the package. The features mentioned in this tutorial do not require the pro version. In this tutorial, we will create a new scene and a few scripts to test the API. Create a new scene and save it in your project; name it "TurnBasedTest" or whatever you feel like. Add a new GameObject and name it "BlockManager", then select it and attach the BlockManager component to it. Now add a sphere and place it at (1.5, 0, 2.5). This will put it right in the center of a node. Add the SingleNodeBlocker script to it and assign the BlockManager component we created earlier to the "manager" field on the SingleNodeBlocker component. Make sure you delete the collider on the sphere because otherwise the sphere will be detected as an obstacle anyway, and we want to use the SingleNodeBlocker for that. Create another GameObject and name it "A\*", then add the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component to it (Menu bar → [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) → [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) ). You can add a large plane to the scene if you want, just to have something to have as a ground plane. Add a Grid Graph to the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component and set the "Unwalkable when no ground" setting to false. If you click the Scan button now, you should see a small empty grid with a single sphere. Note that the sphere does NOT block any node in the graph by itself. ![](https://arongranberg.com/astar/docs/images/turnbased/grid_with_sphere.png) ![](https://arongranberg.com/astar/docs/images/turnbased/part1_inspector.png) Now we want that SingleNodeBlocker to actually block some position, so create a new C# script named "BlockerTest.cs" and add this code: `using UnityEngine; using System.Collections; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) ; public class BlockerTest : MonoBehaviour { public void Start () { var blocker = GetComponent(); blocker.BlockAtCurrentPosition(); } } ` Add that new script to the sphere that we created earlier. When the game starts, that script will make the SingleNodeBlocker component tell the BlockManager that it now occupies the node at that object's position. This is not enough, however, because no path knows that a node has been blocked yet. To actually calculate a path, we will create a new script called "BlockerPathTest.cs" which should contain this code: `using UnityEngine; using System.Collections.Generic; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) ; public class BlockerPathTest : MonoBehaviour { public BlockManager blockManager; public List obstacles; public Transform target; BlockManager.TraversalProvider traversalProvider; public void Start () { // Create a traversal provider which says that a path should be blocked by all the SingleNodeBlockers in the obstacles array traversalProvider = new BlockManager.TraversalProvider(blockManager, BlockManager.BlockMode.OnlySelector, obstacles); } public void Update () { // Create a new Path object var path = ABPath.Construct(transform.position, target.position, null); // Make the path use a specific traversal provider path.traversalConstraint.traversalProvider = traversalProvider; // Calculate the path synchronously [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[StartPath](https://arongranberg.com/astar/docs/astarpath/startpath.html#StartPath) (path); path.BlockUntilCalculated(); if (path.error) { Debug.Log("No path was found"); } else { Debug.Log("A path was found with " + path.vectorPath.Count + " nodes"); // Draw the path in the scene view for (int i = 0; i < path.vectorPath.Count - 1; i++) { Debug.DrawLine(path.vectorPath[i], path.vectorPath[i + 1], Color.red); } } } } ` This script will calculate a path every frame from its own position to the target's position while using a TraversalProvider that was created to make the path avoid any obstacles in the specified list. The BlockManager.TraversalProvider has 2 modes: AllExceptSelector and OnlySelector. If the AllExceptSelector mode is set, then all nodes blocked by SingleNodeBlocker components will be treated as unwalkable **except** those in the specified list. This is useful if you, for example, want a unit to avoid all units except itself, or maybe you want it to avoid all units on its own team but no opponents. When the OnlySelector is set, then all nodes which are blocked by SingleNodeBlockers in the list will be treated as unwalkable. For performance reasons, it is a good idea to keep the selector list relatively small. See [Pathfinding.BlockManager.BlockMode](https://arongranberg.com/astar/docs/blockmanager.html#BlockMode) Create a new GameObject with the name "Target" and position it at, for example, (3.5, 0, 3.5). Also create a GameObject named "Path Searcher" and add the new BlockerPathTest component to it. Move the object to the position (-2.5, 0, 3.5) and assign the "Block Manager" and "Target" fields. Now press play; you should see a red line that goes from the "Path Searcher" to the "Target". Note that it passes through the sphere as if it was not there. This is because we haven't added it to the "Obstacles" list on the searcher. If you stop the game and then add the sphere's SingleNodeBlocker component to the list and press play again, you should see that it is now being avoided. Your browser does not support the video tag. Now we could easily expand this to, for example, create a number of red spheres and a number of blue spheres and make two searchers where one considers just the blue spheres as obstacles and one considers just the red spheres as obstacles. You can see this in the video below. Your browser does not support the video tag. ITraversalProvider ------------------ The above system works for simple cases and is pretty easy to use. However, for more complicated cases, it is better to use the [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) interface. You can read more about that in [Agent-Specific Pathfinding](https://arongranberg.com/astar/docs/traversal_provider.html) . --- # Moving a graph at runtime - A* Pathfinding Project Moving a graph at runtime ========================= How to move a graph at runtime. Why would I want to move a graph at runtime? -------------------------------------------- There are several reasons why you might want to move a graph at runtime: You have loaded a graph from a file, but it is not quite where you want it to be placed. You want to move the whole world to a new position, and you want the graph to move with it. You want to move and resize the graph to cover, for example, a procedurally generated level, and then scan the graph at the new position. You want to move the graph to follow an agent around in a very big, or even infinite, procedural world. See If you want to create a graph from scratch, take a look at [Creating graphs during runtime](https://arongranberg.com/astar/docs/runtimegraphs.html) . How do I move a graph at runtime? --------------------------------- The way to move a graph depends on the graph type, but you'll generally first assign new settings to the graph, and then use the **RelocateNodes** method on the graph to actually move the nodes. Some graphs have an overload of the RelocateNodes method, which allows you to specify the orientation settings directly. The RelocateNodes method has a few different overloads, but the most common usage can be seen in the code snippets below: For the grid graph/layered grid graph: `// Move the graph to the origin, with no rotation, and with a node size of 1.0 var gg = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .gridGraph; gg.RelocateNodes(center: Vector3.zero, rotation: Quaternion.identity, nodeSize: 1.0f); `For the recast graph: `[AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) (() => { // Move the graph to the point (20, 10, 10), rotated 45 degrees around the X axis var graph = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .recastGraph; graph.forcedBoundsCenter = new Vector3(20, 10, 10); graph.rotation = new Vector3(45, 0, 0); graph.RelocateNodes(graph.CalculateTransform()); }); `For the navmesh graph: `[AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) ((System.Action)(() => { // Move the graph to the point (20, 10, 10), rotated 45 degrees around the X axis var graph = AstarPath.active.data.navmeshGraph; graph.offset = new Vector3(20, 10, 10); graph.rotation = new Vector3(45, 0, 0); graph.RelocateNodes((GraphTransform)graph.CalculateTransform()); })); ` Scanning a graph at a new position ---------------------------------- If you want to move a graph and then scan it at the new position, you can insert a Scan call at the end: `[AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) (() => { // Move the graph to the origin, with no rotation, and with a node size of 1.0 var gg = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .gridGraph; gg.RelocateNodes(center: Vector3.zero, rotation: Quaternion.identity, nodeSize: 1.0f); }); [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[FlushWorkItems](https://arongranberg.com/astar/docs/astarpath/flushworkitems.html#FlushWorkItems) (); // Scan the graph at the new position [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) (); ` Move a graph to follow an agent ------------------------------- If you have a big, or even infinite, procedural world, you may want to have a graph that is centered on the player and follows the player as they move around. This can technically be done by moving the graph and scanning it very often, but that is not very efficient. Instead, you may want to use the [ProceduralGraphMover](https://arongranberg.com/astar/docs/proceduralgraphmover.html) component, which can move a grid, layered grid or recast graph around at runtime much more efficiently by only recalculating the nodes that are actually affected by the movement. Note that in contrast to the methods above, the ProceduralGraphMover will leave existing nodes at their original world positions, and instead only change the graph bounds to cover a different part of the world. Your browser does not support the video tag. See [ProceduralGraphMover](https://arongranberg.com/astar/docs/proceduralgraphmover.html) [Large worlds](https://arongranberg.com/astar/docs/largeworlds.html) --- # CircularBuffer - A* Pathfinding Project Struct CircularBuffer Extends IReadOnlyList, IReadOnlyCollection ====================================================================== Public Implements an efficient circular buffer that can be appended to in both directions. See [NativeCircularBuffer](https://arongranberg.com/astar/docs/nativecircularbuffer.html) Public Methods -------------- [AddRange](https://arongranberg.com/astar/docs/circularbuffer/addrange.html#AddRange) (items) Appends a list of items to the end of the buffer. [CircularBuffer](https://arongranberg.com/astar/docs/circularbuffer/circularbuffer.html) (...) Create a new buffer... [Clear](https://arongranberg.com/astar/docs/circularbuffer/clear.html#Clear) () Resets the buffer's length to zero. [Clone](https://arongranberg.com/astar/docs/circularbuffer/clone.html#Clone) () [GetAbsolute](https://arongranberg.com/astar/docs/circularbuffer/getabsolute.html#GetAbsolute) (index) Indexes the buffer using absolute indices. [GetBoundaryValue](https://arongranberg.com/astar/docs/circularbuffer/getboundaryvalue.html#GetBoundaryValue) (start) Return either the first element or the last element. [GetEnumerator](https://arongranberg.com/astar/docs/circularbuffer/getenumerator.html) () [Grow](https://arongranberg.com/astar/docs/circularbuffer/grow.html#Grow) () [InsertAbsolute](https://arongranberg.com/astar/docs/circularbuffer/insertabsolute.html#InsertAbsolute) (index, item) Inserts an item at the given absolute index. [MoveAbsolute](https://arongranberg.com/astar/docs/circularbuffer/moveabsolute.html#MoveAbsolute) (startIndex, endIndex, deltaIndex) [Pool](https://arongranberg.com/astar/docs/circularbuffer/pool.html#Pool) () Release the backing array of this buffer back into an array pool. [Pop](https://arongranberg.com/astar/docs/circularbuffer/pop.html#Pop) (fromStart) Pops either from the start or from the end of the buffer. [PopEnd](https://arongranberg.com/astar/docs/circularbuffer/popend.html#PopEnd) () Removes and returns the last element. [PopStart](https://arongranberg.com/astar/docs/circularbuffer/popstart.html#PopStart) () Removes and returns the first element. [Push](https://arongranberg.com/astar/docs/circularbuffer/push.html#Push) (toStart, item) Pushes a new item to the start or the end of the buffer. [PushEnd](https://arongranberg.com/astar/docs/circularbuffer/pushend.html#PushEnd) (item) Pushes a new item to the end of the buffer. [PushStart](https://arongranberg.com/astar/docs/circularbuffer/pushstart.html#PushStart) (item) Pushes a new item to the start of the buffer. [SetAbsolute](https://arongranberg.com/astar/docs/circularbuffer/setabsolute.html#SetAbsolute) (index, value) [Splice](https://arongranberg.com/astar/docs/circularbuffer/splice.html#Splice) (startIndex, toRemove, toInsert) Removes **toRemove** items from the buffer, starting at **startIndex**, and then inserts the **toInsert** items at **startIndex**. [SpliceAbsolute](https://arongranberg.com/astar/docs/circularbuffer/spliceabsolute.html#SpliceAbsolute) (startIndex, toRemove, toInsert) Like [Splice](https://arongranberg.com/astar/docs/circularbuffer/splice.html#Splice) , but **startIndex** is an absolute index. [SpliceUninitialized](https://arongranberg.com/astar/docs/circularbuffer/spliceuninitialized.html#SpliceUninitialized) (startIndex, toRemove, toInsert) Like [Splice](https://arongranberg.com/astar/docs/circularbuffer/splice.html#Splice) , but the newly inserted items are left in an uninitialized state. [SpliceUninitializedAbsolute](https://arongranberg.com/astar/docs/circularbuffer/spliceuninitializedabsolut.html#SpliceUninitializedAbsolute) (startIndex, toRemove, toInsert) Like [SpliceUninitialized](https://arongranberg.com/astar/docs/circularbuffer/spliceuninitialized.html#SpliceUninitialized) , but **startIndex** is an absolute index. Public Variables ---------------- AbsoluteEndIndex Absolute index of the last item in the buffer, may be negative or greater than [Length](https://arongranberg.com/astar/docs/circularbuffer.html#Length) . Public Readonly ##### int AbsoluteEndIndex Absolute index of the last item in the buffer, may be negative or greater than [Length](https://arongranberg.com/astar/docs/circularbuffer.html#Length) . AbsoluteStartIndex Absolute index of the first item in the buffer, may be negative or greater than [Length](https://arongranberg.com/astar/docs/circularbuffer.html#Length) . Public Readonly ##### int AbsoluteStartIndex Absolute index of the first item in the buffer, may be negative or greater than [Length](https://arongranberg.com/astar/docs/circularbuffer.html#Length) . Count Public Readonly ##### int IReadOnlyCollection(); } public static Vector3 CalculateDestination (Vector3 position, Vector3 target, Vector3 targetUp, float radius, float offset) { var normal = (position - target).normalized; var tangent = Vector3.Cross(normal, targetUp); return target + normal * radius + tangent * offset; } void Update () { ai.destination = CalculateDestination(ai.position, target.position, target.up, radius, offset); } ` See This is implemented in the [MoveInCircle](https://arongranberg.com/astar/docs/moveincircle.html) component included in the package. You can use the same kind of setup to make the agent follow a target at an offset: update the agent's destination every frame to the target's position plus an offset. Note This solution will be smoothest with the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) movement script, as it repairs its path every time you set the destination, to make it always up to date. It will work for other movement scripts as well, but you may have to reduce the time between path recalculations to make it smoother. See [AIDestinationSetter](https://arongranberg.com/astar/docs/aidestinationsetter.html) [Patrol](https://arongranberg.com/astar/docs/patrol.html) --- # GridLookup - A* Pathfinding Project Class GridLookup ================ Public Holds a lookup datastructure to quickly find objects inside rectangles. Objects of type T occupy an integer rectangle in the grid and they can be moved efficiently. You can query for all objects that touch a specified rectangle that runs in O(m\*k+r) time where m is the number of objects that the query returns, k is the average number of cells that an object occupies and r is the area of the rectangle query. All objects must be contained within a rectangle with one point at the origin (inclusive) and one at [size](https://arongranberg.com/astar/docs/gridlookup.html#size) (exclusive) that is specified in the constructor. Inner Types ----------- [Item](https://arongranberg.com/astar/docs/item.html) [Root](https://arongranberg.com/astar/docs/root.html) Public Methods -------------- [Add](https://arongranberg.com/astar/docs/gridlookup/add.html#Add) (item, bounds) Add an object to the lookup data structure. [Clear](https://arongranberg.com/astar/docs/gridlookup/clear.html#Clear) () [Dirty](https://arongranberg.com/astar/docs/gridlookup/dirty.html#Dirty) (item) [GetRoot](https://arongranberg.com/astar/docs/gridlookup/getroot.html#GetRoot) (item) [GridLookup](https://arongranberg.com/astar/docs/gridlookup/gridlookup.html#GridLookup) (size) [Move](https://arongranberg.com/astar/docs/gridlookup/move.html#Move) (item, bounds) Move an object to occupy a new set of cells. [QueryRect](https://arongranberg.com/astar/docs/gridlookup/queryrect.html#QueryRect) (r) Returns all objects of a specific type inside the cells marked by the rectangle. [Remove](https://arongranberg.com/astar/docs/gridlookup/remove.html#Remove) (item) Removes an item from the lookup data structure. [Resize](https://arongranberg.com/astar/docs/gridlookup/resize.html#Resize) (newBounds) Public Variables ---------------- AllItems Linked list of all items. Public ##### [Root](https://arongranberg.com/astar/docs/root.html) AllItems Linked list of all items. Private/Protected Members ------------------------- all Linked list of all items. Private ##### [Root](https://arongranberg.com/astar/docs/root.html) all = new [Root](https://arongranberg.com/astar/docs/root.html) () Linked list of all items. Note that the first item in the list is a dummy item and does not contain any data. cells Private ##### [Item](https://arongranberg.com/astar/docs/item.html) \[\] cells itemPool Private ##### Stack<[Item](https://arongranberg.com/astar/docs/item.html) \> itemPool = new Stack<[Item](https://arongranberg.com/astar/docs/item.html) \>() rootLookup Private ##### Dictionary rootLookup = new Dictionary() size Private ##### Vector2Int size --- # Detecting obstacles along a line - A* Pathfinding Project Detecting obstacles along a line ================================ Tutorial on how to use linecasting to detect if there is line of sight between two points. Contents -------- * [Introduction](https://arongranberg.com/astar/docs/linecasting.html#linecasting-intro) * [Simple linecasting](https://arongranberg.com/astar/docs/linecasting.html#linecasting-simple) * [Advanced linecasting](https://arongranberg.com/astar/docs/linecasting.html#linecasting-advanced) * [Line of sight between two nodes](https://arongranberg.com/astar/docs/linecasting.html#linecasting-grid) * [Use case: charge attacks](https://arongranberg.com/astar/docs/linecasting.html#linecasting-use-cases) Introduction ------------ Raycasting and linecasting are common in games to detect obstacles in the world. Often one will query the colliders in the scene, using for example [Unity's Physics class](https://docs.unity3d.com/ScriptReference/Physics.html) . However, when using this package, it is also possible to query the **navmesh** for obstacles. Your browser does not support the video tag. Simple linecasting ------------------ The most basic form of linecasting is to check if there is a straight path between two points. This can be done using the [AstarPath.Linecast](https://arongranberg.com/astar/docs/astarpath/linecast.html) method: `var start = transform.position; var end = start + Vector3.forward * 10; if ([AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[Linecast](https://arongranberg.com/astar/docs/astarpath/linecast.html#Linecast) (start, end)) { Debug.DrawLine(start, end, Color.red); } else { Debug.DrawLine(start, end, Color.green); } `You can also query a specific graph. However this graph needs to implement the [IRaycastableGraph](https://arongranberg.com/astar/docs/iraycastablegraph.html) interface (which grid graphs, navmesh graphs and recast graphs do). This slightly faster, and it also allows you to get more information about the hit (see next section). `var gg = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .gridGraph; bool anyObstaclesInTheWay = gg.Linecast(transform.position, enemy.position); ` Advanced linecasting -------------------- You may want to get more information about the hit, such as the exact point where the line hit the obstacle. Or get information about which nodes the line passed through on its way to the target. ![](https://arongranberg.com/astar/docs/images/linecast.png) This can be done by querying a specific graph and using an overload that outputs a [GraphHitInfo](https://arongranberg.com/astar/docs/graphhitinfo.html) . `var graph = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .recastGraph; var start = transform.position; var end = start + Vector3.forward * 10; var trace = new List(); var traversalConstraint = TraversalConstraint.None; traversalConstraint.tags = 1 << 3; // Only allow traversing nodes with tag 3 if (graph.Linecast(start, end, out GraphHitInfo hit, ref traversalConstraint, trace)) { Debug.Log("Linecast traversed " + trace.Count + " nodes before hitting an obstacle"); Debug.DrawLine(start, hit.point, Color.red); Debug.DrawLine(hit.point, end, Color.blue); } else { Debug.Log("Linecast traversed " + trace.Count + " nodes"); Debug.DrawLine(start, end, Color.green); } `The [GraphHitInfo](https://arongranberg.com/astar/docs/graphhitinfo.html) struct contains the following data: origin Start of the segment/ray. Note that the point passed to the Linecast method will be clamped to the surface on the navmesh, but it will be identical when seen from above. See This setting corresponds to the member [GraphHitInfo.origin](https://arongranberg.com/astar/docs/graphhitinfo.html#origin) point Hit point. This is typically a point on the border of the navmesh. In case no obstacle was hit then this will be set to the endpoint of the segment. If the origin was inside an unwalkable node, then this will be set to the origin point. See This setting corresponds to the member [GraphHitInfo.point](https://arongranberg.com/astar/docs/graphhitinfo.html#point) node Node which contained the edge which was hit. If the linecast did not hit anything then this will be set to the last node along the line's path (the one which contains the endpoint). For layered grid graphs the linecast will return true (i.e: no free line of sight) if, when walking the graph, we ended up at the right X,Z coordinate for the end node, but the end node was on a different level (e.g the floor below or above in a building). In this case no node edge was really hit so this field will still be null. If the origin was inside an unwalkable node, then this field will be set to that node. If no node could be found which contained the origin, then this field will be set to null. See This setting corresponds to the member [GraphHitInfo.node](https://arongranberg.com/astar/docs/graphhitinfo.html#node) tangentOrigin Where the tangent starts. [tangentOrigin](https://arongranberg.com/astar/docs/graphhitinfo.html#tangentOrigin) and [tangent](https://arongranberg.com/astar/docs/graphhitinfo.html#tangent) together actually describes the edge which was hit. ![](https://arongranberg.com/astar/docs/images/linecast_tangent.png) If nothing was hit, this will be Vector3.zero. See This setting corresponds to the member [GraphHitInfo.tangentOrigin](https://arongranberg.com/astar/docs/graphhitinfo.html#tangentOrigin) tangent Tangent of the edge which was hit. ![](https://arongranberg.com/astar/docs/images/linecast_tangent.png) If nothing was hit, this will be Vector3.zero. In some cases, an obstruction could be reported, but no edge was hit per se. For example if the origin was inside an unwalkable node. In those cases this field will be set to Vector3.zero. See This setting corresponds to the member [GraphHitInfo.tangent](https://arongranberg.com/astar/docs/graphhitinfo.html#tangent) distance Distance from [origin](https://arongranberg.com/astar/docs/graphhitinfo.html#origin) to [point](https://arongranberg.com/astar/docs/graphhitinfo.html#point) . See This setting corresponds to the member [GraphHitInfo.distance](https://arongranberg.com/astar/docs/graphhitinfo.html#distance) See [GraphHitInfo](https://arongranberg.com/astar/docs/graphhitinfo.html) Line of sight between two nodes ------------------------------- On grid graphs, there is a convenience function for checking for line of sight between the centers of two nodes: `var gg = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .gridGraph; var node1 = gg.GetNode(2, 3); var node2 = gg.GetNode(5, 7); bool anyObstaclesInTheWay = gg.Linecast(node1, node2); ` Use case: charge attacks ------------------------ Assume you have an enemy with a charge attack. When it sees the player, and is close enough, you want it to quickly run towards the player. However, you don't want the enemy to charge through walls or other obstacles. Something like this pseudocode: `if (enemy is close enough && there is a straight path to the player) { charge towards the player } ` Here's how it will look: Your browser does not support the video tag. Using Unity's Physics raycasting is not enough here. The enemy could be standing on the other side of a ravine, and a physics raycast would not detect that. Instead, we can use the navmesh to detect if there is a clear path to the player. Putting everything together into a working script, we get something like this: `#if MODULE_ENTITIES using UnityEngine; using System.Collections; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) ; namespace Pathfinding.Examples { public class ChargeBehaviour : MonoBehaviour { bool isCharging = false; public float maxChargingDistance = 10; public float chargeDuration = 0.5f; FollowerEntity ai = null; void Awake () { ai = GetComponent(); } void Update () { // Check if target is close (but not too close) and there is a straight path to it bool reasonableDistance = ai.remainingDistance< maxChargingDistance && ai.remainingDistance > maxChargingDistance * 0.1f; bool lineOfSight = ![AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[Linecast](https://arongranberg.com/astar/docs/astarpath/linecast.html#Linecast) (ai.position, ai.destination); if (!isCharging && reasonableDistance && lineOfSight) { // Charge the player StartCoroutine(Charge(ai.destination)); } } IEnumerator Charge (Vector3 point) { isCharging = true; var start = ai.position; // Disable the agent's own movement while charging ai.simulateMovement = false; ai.rotation = Quaternion.LookRotation(point - ai.position); // Override the velocity, in case some animation is using this value to adjust the animation speed ai.velocity = (point - start) / chargeDuration; // Move towards the target point over chargeDuration seconds // In a real game you'll want to do something more sophisticated than this for (float t = 0; t < chargeDuration; t += Time.deltaTime) { Debug.DrawLine(start, point, Color.red); transform.position = Vector3.Lerp(start, point, t / chargeDuration); yield return null; } ai.velocity = Vector3.zero; yield return new WaitForSeconds(1f); // Enable the agent's movement again ai.simulateMovement = true; isCharging = false; } } } #endif ` --- # Spherical world - A* Pathfinding Project Spherical world =============== Example scene which demonstrates pathfinding on spherical worlds and other strange shapes. Your browser does not support the video tag. The scene contains one spherical world and one box world. Two agents exist at the start, but you can create more by pressing the P key. Local avoidance is also enabled in the scene, so the agents will avoid each other, even on these non-planar worlds. Graph setup ----------- ![](https://arongranberg.com/astar/docs/images/generated/scenes/Spherical/graphsettings@2x.png) ![](https://arongranberg.com/astar/docs/images/generated/scenes/Spherical/graphs.png) For spherical worlds, a navmesh graph is really the only option. Neither grid graphs nor recast graphs can be automatically generated on a spherical world, or any other shape that is not at least somewhat planar. This scene has two navmesh graphs, one for a sphere and one for a collapsed box shape. These navmeshes have been modeled by hand in a 3D modeling application, and then imported into Unity. See Read more about spherical [Graph Types](https://arongranberg.com/astar/docs/graphs.html) in [Spherical Worlds](https://arongranberg.com/astar/docs/spherical.html) . [Creating a navmesh manually](https://arongranberg.com/astar/docs/createnavmesh.html) Movement scripts ---------------- This example uses the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) movement script to allow it to move on the spherical navmesh. You can read more about this here: [Movement scripts](https://arongranberg.com/astar/docs/spherical.html#spherical-movement) . --- # Creating graphs during runtime - A* Pathfinding Project Creating graphs during runtime ============================== How to create graphs during runtime from a script. If for some reason you cannot create the graph and set its settings during design time in the Unity editor, it is possible to create graphs directly using scripting. Note Note that you can save and load both graph settings and complete scanned graphs from files. For more info about that, see [Saving and Loading Graphs](https://arongranberg.com/astar/docs/saveloadgraphs.html) . Usually, you can define most of the settings in the Unity editor, and then when the game starts, only adjust a few values using a script and then re-scan the graph. You can create a graph like this: `// This holds all graph data AstarData data = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) ; // This creates a Grid Graph GridGraph gg = data.AddGraph(typeof(GridGraph)) as GridGraph; `The graph objects have all the settings that are exposed in the graph editor, so you can set them to any values you want, and then scan the graph. `// This holds all graph data AstarData data = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) ; // This creates a Grid Graph GridGraph gg = data.AddGraph(typeof(GridGraph)) as GridGraph; // Setup a grid graph with some values int width = 50; int depth = 50; float nodeSize = 1; gg.center = new Vector3(10, 0, 0); // Updates internal size from the above values gg.SetDimensions(width, depth, nodeSize); // Scans all graphs [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) (); `If you want to create a completely custom graph with your own nodes and connections, you can use a point graph like this: `// This holds all graph data AstarData data = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) ; // Create a Point Graph. Identical to adding it via the AstarPath inspector PointGraph graph = data.AddGraph(); // Scan the graph to initialize it. It will just be empty afterwards, though. graph.Scan(); // Make sure we only modify the graph when all pathfinding threads are paused [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) (() => { // Add 2 nodes and connect them var node1 = graph.AddNode((Int3) new Vector3(1, 2, 3)); var node2 = graph.AddNode((Int3) new Vector3(4, 5, 6)); var cost = (uint)(node2.position - node1.position).costMagnitude; GraphNode.Connect(node1, node2, cost); }); // Run the above work item immediately [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[FlushWorkItems](https://arongranberg.com/astar/docs/astarpath/flushworkitems.html#FlushWorkItems) (); `Or you can create your own custom graph type. For more info about that, take a look at [Writing Graph Generators](https://arongranberg.com/astar/docs/writinggraphgenerators.html) . See [Graph Types](https://arongranberg.com/astar/docs/graphtypes.html) --- # Path Types - A* Pathfinding Project Path Types ========== Example scene which demonstrates different path types. ![](https://arongranberg.com/astar/docs/images/generated/scenes/PathTypes/multitargetpath.png) Contents -------- * [Overview](https://arongranberg.com/astar/docs/example_path_types.html#example_path_types_overview) * [Graph setup](https://arongranberg.com/astar/docs/example_path_types.html#example_path_types_graph) * [Path types](https://arongranberg.com/astar/docs/example_path_types.html#example_path_types_path_types) * [ABPath](https://arongranberg.com/astar/docs/example_path_types.html#example_path_types_ABPath) * [MultiTargetPath](https://arongranberg.com/astar/docs/example_path_types.html#example_path_types_MultiTargetPath) * [RandomPath](https://arongranberg.com/astar/docs/example_path_types.html#example_path_types_RandomPath) * [FleePath](https://arongranberg.com/astar/docs/example_path_types.html#example_path_types_FleePath) * [ConstantPath](https://arongranberg.com/astar/docs/example_path_types.html#example_path_types_ConstantPath) * [FloodPath and FloodPathTracer](https://arongranberg.com/astar/docs/example_path_types.html#example_path_types_FloodPath) Overview -------- The scene has a GUI interface on the left side of the screen which allows you to select different path types and see how they behave. If you enable gizmos in the game view, you should be able to see the graph and the paths that are being calculated. The [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component is set up to visualize the path search. After a path has been calculated, all searched nodes will be highlighted in blue. The paths themselves will be drawn in orange. As thin blue lines, you can also see the search tree. All of these lines converge on the start node, and they show the shortest path from the start node to all other nodes that were searched. This is done by setting [A\* Inspector → Settings → Debug → Show Search Tree](https://arongranberg.com/astar/docs/astarpath.html#showSearchTree) to true, and ensuring that the grid graph has the "Show Connections" option enabled. ![](https://arongranberg.com/astar/docs/images/generated/scenes/PathTypes/pathvisualization.png) See You can read more about how to calculate different types of paths in [Searching for paths](https://arongranberg.com/astar/docs/callingpathfinding.html) . Graph setup ----------- ![](https://arongranberg.com/astar/docs/images/generated/scenes/PathTypes/graphsettings@2x.png) ![](https://arongranberg.com/astar/docs/images/generated/scenes/PathTypes/graph.png) This example scene uses a grid graph for illustration purposes. Any other graph type could have been used, but grid graphs are usually the easiest to understand and reason about when it comes to the path visualizations. All path types shown here are supported on all graph types, but the [RandomPath](https://arongranberg.com/astar/docs/randompath.html) and [FleePath](https://arongranberg.com/astar/docs/fleepath.html) path types work better on grid graphs than navmesh/recast graphs, due to their higher granularity. Path types ---------- The scene demonstrates the following path types. ### ABPath ![](https://arongranberg.com/astar/docs/images/generated/scenes/PathTypes/abpath.png) This is the most common path type. It is used for point-to-point movement. It is used by default by all movement scripts. If you hold down the left mouse button in the game, you can see how the path is recalculated as you move the mouse around. Note The path visualization may flicker a lot while you do this. This is because the path is recalculated asynchronously on a separate thread, and when the gizmos are drawn, the path may still be in the process of being calculated. This is nothing to worry about. If you release the mouse button, the visualization will stabilize. `// Disable the automatic path recalculation. ai.canSearch = false; // Note: If you only want to calculate paths to a particular point, // using ai.destination is usually a better choice. var path = ABPath.Construct(ai.position, ai.position + Vector3.forward * 10); ai.SetPath(path); ` See [ABPath](https://arongranberg.com/astar/docs/abpath.html) ### MultiTargetPath ![](https://arongranberg.com/astar/docs/images/generated/scenes/PathTypes/multitargetpath.png) A multi-target path can be used in two scenarios: 1. You want to find the shortest paths from a single point to a number of other points, or from many points to a single target. 2. You want to find the path to the closest target out of a collection of them. You can switch between these two modes in the in-game GUI with the toggle "Only Shortest Path". In the image above, a single [MultiTargetPath](https://arongranberg.com/astar/docs/multitargetpath.html) has been calculated from the center to 4 different targets. Calculating all 4 paths at the same time is faster than calculating them one by one. This is especially true if you have many targets, or if the targets are close to each other, as the paths will share a large part of the searched nodes. To test it in the example scene, use shift+click to add targets to the path, and then left-click to calculate the path. `var targets = new Vector3[] { ai.position + Vector3.forward * 5, ai.position + Vector3.right * 10, ai.position + Vector3.back * 15 }; // Disable the automatic path recalculation. ai.canSearch = false; var path = MultiTargetPath.Construct(ai.position, targets, null, null); // Only calculate a path to the closest target path.pathsForAll = false; ai.SetPath(path); ` See [MultiTargetPath](https://arongranberg.com/astar/docs/multitargetpath.html) ### RandomPath Your browser does not support the video tag. A random path is useful for wandering agents, and possibly for procedurally generating world features. The random path will search outwards from its start point and will pick a target node with a path cost somewhere between \[search distance\] and \[search distance\] + \[spread\], which you can configure in the GUI. You can also specify an aim strength which will make the path more likely to move towards the endpoint (specified by the cursor). `// Disable the automatic path recalculation ai.canSearch = false; // Make the AI move in a random direction. // The path will be about 20 world units long (the default cost of moving 1 world unit is 1000). var path = FleePath.Construct(ai.position, 1000 * 20); path.spread = 5000; ai.SetPath(path); ` See [RandomPath](https://arongranberg.com/astar/docs/randompath.html) [Wandering AI Tutorial](https://arongranberg.com/astar/docs/wander.html) ### FleePath This is essentially the same as a [RandomPath](https://arongranberg.com/astar/docs/randompath.html) , but the path will try to move away from the endpoint instead of towards it. Make sure to use a flee strength greater than zero, to make the path move away from the cursor. `// Disable the automatic path recalculation ai.canSearch = false; var pointToAvoid = enemy.position; // Make the AI flee from the enemy. // The path will be about 20 world units long (the default cost of moving 1 world unit is 1000). var path = FleePath.Construct(ai.position, pointToAvoid, 1000 * 20); ai.SetPath(path); ` See [FleePath](https://arongranberg.com/astar/docs/fleepath.html) ### ConstantPath ![](https://arongranberg.com/astar/docs/images/generated/scenes/PathTypes/constantpath.png) The constant path does not calculate a path; instead, it finds all nodes an agent could reach given a maximum path cost. This is useful, for example, in turn-based games, where you may want to visualize all nodes an agent can reach on their turn. You can get the output nodes from the [ConstantPath.allNodes](https://arongranberg.com/astar/docs/constantpath.html#allNodes) field. These are also sorted by their cost from the starting node. However, it is not possible to directly access the costs, as they are not saved by this path type. `// Here you create a new path and set how far it should search. ConstantPath cpath = ConstantPath.Construct(transform.position, 20000, null); [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[StartPath](https://arongranberg.com/astar/docs/astarpath/startpath.html#StartPath) (cpath); // Block until the path has been calculated. You can also calculate it asynchronously // by providing a callback in the constructor above. cpath.BlockUntilCalculated(); // Draw a line upwards from all nodes within range for (int i = 0; i < cpath.allNodes.Count; i++) { Debug.DrawRay((Vector3)cpath.allNodes[i].position, Vector3.up, Color.red, 2f); } ` See [ConstantPath](https://arongranberg.com/astar/docs/constantpath.html) [PathUtilities.BFS](https://arongranberg.com/astar/docs/pathutilities/bfs.html#BFS) works in a similar way, but it does not use path costs, it only uses the number of steps to reach a node. ### FloodPath and FloodPathTracer The [FloodPath](https://arongranberg.com/astar/docs/floodpath.html) is a bit special, because it does not do anything useful by itself. What it does is calculate paths to all nodes it can reach; it floods the graph. This data will remain stored in the path. Then you can calculate a [FloodPathTracer](https://arongranberg.com/astar/docs/floodpathtracer.html) path. That path will trace the path from its starting point all the way to where the original FloodPath started. A FloodPathTracer search is extremely fast compared to a normal path request. To test it in the example scene: 1. Select the **FloodPath** mode 2. Click where you want the FloodPath to start 3. Select the **FloodPathTracer** mode 4. Click and hold to calculate paths from the cursor to the start point of the FloodPath You can check the console to see how long the [FloodPathTracer](https://arongranberg.com/astar/docs/floodpathtracer.html) took to calculate. It should be very fast compared to the [ABPath](https://arongranberg.com/astar/docs/abpath.html) . This path type can be useful in games where you spawn a lot of agents, and they all have to move to the same target (e.g., a tower-defense game). See [FloodPath](https://arongranberg.com/astar/docs/floodpath.html) [FloodPathTracer](https://arongranberg.com/astar/docs/floodpathtracer.html) --- # Item - A* Pathfinding Project Class Item ========== Package Public Variables ---------------- prev Public ##### [Item](https://arongranberg.com/astar/docs/item.html) prev root Public ##### [Root](https://arongranberg.com/astar/docs/root.html) root Private/Protected Members ------------------------- next Private ##### [Item](https://arongranberg.com/astar/docs/item.html) next --- # Root - A* Pathfinding Project Class Root ========== Public Public Variables ---------------- next Next item in the linked list of all roots. Public ##### [Root](https://arongranberg.com/astar/docs/root.html) next Next item in the linked list of all roots. obj Underlying object. Public ##### T obj Underlying object. previousPosition Public ##### UnityEngine.Vector3 previousPosition = new UnityEngine.Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity) previousRotation Public ##### UnityEngine.Quaternion previousRotation Private/Protected Members ------------------------- flag Internal ##### bool flag items References to an item in each grid cell that this object is contained inside. Internal ##### List<[Item](https://arongranberg.com/astar/docs/item.html) \> items = new List<[Item](https://arongranberg.com/astar/docs/item.html) \>() References to an item in each grid cell that this object is contained inside. prev Previous item in the linked list of all roots. Internal ##### [Root](https://arongranberg.com/astar/docs/root.html) prev Previous item in the linked list of all roots. previousBounds Internal ##### [IntRect](https://arongranberg.com/astar/docs/intrect.html) previousBounds = new [IntRect](https://arongranberg.com/astar/docs/intrect.html) (0, 0, -1, -1) --- # Extending The System - A* Pathfinding Project Extending The System ==================== The system can be extended in various ways. Check the subpages for more info. * [Writing Graph Generators](https://arongranberg.com/astar/docs/writinggraphgenerators.html) * [Writing Modifiers](https://arongranberg.com/astar/docs/writemodifiers.html) --- # Pathfinding from editor scripts - A* Pathfinding Project Pathfinding from editor scripts =============================== This page shows how to get pathfinding working outside of play mode from e.g. an editor script. Pathfinding in editor mode, i.e. when the game is not running at all in the Unity editor, works in the same way as in play mode, with the only major difference being that path requests are synchronous, i.e. they will be calculated immediately. Normally, path requests are asynchronous and may take several frames to calculate. To get it working, you must, however, first initialize the pathfinding system because in editor mode, graphs may not have been deserialized, and the graphs may not be scanned. The [AstarPath.FindAstarPath](https://arongranberg.com/astar/docs/astarpath/findastarpath.html#FindAstarPath) method will make sure that the [AstarPath.active](https://arongranberg.com/astar/docs/astarpath.html#active) property is set and that all graphs have been deserialized (they are stored as a byte array internally). `// Make sure the AstarPath object has been loaded [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[FindAstarPath](https://arongranberg.com/astar/docs/astarpath/findastarpath.html#FindAstarPath) (); [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) (); `If you think a graph might have been scanned, but you are not sure (for example, you might run a particular editor script several times), then you can check first. `// Check if the first grid graph in the scene is scanned, and if not, scan it immediately if (![AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .gridGraph.isScanned) [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) (); `After this, you can request paths as usual. The example below uses the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component directly, but using a Seeker component should work just as well. `ABPath path = ABPath.Construct(transform.position, target.position); [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[StartPath](https://arongranberg.com/astar/docs/astarpath/startpath.html#StartPath) (path); // Everything is synchronous so the path is calculated now Debug.Log("Found a path with " + path.vectorPath.Count + " points. The error log says: " + path.errorLog); // Draw the path in the scene view for (int i = 0; i < path.vectorPath.Count - 1; i++) { Debug.DrawLine(path.vectorPath[i], path.vectorPath[i+1], Color.red); } ` See [Searching for paths](https://arongranberg.com/astar/docs/callingpathfinding.html) --- # Manual Player Movement - A* Pathfinding Project Manual Player Movement ====================== This page describes how to move a character manually using the A\* [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) Project. Contents -------- * [Introduction](https://arongranberg.com/astar/docs/playermovement.html#playermovement_intro) * [Case studies](https://arongranberg.com/astar/docs/playermovement.html#playermovement_cases) * [Keyboard movement with pathfinding](https://arongranberg.com/astar/docs/playermovement.html#playermovement_manual_keyboard) * [Keyboard movement without pathfinding](https://arongranberg.com/astar/docs/playermovement.html#playermovement_manual_keyboard2) * [Point and click movement](https://arongranberg.com/astar/docs/playermovement.html#playermovement_point_and_click) Introduction ------------ In your game, you may want to control the player character using the keyboard or a game pad, or perhaps using point-and-click movement. This tutorial describes a few different setups that you can use. Case studies ------------ ### Keyboard movement with pathfinding Using the keyboard to move a character is a common way to control characters in games. It is often used in action games, platformers, and other games where the player directly controls the character's movement. Usually, the WASD or arrow keys are used to move the character. To achieve this, you can use one of the built-in movement scripts, and continuously set the destination of the agent to a point a few meters away from the character, in the direction indicated by the current keyboard input. Your browser does not support the video tag. `using UnityEngine; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) ; public class PlayerMovement : MonoBehaviour { public float lookaheadDistance = 1f; IAstarAI ai; void OnEnable () { ai = GetComponent(); } void Update () { // Check the current keyboard input var dx = Input.GetAxis("Horizontal"); var dz = Input.GetAxis("Vertical"); // Get the first enabled camera var cam = Camera.allCameras[0]; // Calculate movement directions relative to the camera var forward = cam.transform.forward; forward.y = 0; forward.Normalize(); var right = cam.transform.right; right.y = 0; right.Normalize(); // Set the destination of the AI to a point a few meters ahead of the character, // in the desired direction. ai.destination = transform.position + (dx * right + dz * forward) * lookaheadDistance; } } `In the video, you can see the current path in orange. Note how, even when trying to move into an obstacle, the agent will automatically move around it. This is a significant advantage of using pathfinding even for these very short paths. Be mindful of what you set the "slowdown time" or "slowdown distance" (depending on the movement script) to. If you set it too low, the agent will move very slowly because the destination that you set will always be pretty close to the agent when using this method. Note This method works best with the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) movement script, due to how it repairs its path automatically every frame, leading to very responsive movement. If you have other NPCs in your game, you may want to use local avoidance to make the NPCs avoid the player character. Typically, you don't want the player to avoid NPCs, though. This can be done by changing the local avoidance settings, which are either on the [RVOController](https://arongranberg.com/astar/docs/rvocontroller.html) component, or directly on the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component if you are using that movement script. In particular, on the player character, we want to drag the priority up to maximum, and set the Collides With mask to Nothing. This will make the player ignore all other agents, but other agents will still avoid the player, and prioritize avoiding the player over other agents. ### Keyboard movement without pathfinding Using your own movement code for the player character, instead of using any of the built-in movement scripts, is also possible. In this case, you may also want to integrate with local avoidance to make the other agents in your game avoid the player character. You can do this by attaching an [RVOController](https://arongranberg.com/astar/docs/rvocontroller.html) component to the player character. In your movement code, you can then manually set the [RVOController's velocity](https://arongranberg.com/astar/docs/rvocontroller.html#velocity) to the desired velocity of the character. Setting the velocity manually will make the local avoidance system mark this agent as manually controlled, and other agents will just have to deal with it. Note You have to set the velocity every frame, or the local avoidance system will think the agent is not manually controlled anymore. `void Update () { var x = Input.GetAxis("Horizontal"); var y = Input.GetAxis("Vertical"); var v = new Vector3(x, 0, y) * speed; // Override the RVOController's velocity. This will disable local avoidance calculations for one simulation step. rvo.velocity = v; transform.position += v * Time.deltaTime; } `If you also want to clamp your agent to the navmesh, you could use the [NavmeshClamp](https://arongranberg.com/astar/docs/navmeshclamp.html) component. ### Point and click movement Point and click movement is a common way to move characters in games. It is often used in strategy games, RPGs, and other games where the player does not directly control the character's movement. This is a perfect use case for using the built-in movement scripts in the A\* [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) Project, and is very simple to implement. Whenever you want to move your player to a point, you can set the [destination](https://arongranberg.com/astar/docs/iastarai.html#destination) property on the movement script to this point. Your browser does not support the video tag. `void PointAndClick (IAstarAI ai) { // Check if the mouse button is pressed if (Input.GetMouseButton(0)) { var cam = Camera.main; // Make the raycast hit all colliders LayerMask mask = -1; // Shoot a ray from the cursor, to see where in the world it hits if (Physics.Raycast(cam.ScreenPointToRay(Input.mousePosition), out var hit, Mathf.Infinity, mask)) { // Set the destination of the AI to the point where the ray hit ai.destination = hit.point; } } } ` See The [TargetMover](https://arongranberg.com/astar/docs/targetmover.html) component is used in the example scenes to provide this kind of movement. Local avoidance can be handled in the same way as in [Keyboard movement with pathfinding](https://arongranberg.com/astar/docs/playermovement.html#playermovement_manual_keyboard) . --- # VersionedMonoBehaviour - A* Pathfinding Project Class VersionedMonoBehaviour Extends MonoBehaviourGizmos, [ISerializationCallbackReceiver](https://docs.unity3d.com/ScriptReference/ISerializationCallbackReceiver.html) , [IVersionedMonoBehaviourInternal](https://arongranberg.com/astar/docs/iversionedmonobehaviourinternal.html) , [IEntityIndex](https://arongranberg.com/astar/docs/ientityindex.html) =============================================================================================================================================================================================================================================================================================================================================================== Public Base class for all components in the package. Private/Protected Members ------------------------- [Awake](https://arongranberg.com/astar/docs/versionedmonobehaviour/awake.html#Awake) () [DisableGizmosIcon](https://arongranberg.com/astar/docs/versionedmonobehaviour/disablegizmosicon.html#DisableGizmosIcon) () EntityIndex Internal entity index used by [BatchedEvents](https://arongranberg.com/astar/docs/batchedevents.html) . Private ##### int EntityIndex Internal entity index used by [BatchedEvents](https://arongranberg.com/astar/docs/batchedevents.html) . Should never be modified by other scripts. [OnAfterDeserialize](https://arongranberg.com/astar/docs/versionedmonobehaviour/onafterdeserialize.html#OnAfterDeserialize) () Handle serialization backwards compatibility. [OnBeforeSerialize](https://arongranberg.com/astar/docs/versionedmonobehaviour/onbeforeserialize.html#OnBeforeSerialize) () Handle serialization backwards compatibility. [OnUpgradeSerializedData](https://arongranberg.com/astar/docs/versionedmonobehaviour/onupgradeserialize.html#OnUpgradeSerializedData) (migrations, unityThread) Handle serialization backwards compatibility. [Reset](https://arongranberg.com/astar/docs/versionedmonobehaviour/reset.html#Reset) () Handle serialization backwards compatibility. [UpgradeFromUnityThread](https://arongranberg.com/astar/docs/versionedmonobehaviour/upgradefromunityth.html#UpgradeFromUnityThread) () [UpgradeSerializedData](https://arongranberg.com/astar/docs/versionedmonobehaviour/upgradeserializedd.html#UpgradeSerializedData) (isUnityThread) version Version of the serialized data. Private ##### int version = 0 Version of the serialized data. Used for script upgrades. --- # Hexagonal Turn Based - A* Pathfinding Project Hexagonal Turn Based ==================== Example scene which demonstrates turn-based movement and custom traversal rules. ![](https://arongranberg.com/astar/docs/images/generated/scenes/HexagonalTurnBased/overview.png) Overview -------- This example scene shows turn-based movement on a hexagonal grid. It does not use the normal movement scripts, but instead handles movement for all characters in a single script. Note Turn-based movement can, of course, be done with the included movement scripts as well. The scene presents a simple puzzle game. You can click on the orange cones to show their movement range, and then you can move them by clicking on a separate tile. If you move an orange cone to a purple hexagon, you will get the option to toggle a set of green "door" hexagons. The goal of the puzzle is to get one orange cone to the purple hexagon in the red area to the right of the screen. Graph setup ----------- ![](https://arongranberg.com/astar/docs/images/generated/scenes/HexagonalTurnBased/graphsettings@2x.png) ![](https://arongranberg.com/astar/docs/images/generated/scenes/HexagonalTurnBased/graphs.png) A hexagonal grid graph is used in this scene. It is configured by creating a [GridGraph](https://arongranberg.com/astar/docs/gridgraph.html) , and then changing the **Shape** dropdown to **Hexagonal**. For hexagonal graphs, there are two different measurements that one can use to size them. In this scene we set the width (distance between opposing sides) of the hexagons to 1 world unit, but it is also possible to use the diameter (distance between opposing vertices). Note If you are building a 2D game with a Tilemap component, you can align the graph to your tilemap directly. See [Pathfinding on tilemaps](https://arongranberg.com/astar/docs/tilemaps.html) . You may notice that the hexagonal graph looks like a squished rectangle. This is because a hexagonal graph is internally actually just a grid graph which has been squished and connected in a different way. For some games, you may get some wasted nodes outside your level, but this is usually nothing to worry about, performance-wise. To align all the hexagonal meshes in the scene with the graph, a script called [SnapToNode](https://arongranberg.com/astar/docs/snaptonode.html) is used. This runs even in edit mode, and will snap the transform to the closest node every time the transform is moved. `void Update () { if (transform.hasChanged && [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) != null) { var node = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (transform.position).node; if (node != null) { transform.position = (Vector3)node.position; transform.hasChanged = false; } } } `This makes it easy to move around prefabs in the scene view, and have them automatically snap to the closest hexagon node. See [AstarPath.GetNearest(Vector3,NearestNodeConstraint)](https://arongranberg.com/astar/docs/astarpath/getnearest.html) Purple triggers --------------- The purple hexagons in the scene are triggered using Unity's built-in **OnTriggerEnter** function. This is handled by the [HexagonTrigger](https://arongranberg.com/astar/docs/hexagontrigger.html) class. In this method, the script checks if the object is an agent, and if so, if the unit has this node as its target node, or if it is merely passing through. If the checks pass, an animation is played. `void OnTriggerEnter (Collider coll) { var unit = coll.GetComponentInParent(); var node = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (transform.position).node; // Check if it is an agent and the agent is headed for this node if (unit != null && unit.targetNode == node) { visible = true; anim.CrossFade("show", 0.1f); } } `The animation will either reveal a button, or for the final one, show a victory message. The buttons that are revealed can toggle the traversability of the green hexagons. If a button is clicked, it calls [TurnBasedDoor.Toggle](https://arongranberg.com/astar/docs/turnbaseddoor/toggle.html#Toggle) on the relevant green hexagons. In turn, this will play an animation, and use the [SingleNodeBlocker](https://arongranberg.com/astar/docs/singlenodeblocker.html) component to block or unblock the node underneath the green hexagon. See [Utilities for turn-based games](https://arongranberg.com/astar/docs/turnbased.html) For more info about how the [SingleNodeBlocker](https://arongranberg.com/astar/docs/singlenodeblocker.html) component works. Agent movement -------------- Movement in this example scene is a bit different from the other ones, in that it does not use one of the built-in movement scripts. Instead, it uses a custom script, [TurnBasedManager](https://arongranberg.com/astar/docs/turnbasedmanager.html) to handle all movement. This is not a requirement for a turn-based game, but it illustrates an alternative approach to movement. This manager does a few things: * It listens for mouse clicks, and selects or moves agents depending on what was clicked. * If an agent is selected, it shows all nodes it can move to within one turn. * When an agent moves, it animates the agent's position along a smoothed version of the path. * It triggers the [SingleNodeBlocker](https://arongranberg.com/astar/docs/singlenodeblocker.html) on each agent when they move, so that the other agent cannot move to the same hexagon. ### Movement animation To move the agents, the [TurnBasedManager.MoveAlongPath](https://arongranberg.com/astar/docs/turnbasedmanager/movealongpath.html#MoveAlongPath) method is used. It uses a [catmull-rom spline](https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Catmull%E2%80%93Rom_spline) to smoothly interpolate between the points in the path. ` static IEnumerator MoveAlongPath (TurnBasedAI unit, ABPath path, float speed) { if (path.error || path.vectorPath.Count == 0) throw new System.ArgumentException("Cannot follow an empty path"); // Very simple movement, just interpolate using a catmull-rom spline float distanceAlongSegment = 0; for (int i = 0; i < path.vectorPath.Count - 1; i++) { var p0 = path.vectorPath[Mathf.Max(i-1, 0)]; // Start of current segment var p1 = path.vectorPath[i]; // End of current segment var p2 = path.vectorPath[i+1]; var p3 = path.vectorPath[Mathf.Min(i+2, path.vectorPath.Count-1)]; // Approximate the length of the spline var segmentLength = Vector3.Distance(p1, p2); // Move the agent forward each frame, until we reach the end of the segment while (distanceAlongSegment < segmentLength) { // Use a Catmull-rom spline to smooth the path. See https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Catmull%E2%80%93Rom_spline var interpolatedPoint = AstarSplines.CatmullRom(p0, p1, p2, p3, distanceAlongSegment / segmentLength); unit.transform.position = interpolatedPoint; yield return null; distanceAlongSegment += Time.deltaTime * speed; } distanceAlongSegment -= segmentLength; } // Move the agent to the final point in the path unit.transform.position = path.vectorPath[path.vectorPath.Count - 1]; } ` ### Movement range To show the movement range, a [ConstantPath](https://arongranberg.com/astar/docs/constantpath.html) is used. This is a special path type which outputs all nodes that can be reached up to a given maximum path cost. Therefore, it is perfect for generating all nodes that an agent can reach in one turn. See Take a look at the [Path Types](https://arongranberg.com/astar/docs/example_path_types.html) example scene for more info about the [ConstantPath](https://arongranberg.com/astar/docs/constantpath.html) type. This is handled by the [TurnBasedManager.GeneratePossibleMoves](https://arongranberg.com/astar/docs/turnbasedmanager/generatepossiblemoves.html#GeneratePossibleMoves) method. It synchronously (for simplicity) calculates a [ConstantPath](https://arongranberg.com/astar/docs/constantpath.html) , iterates through all nodes in the path, and instantiates a prefab on each node's position. `void GeneratePossibleMoves (TurnBasedAI unit) { var path = ConstantPath.Construct(unit.transform.position, unit.movementPoints * 1000 + 1); path.traversalConstraint.traversalProvider = unit.traversalProvider; // Schedule the path for calculation [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[StartPath](https://arongranberg.com/astar/docs/astarpath/startpath.html#StartPath) (path); // Force the path request to complete immediately // This assumes the graph is small enough that // this will not cause any lag path.BlockUntilCalculated(); foreach (var node in path.allNodes) { if (node != path.startNode) { // Create a new node prefab to indicate a node that can be reached // NOTE: If you are going to use this in a real game, you might want to // use an object pool to avoid instantiating new GameObjects all the time var go = GameObject.Instantiate(nodePrefab, (Vector3)node.position, Quaternion.identity) as GameObject; possibleMoves.Add(go); go.GetComponent().node = node; } } } ` --- # Point graph in a 3D game - A* Pathfinding Project Point graph in a 3D game ======================== Example scene which demonstrates a point graph in a 3D level. Your browser does not support the video tag. This example scene demonstrates how to use a point graph in a 3D game. It contains a number of "road segments" under a common root object called "Roads". The positions of all these road segments are used as nodes in the point graph. See To read more, check out the [Get started with point graphs](https://arongranberg.com/astar/docs/getstartedpoint.html) tutorial, which is based on this scene. --- # ProceduralGraphMover - A* Pathfinding Project Class ProceduralGraphMover Extends [VersionedMonoBehaviour](https://arongranberg.com/astar/docs/versionedmonobehaviour.html) ============================================================================================================================= Public Moves a grid or recast graph to follow a target. ![](https://arongranberg.com/astar/docs/images/generated/inspectors/ProceduralGraphMover@2x.png) This is useful if you have a very large, or even infinite, world, but pathfinding is only necessary in a small region around an object (for example the player). This component will move a graph around so that its center stays close to the [target](https://arongranberg.com/astar/docs/proceduralgraphmover.html#target) object. Note This component can only be used with grid graphs, layered grid graphs and (tiled) recast graphs. **Usage** Take a look at the example scene called "Procedural" for an example of how to use this script Attach this to some object in the scene and assign the target to e.g the player. Then the graph will follow that object around as it moves. Your browser does not support the video tag. Your browser does not support the video tag. **Performance** When the graph is moved you may notice an fps drop. If this grows too large you can try a few things: General advice: * Turn on multithreading (A\* Inspector -> Settings) * Make sure you have 'Show [Graphs](https://arongranberg.com/astar/docs/graphs2.html) ' disabled in the A\* inspector, since gizmos in the scene view can take some time to update when the graph moves, and thus make it seem like this script is slower than it actually is. For grid graphs: * Avoid using any erosion in the grid graph settings. This is relatively slow. Each erosion iteration requires expanding the region that is updated by 1 node. * Reduce the grid size or resolution. * Reduce the [updateDistance](https://arongranberg.com/astar/docs/proceduralgraphmover.html#updateDistance) . This will make the updates smaller but more frequent. This only works to some degree however since an update has an inherent overhead. * Disable Height Testing or Collision Testing in the grid graph if you can. This can give a performance boost since fewer calls to the physics engine need to be done. For recast graphs: * Rasterize colliders instead of meshes. This is typically faster. * Use a reasonable tile size. Very small tiles can cause more overhead, and too large tiles might mean that you are updating too much in one go. Typical values are around 64 to 256 voxels. * Use a larger cell size. A lower cell size will give better quality graphs, but it will also be slower to scan. The graph updates will be offloaded to worker threads as much as possible. See [Large worlds](https://arongranberg.com/astar/docs/largeworlds.html) Public Methods -------------- [UpdateGraph](https://arongranberg.com/astar/docs/proceduralgraphmover/updategraph.html#UpdateGraph) (async=true) Updates the graph asynchronously. Public Variables ---------------- graph Graph to update. Public ##### [NavGraph](https://arongranberg.com/astar/docs/navgraph.html) graph Graph to update. This will be set at Start based on [graphIndex](https://arongranberg.com/astar/docs/proceduralgraphmover.html#graphIndex) . During runtime you may set this to any graph or to null to disable updates. graphIndex Index for the graph to update. Public ##### int graphIndex Index for the graph to update. This will be used at Start to set [graph](https://arongranberg.com/astar/docs/proceduralgraphmover.html#graph) . This is an index into the AstarPath.active.data.graphs array. target Graph will be moved to follow this target. Public ##### [Transform](https://docs.unity3d.com/ScriptReference/Transform.html) target Graph will be moved to follow this target. updateDistance Grid graphs will be updated if the target is more than this number of nodes from the graph center. Public ##### float updateDistance = 10 Grid graphs will be updated if the target is more than this number of nodes from the graph center. Note that this is in nodes, not world units. Note For recast graphs, this setting has no effect. updatingGraph True while the graph is being updated by this script. Public ##### bool updatingGraph True while the graph is being updated by this script. Private/Protected Members ------------------------- [Awake](https://arongranberg.com/astar/docs/versionedmonobehaviour/awake.html#Awake) () [OnDisable](https://arongranberg.com/astar/docs/proceduralgraphmover/ondisable.html#OnDisable) () [OnUpgradeSerializedData](https://arongranberg.com/astar/docs/versionedmonobehaviour/onupgradeserialize.html#OnUpgradeSerializedData) (migrations, unityThread) Handle serialization backwards compatibility. [RecastGraphTileShift](https://arongranberg.com/astar/docs/proceduralgraphmover/recastgraphtileshift.html#RecastGraphTileShift) (graph, targetCenter) [Reset](https://arongranberg.com/astar/docs/versionedmonobehaviour/reset.html#Reset) () Handle serialization backwards compatibility. [Start](https://arongranberg.com/astar/docs/proceduralgraphmover/start.html#Start) () [Update](https://arongranberg.com/astar/docs/proceduralgraphmover/update.html#Update) () Update is called once per frame. [UpdateGridGraph](https://arongranberg.com/astar/docs/proceduralgraphmover/updategridgraph.html#UpdateGridGraph) (graph, async) [UpdateRecastGraph](https://arongranberg.com/astar/docs/proceduralgraphmover/updaterecastgraph.html#UpdateRecastGraph) (graph, delta, async) [UpgradeSerializedData](https://arongranberg.com/astar/docs/versionedmonobehaviour/upgradeserializedd.html#UpgradeSerializedData) (isUnityThread) --- # Navmesh Graph - A* Pathfinding Project Navmesh Graph ============= Example scene which uses a navmesh graph. ![](https://arongranberg.com/astar/docs/images/generated/scenes/NavmeshGraph/overview.png) Graph setup ----------- ![](https://arongranberg.com/astar/docs/images/generated/scenes/NavmeshGraph/graphsettings@2x.png) The graph used in this scene is a [NavMeshGraph](https://arongranberg.com/astar/docs/navmeshgraph.html) . This is a completely manually modeled graph, which means that it does not use any automatic generation. Such graphs are more time-consuming to create, but in return you get full control over how they look. In most cases, an automatically generated [RecastGraph](https://arongranberg.com/astar/docs/recastgraph.html) is a better choice, but navmesh graphs can be useful in some cases. For example, if you get a mesh from an external source, or if you want to do pathfinding on a spherical world, then a navmesh graph can be a good choice. You can also create a manual navmesh which is just a quad (or some other simple shape), and then use the [NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) component to cut holes in it to represent all obstacles. This leads to a pretty flexible system for games where you do a lot of building. However, it can lead to a navmesh which does not have a great quality (lots of thin triangles). Using a recast graph and graph updates that recalculate tiles from scratch will usually lead to a higher quality navmesh, though it can be slower, depending on your world complexity and graph settings. See [Creating a navmesh manually](https://arongranberg.com/astar/docs/createnavmesh.html) [Using navmeshes](https://arongranberg.com/astar/docs/getstarted2.html) [Spherical Worlds](https://arongranberg.com/astar/docs/spherical.html) --- # HierarchicalBitset - A* Pathfinding Project Struct HierarchicalBitset ========================= Public Thread-safe hierarchical bitset. Stores an array of bits. Each bit can be set or cleared individually from any thread. Note Setting the capacity is not thread-safe, nor is iterating over the bitset while it is being modified. Inner Types ----------- [Iterator](https://arongranberg.com/astar/docs/iterator.html) Public Methods -------------- [Clear](https://arongranberg.com/astar/docs/hierarchicalbitset/clear.html#Clear) () Clear all bits. [Count](https://arongranberg.com/astar/docs/hierarchicalbitset/count.html#Count) () Number of set bits in the bitset. [Dispose](https://arongranberg.com/astar/docs/hierarchicalbitset/dispose.html#Dispose) () [Get](https://arongranberg.com/astar/docs/hierarchicalbitset/get.html#Get) (index) Get the value of a bit. [GetIndices](https://arongranberg.com/astar/docs/hierarchicalbitset/getindices.html#GetIndices) (result) [GetIterator](https://arongranberg.com/astar/docs/hierarchicalbitset/getiterator.html#GetIterator) (scratchBuffer) Get an iterator over all set bits. [HierarchicalBitset](https://arongranberg.com/astar/docs/hierarchicalbitset/hierarchicalbitset.html#HierarchicalBitset) (size, allocator) [Reset](https://arongranberg.com/astar/docs/hierarchicalbitset/reset.html#Reset) (index) Set a given bit to 0. [Set](https://arongranberg.com/astar/docs/hierarchicalbitset/set.html#Set) (index) Set a given bit to 1. Public Static Methods --------------------- [ResetAtomic](https://arongranberg.com/astar/docs/hierarchicalbitset/resetatomic.html#ResetAtomic) (span, index) [SetAtomic](https://arongranberg.com/astar/docs/hierarchicalbitset/setatomic.html#SetAtomic) (span, index) Public Variables ---------------- Capacity Public ##### int Capacity IsCreated Public ##### bool IsCreated IsEmpty True if the bitset is empty. Public ##### bool IsEmpty True if the bitset is empty. allocator Public ##### Allocator allocator l1 Public ##### [UnsafeSpan](https://arongranberg.com/astar/docs/unsafespan.html) l1 l2 Public ##### [UnsafeSpan](https://arongranberg.com/astar/docs/unsafespan.html) l2 l3 Public ##### [UnsafeSpan](https://arongranberg.com/astar/docs/unsafespan.html) l3 Public Static Variables ----------------------- Log64 Public Static ##### const int Log64 = 6 --- # DebugLimitsCtx - A* Pathfinding Project Struct DebugLimitsCtx ===================== Private Public Variables ---------------- debugFloor Public ##### float debugFloor debugMode Public ##### [GraphDebugMode](https://arongranberg.com/astar/docs/pathfinding.html#GraphDebugMode) debugMode debugPathID Public ##### ushort debugPathID debugPathNodes Public ##### [UnsafeSpan](https://arongranberg.com/astar/docs/unsafespan.html) <[GlobalNodeStorage.DebugPathNode](https://arongranberg.com/astar/docs/debugpathnode.html) \> debugPathNodes debugRoof Public ##### float debugRoof --- # Editing graph connections manually - A* Pathfinding Project Editing graph connections manually ================================== How to make edits to the graph structure. Sometimes the graph is almost right, but there may be some cases where you need it fixed up a bit. This is most common with the point graph and this page is mostly intended for that graph type. The methods do work for other graph types as well to some extent, however. See [Off-mesh links](https://arongranberg.com/astar/docs/offmeshlinks2.html) if you want to handle jumping, climbing, teleporters and other special movement logic. The NodeLink component ---------------------- If you have a point graph where you want to either add a connection, remove an existing connection or perhaps change the cost of some connection, then you can use the [NodeLink](https://arongranberg.com/astar/docs/nodelink.html) component. Point graphs are generally created from a collection of GameObjects. You can add the NodeLink component to one node and then set the target to another node. By changing the options, the component can then either add a new connection between those two nodes, remove an already existing connection (if one exists) or change the cost of the connection between them. These new connections are identical to the ones created by the point graph originally. ![](https://arongranberg.com/astar/docs/images/generated/inspectors/NodeLink@2x.png) To make it easier to modify the graph, there are some keyboard shortcuts. You can find the menu items in Unity under menubar → Edit → Pathfinding. * **alt+ctrl+L** (**alt+cmd+L** on macOS): Link two nodes. Connect the nodes if there is no NodeLink connection between them. If they are already connected, then explicitly delete their connection. * **alt+ctrl+U** (**alt+cmd+U** on macOS): Unlink two nodes. This removes the NodeLink components that link the two nodes, regardless of whether the NodeLink is configured to add or delete a connection. * **alt+ctrl+B** (**alt+cmd+B** on macOS): Destroy all NodeLink components on the selected GameObjects. Editing graph connections using code ------------------------------------ You can also modify graph connections using code. `// Connect two nodes var node1 = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (transform.position, NearestNodeConstraint.None).node; var node2 = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (transform.position + Vector3.right, NearestNodeConstraint.None).node; var cost = (uint)(node2.position - node1.position).costMagnitude; GraphNode.Connect(node1, node2, cost, OffMeshLinks.Directionality.TwoWay); ` See [GraphNode.Connect](https://arongranberg.com/astar/docs/graphnode/connect.html#Connect) [GraphNode.Disconnect](https://arongranberg.com/astar/docs/graphnode/disconnect.html#Disconnect) [GraphNode.ContainsOutgoingConnection](https://arongranberg.com/astar/docs/graphnode/containsoutgoingconnection.html#ContainsOutgoingConnection) [Graph Updates during Runtime](https://arongranberg.com/astar/docs/graphupdates.html) [Creating graphs during runtime](https://arongranberg.com/astar/docs/runtimegraphs.html) [Graph Types](https://arongranberg.com/astar/docs/graphtypes.html) --- # DestroyGraphPromise - A* Pathfinding Project Class DestroyGraphPromise Extends [IGraphUpdatePromise](https://arongranberg.com/astar/docs/igraphupdatepromise.html) ====================================================================================================================== Private Public Methods -------------- [Apply](https://arongranberg.com/astar/docs/destroygraphpromise/apply.html#Apply) (context) Applies the update in a single atomic update. [Prepare](https://arongranberg.com/astar/docs/destroygraphpromise/prepare.html#Prepare) () Coroutine to prepare an update asynchronously. Public Variables ---------------- graph Public ##### [IGraphInternals](https://arongranberg.com/astar/docs/igraphinternals.html) graph --- # Off-mesh links - A* Pathfinding Project Off-mesh links ============== Tutorial on how to use off-mesh links to implement jumps, climbing, teleporters and other special movement logic. Your browser does not support the video tag. Contents -------- * [Introduction](https://arongranberg.com/astar/docs/offmeshlinks2.html#offmeshlinks_intro) * [Setting up an off-mesh link](https://arongranberg.com/astar/docs/offmeshlinks2.html#offmeshlinks_setup) * [Case studies](https://arongranberg.com/astar/docs/offmeshlinks2.html#offmeshlinks_cases) * [Jumping off a ledge](https://arongranberg.com/astar/docs/offmeshlinks2.html#offmeshlink_ledge) * [Teleporter](https://arongranberg.com/astar/docs/offmeshlinks2.html#offmeshlink_teleporter) * [Opening a door](https://arongranberg.com/astar/docs/offmeshlinks2.html#offmeshlink_door) * [Custom off-mesh link traversal logic](https://arongranberg.com/astar/docs/offmeshlinks2.html#offmeshlink_event) Introduction ------------ Off-mesh links are custom connections between two nodes in a single graph, or even between different graphs. They are used for implementing special movement logic such as jumping, climbing, opening doors, teleporters and other things. Your browser does not support the video tag. When an agent reaches an off-mesh link, it will stop its normal movement code, and instead call a user-defined function. This function can then implement special movement logic, such as playing an animation, moving the agent to a different position, or anything else. The included movement scripts have varying levels of support for off-mesh links. * [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) : Good support for off-mesh links. * [RichAI](https://arongranberg.com/astar/docs/richai.html) : Decent support for off-mesh links. Does not support using the [Interactable](https://arongranberg.com/astar/docs/interactable.html) component for movement logic on off-mesh links. * [AIPath](https://arongranberg.com/astar/docs/aipath.html) : Limited support for off-mesh links. The agent can traverse them, but it does not know that it traverses an off-mesh link, and cannot use any special movement logic. * [AILerp](https://arongranberg.com/astar/docs/ailerp.html) : Limited support for off-mesh links. The agent can traverse them, but it does not know that it traverses an off-mesh link, and cannot use any special movement logic. Setting up an off-mesh link --------------------------- Off-mesh links are created using the [NodeLink2](https://arongranberg.com/astar/docs/nodelink2.html) component. ![](https://arongranberg.com/astar/docs/images/generated/scenes/Recast3D/droplinkinspector@2x.png) End End position of the link. See This setting corresponds to the member [NodeLink2.end](https://arongranberg.com/astar/docs/nodelink2.html#end) Cost Factor The connection will be this times harder/slower to traverse. A cost factor of 1 means that the link is equally expensive as moving the same distance on the normal navmesh. But a cost factor greater than 1 means that it is proportionally more expensive. You should not use a cost factor less than 1 unless you also change the [AstarPath.heuristicScale](https://arongranberg.com/astar/docs/astarpath.html#heuristicScale) field (A\* Inspector -> Settings -> [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) ) to at most the minimum cost factor that you use anywhere in the scene (or disable the heuristic altogether). This is because the pathfinding algorithm assumes that paths are at least as costly as walking just the straight line distance to the target, and if you use a cost factor less than 1, that assumption is no longer true. What then happens is that the pathfinding search may ignore some links because it doesn't even think to search in that direction, even if they would have lead to a lower path cost. Warning Reducing the heuristic scale or disabling the heuristic can significantly increase the cpu cost for pathfinding, especially for large graphs. Read more about this at [https://en.wikipedia.org/wiki/Admissible\_heuristic](https://en.wikipedia.org/wiki/Admissible_heuristic) . See This setting corresponds to the member [NodeLink2.costFactor](https://arongranberg.com/astar/docs/nodelink2.html#costFactor) One Way Make a one-way connection. See This setting corresponds to the member [NodeLink2.oneWay](https://arongranberg.com/astar/docs/nodelink2.html#oneWay) Pathfinding Tag The tag to apply to the link. This can be used to exclude certain agents from using the link, or make it more expensive to use. See [Working with tags](https://arongranberg.com/astar/docs/tags.html) See This setting corresponds to the member [NodeLink2.pathfindingTag](https://arongranberg.com/astar/docs/nodelink2.html#pathfindingTag) Graph Mask Which graphs this link is allowed to connect. The link will always connect the nodes closest to the start and end points on the graphs that it is allowed to connect. See This setting corresponds to the member [NodeLink2.graphMask](https://arongranberg.com/astar/docs/nodelink2.html#graphMask) The [NodeLink2](https://arongranberg.com/astar/docs/nodelink2.html) creates a link between its own position and the position of the target transform. By default, this link is bidirectional, meaning that the agent can traverse it in both directions. But it can also be configured to be one-way, which is useful for things like jumping down from ledges. A link can also have a tag applied to it. This is useful if you want to allow only specific agents to traverse it, or if you want to make it more expensive to traverse for some agents. Speaking of cost, the cost factor can be used to make the agent prefer to walk around the link instead of traversing it. A cost factor of 1 means that the link is equally expensive as moving the same distance on the normal navmesh. But a cost factor greater than 1 means that it is proportionally more expensive. To use a cost factor lower than one (useful for e.g. teleporters), you must do some additional configuration. Read more about this here: [NodeLink2.costFactor](https://arongranberg.com/astar/docs/nodelink2.html#costFactor) . Case studies ------------ The following sections will describe how to implement some common use cases for off-mesh links. ### Jumping off a ledge Your browser does not support the video tag. If a character needs to be able to jump off a ledge, you can add a one-way off-mesh link from the ledge to the ground below. This will allow the character to traverse the link, but not to traverse it in the opposite direction. ![](https://arongranberg.com/astar/docs/images/generated/scenes/RecastOffMeshLinks/droplinkinspector@2x.png) The default off-mesh link traversal logic will usually work for this, as it just moves the agent towards the end of the link while ignoring the navmesh. However, you may want to add some [custom logic](https://arongranberg.com/astar/docs/offmeshlinks2.html#offmeshlink_event) to play an animation or to make the character jump in a more realistic way. ### Teleporter Your browser does not support the video tag. A teleporter can also be implemented using an off-mesh link. However, this requires some custom logic to move the agent to the new position. This can be done in multiple ways, but the simplest one is to use the [Interactable](https://arongranberg.com/astar/docs/interactable.html) component, which is included with the example scenes. If the interactable component is attached to the same GameObject as a [NodeLink2](https://arongranberg.com/astar/docs/nodelink2.html) component, its workflow will trigger when the agent traverses the link. ![](https://arongranberg.com/astar/docs/images/generated/scenes/RecastOffMeshLinks/teleportinteractableinspector@2x.png) The workflow moves the agent to the end of the link, and also triggers some particle systems. However, to make the agent treat the teleport as a zero-cost action (instead of having a cost proportional to the teleportation distance), we must do a few things. First, we must set the cost factor of the link component to 0. ![](https://arongranberg.com/astar/docs/images/generated/scenes/RecastOffMeshLinks/teleportlinkinspector@2x.png) Secondly, we must set the A\* Inspector → Settings → [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) → [Heuristic](https://arongranberg.com/astar/docs/astarpath.html#heuristic) field to None. Otherwise, the agent may walk around the teleporter because the pathfinding search will not even consider going in that direction. You can read more about this in the [NodeLink2.costFactor](https://arongranberg.com/astar/docs/nodelink2.html#costFactor) documentation. ### Opening a door Your browser does not support the video tag. There are several ways of handling doors that the agent should be able to open. * If the door is automatic, then excluding it from the graph scan and using a separate script to play an opening/closing animation depending on whether agents are near is a good solution. You should not use an off-mesh link in this case. * If the door requires activation the first time, but then it will stay open, you can use a [NodeLink2](https://arongranberg.com/astar/docs/nodelink2.html) component as described below. Create a [NodeLink2](https://arongranberg.com/astar/docs/nodelink2.html) component that goes from one side of the door to the other side. We will also use an [Interactable](https://arongranberg.com/astar/docs/interactable.html) component on the link to trigger the door opening animation. ![](https://arongranberg.com/astar/docs/images/generated/scenes/RecastOffMeshLinks/doorinteractableinspector@2x.png) The interactable component will make the agent do a few things. 1. Start the opening animation of the door (which will also make the navmesh traversable, see [Doors](https://arongranberg.com/astar/docs/example_recast_doors.html#example_recast_doors_doors) for more info). 2. Move the agent to the start of the link, and make it face the door (the agent should already be at the door when it starts traversing the link, so this is primarily for the rotation). 3. Wait a few seconds for the door to open. 4. Deactivate the off-mesh link. The last step is perhaps unintuitive, but it works very well for this use case. What happens is that when the door opens, it will make the navmesh underneath it traversable. Then, when we deactivate the link, the agent will be forced to recalculate its path, and it will find the new path through the door without using the link this time. In the future, the door will stay open and agents will be able to just walk through. If necessary, one could also make the door close after a while and re-activate the off-mesh link. Custom off-mesh link traversal logic ------------------------------------ If you need custom off-mesh link traversal logic, for example to play custom animations, or move the character in ways specific to your game, you can register a callback to control every aspect of the traversal. Register your handler to the [FollowerEntity.onTraverseOffMeshLink](https://arongranberg.com/astar/docs/followerentity.html#onTraverseOffMeshLink) or [RichAI.onTraverseOffMeshLink](https://arongranberg.com/astar/docs/richai.html#onTraverseOffMeshLink) properties, depending on which movement script you are using. Alternatively, you can use the [NodeLink2.onTraverseOffMeshLink](https://arongranberg.com/astar/docs/nodelink2.html#onTraverseOffMeshLink) property to register a callback for a specific off-mesh link. Note The [AIPath](https://arongranberg.com/astar/docs/aipath.html) and [AILerp](https://arongranberg.com/astar/docs/ailerp.html) movement scripts do not support custom movement during off-mesh link traversal. This section will focus on the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) . The [RichAI](https://arongranberg.com/astar/docs/richai.html) has similar functionality, but the API looks slightly different and is a bit more limited. You can assign any class as a handler if it implements the [IOffMeshLinkHandler](https://arongranberg.com/astar/docs/ioffmeshlinkhandler.html) interface. This interface has a single method, [GetOffMeshLinkStateMachine](https://arongranberg.com/astar/docs/ioffmeshlinkhandler/getoffmeshlinkstatema.html#GetOffMeshLinkStateMachine) , which should return an object that implements the [IOffMeshLinkStateMachine](https://arongranberg.com/astar/docs/ioffmeshlinkstatemachine.html) interface. The state machine interface has several methods that you can override to control different parts of the traversal. OnTraverseOffMeshLink (context) Called when an agent traverses an off-mesh link. This method should be a coroutine (i.e return an IEnumerable) which will be iterated over until it finishes, or the agent is destroyed. The coroutine should yield null every frame until the agent has finished traversing the link. When the coroutine completes, the agent will be assumed to have reached the end of the link and control will be returned to the normal movement code. The coroutine typically moves the agent to the end of the link over some time, and perform any other actions that are necessary. For example, it could play an animation, or move the agent in a specific way. See This setting corresponds to the member [IOffMeshLinkStateMachine.OnTraverseOffMeshLink](https://arongranberg.com/astar/docs/ioffmeshlinkstatemachine/ontraverseoffmes.html#OnTraverseOffMeshLink) OnFinishTraversingOffMeshLink (context) Called when an agent finishes traversing an off-mesh link. This can be used to perform any cleanup that is necessary after the traversal. Either [OnFinishTraversingOffMeshLink](https://arongranberg.com/astar/docs/ioffmeshlinkstatemachine/onfinishtraversi.html#OnFinishTraversingOffMeshLink) or [OnAbortTraversingOffMeshLink](https://arongranberg.com/astar/docs/ioffmeshlinkstatemachine/onaborttraversin.html#OnAbortTraversingOffMeshLink) will be called, but not both. See This setting corresponds to the member [IOffMeshLinkStateMachine.OnFinishTraversingOffMeshLink](https://arongranberg.com/astar/docs/ioffmeshlinkstatemachine/onfinishtraversi.html#OnFinishTraversingOffMeshLink) OnAbortTraversingOffMeshLink () Called when an agent fails to finish traversing an off-mesh link. This can be used to perform any cleanup that is necessary after the traversal. An abort can happen if the agent was destroyed while it was traversing the link. It can also happen if the agent was teleported somewhere else while traversing the link. Either [OnFinishTraversingOffMeshLink](https://arongranberg.com/astar/docs/ioffmeshlinkstatemachine/onfinishtraversi.html#OnFinishTraversingOffMeshLink) or [OnAbortTraversingOffMeshLink](https://arongranberg.com/astar/docs/ioffmeshlinkstatemachine/onaborttraversin.html#OnAbortTraversingOffMeshLink) will be called, but not both. Warning When this is called, the agent may already be destroyed. The handler component itself could also be destroyed at this point. See This setting corresponds to the member [IOffMeshLinkStateMachine.OnAbortTraversingOffMeshLink](https://arongranberg.com/astar/docs/ioffmeshlinkstatemachine/onaborttraversin.html#OnAbortTraversingOffMeshLink) In the simplest case, you may only want to receive an event when the agent traverses a link, but fall back to the default movement implementation. You can do that like this: `using UnityEngine; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) ; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) .[ECS](https://arongranberg.com/astar/docs/ecs2.html) ; public class LogOffMeshLinkTraversal : MonoBehaviour, IOffMeshLinkHandler, IOffMeshLinkStateMachine { // Register this class as the handler for off mesh links when the component is enabled. // This component supports registering to both NodeLink2 and FollowerEntity. void OnEnable () { if (TryGetComponent(out var link)) link.onTraverseOffMeshLink = this; if (TryGetComponent(out var ai)) ai.onTraverseOffMeshLink = this; } void OnDisable () { if (TryGetComponent(out var link)) link.onTraverseOffMeshLink = null; if (TryGetComponent(out var ai)) ai.onTraverseOffMeshLink = null; } IOffMeshLinkStateMachine IOffMeshLinkHandler.GetOffMeshLinkStateMachine (AgentOffMeshLinkTraversalContext context) { Debug.Log("An agent started traversing an off-mesh link"); return this; } void IOffMeshLinkStateMachine.OnFinishTraversingOffMeshLink (AgentOffMeshLinkTraversalContext context) { Debug.Log("An agent finished traversing an off-mesh link"); } void IOffMeshLinkStateMachine.OnAbortTraversingOffMeshLink () { Debug.Log("An agent aborted traversing an off-mesh link"); } // Don't implement IOffMeshLinkStateMachine.OnTraverseOffMeshLink to fall back to the default implementation // System.Collections.IEnumerable IOffMeshLinkStateMachine.OnTraverseOffMeshLink(ECS.AgentOffMeshLinkTraversalContext context) } `The provided context object gives you some helper methods like [AgentOffMeshLinkTraversalContext.Teleport](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext/teleport.html#Teleport) and [AgentOffMeshLinkTraversalContext.MoveTowards](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext/movetowa.html#MoveTowards) , and it also provides you with access to various agent data. See [AgentOffMeshLinkTraversalContext](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext.html) You can also do more complex things, like controlling the position of the agent completely. In the example below, a jump link is implemented. The agent first rotates to face the other side of the link, and then "jumps" to the other side by moving along an arc controlled by a [bezier curve](https://en.wikipedia.org/wiki/B%C3%A9zier_curve) . `using UnityEngine; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) ; using System.[Collections](https://arongranberg.com/astar/docs/collections.html) ; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) .[ECS](https://arongranberg.com/astar/docs/ecs2.html) ; namespace Pathfinding.Examples { public class FollowerJumpLink : MonoBehaviour, IOffMeshLinkHandler, IOffMeshLinkStateMachine { // Register this class as the handler for off-mesh links when the component is enabled void [OnEnable](https://arongranberg.com/astar/docs/followerjumplink/onenable.html#OnEnable) () => GetComponent().onTraverseOffMeshLink = this; void [OnDisable](https://arongranberg.com/astar/docs/followerjumplink/ondisable.html#OnDisable) () => GetComponent().onTraverseOffMeshLink = null; IOffMeshLinkStateMachine IOffMeshLinkHandler.GetOffMeshLinkStateMachine(AgentOffMeshLinkTraversalContext context) => this; void IOffMeshLinkStateMachine.OnFinishTraversingOffMeshLink (AgentOffMeshLinkTraversalContext context) { Debug.Log("An agent finished traversing an off-mesh link"); } void IOffMeshLinkStateMachine.OnAbortTraversingOffMeshLink () { Debug.Log("An agent aborted traversing an off-mesh link"); } IEnumerable IOffMeshLinkStateMachine.OnTraverseOffMeshLink (AgentOffMeshLinkTraversalContext ctx) { var start = (Vector3)ctx.link.relativeStart; var end = (Vector3)ctx.link.relativeEnd; var dir = end - start; // Disable local avoidance while traversing the off-mesh link. // If it was enabled, it will be automatically re-enabled when the agent finishes traversing the link. ctx.DisableLocalAvoidance(); // Move and rotate the agent to face the other side of the link. // When reaching the off-mesh link, the agent may be facing the wrong direction. while (!ctx.MoveTowards( position: start, rotation: Quaternion.LookRotation(dir, ctx.movementPlane.up), gravity: true, slowdown: true).reached) { yield return null; } var bezierP0 = start; var bezierP1 = start + Vector3.up*5; var bezierP2 = end + Vector3.up*5; var bezierP3 = end; var jumpDuration = 1.0f; // Animate the AI to jump from the start to the end of the link for (float t = 0; t < jumpDuration; t += ctx.deltaTime) { ctx.transform.Position = AstarSplines.CubicBezier(bezierP0, bezierP1, bezierP2, bezierP3, Mathf.SmoothStep(0, 1, t / jumpDuration)); yield return null; } } } } `Attaching the above script to the same GameObject as a [NodeLink2](https://arongranberg.com/astar/docs/nodelink2.html) component will make the agent jump when it traverses the link, as can be seen in the video below. Your browser does not support the video tag. --- # GetNearest - A* Pathfinding Project Function [NavGraph](https://arongranberg.com/astar/docs/navgraph.html) .GetNearest ================================================================================== GetNearest ([Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) position) Returns the nearest node to a position. Public ##### [NNInfo](https://arongranberg.com/astar/docs/nninfo.html) GetNearest ( | | | | | --- | --- | --- | | [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) | position | The position to try to find the closest node to. | ) Returns the nearest node to a position. The returned [NNInfo](https://arongranberg.com/astar/docs/nninfo.html) will contain both the closest node, and the closest point on the surface of that node. The distance is measured to the closest point on the surface of the node. See You can use [AstarPath.GetNearest(Vector3)](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) instead, if you want to check all [Graph Types](https://arongranberg.com/astar/docs/graphs.html) . GetNearest ([Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) position, [NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) constraint) Nearest node to a position using the specified [NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) . Public ##### [NNInfo](https://arongranberg.com/astar/docs/nninfo.html) GetNearest ( | | | | | --- | --- | --- | | [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) | position | The position to try to find the closest node to. | | [NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) | constraint | Used to limit which nodes are considered acceptable. You may, for example, only want to consider walkable nodes. | ) Nearest node to a position using the specified [NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) . The returned [NNInfo](https://arongranberg.com/astar/docs/nninfo.html) will contain both the closest node, and the closest point on the surface of that node. The distance is measured to the closest point on the surface of the node. See You can use [AstarPath.GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html) instead, if you want to check all [Graph Types](https://arongranberg.com/astar/docs/graphs.html) . GetNearest ([Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) position, ref[NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) constraint) Public ##### [NNInfo](https://arongranberg.com/astar/docs/nninfo.html) GetNearest ( | | | | | --- | --- | --- | | [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) | position | | | ref[NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) | constraint | | ) GetNearest ([Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) position, [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) constraint) Returns the nearest node to a position using the specified [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) . Public ##### [NNInfo](https://arongranberg.com/astar/docs/nninfo.html) GetNearest ( | | | | | --- | --- | --- | | [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) | position | The position to try to find the closest node to. | | [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) | constraint | Used to limit which nodes are considered acceptable. You may, for example, only want to consider walkable nodes. If null, all nodes will be considered acceptable. | ) Returns the nearest node to a position using the specified [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) . The returned [NNInfo](https://arongranberg.com/astar/docs/nninfo.html) will contain both the closest node, and the closest point on the surface of that node. The distance is measured to the closest point on the surface of the node. See You can use [AstarPath.GetNearest(Vector3)](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) instead, if you want to check all [Graph Types](https://arongranberg.com/astar/docs/graphs.html) . Version Before 4.3.63, this method would not use the [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) in all cases. Deprecated Use the overload that takes a [NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) instead. --- # DummyGraphUpdateContext - A* Pathfinding Project Class DummyGraphUpdateContext Extends [IGraphUpdateContext](https://arongranberg.com/astar/docs/igraphupdatecontext.html) ========================================================================================================================== Private Public Methods -------------- [DirtyBounds](https://arongranberg.com/astar/docs/dummygraphupdatecontext/dirtybounds.html#DirtyBounds) (bounds) Mark a particular region of the world as having been changed. --- # Iterator - A* Pathfinding Project Struct Iterator Extends IEnumerator>, IEnumerable> ================================================================================== Public Public Methods -------------- [Dispose](https://arongranberg.com/astar/docs/iterator/dispose.html#Dispose) () [GetEnumerator](https://arongranberg.com/astar/docs/iterator/getenumerator.html) () [Iterator](https://arongranberg.com/astar/docs/iterator/iterator.html#Iterator) (bitSet, result) [MoveNext](https://arongranberg.com/astar/docs/iterator/movenext.html#MoveNext) () [MoveNextInternal](https://arongranberg.com/astar/docs/iterator/movenextinternal.html#MoveNextInternal) () [Reset](https://arongranberg.com/astar/docs/iterator/reset.html#Reset) () Public Static Methods --------------------- [MoveNextBurst](https://arongranberg.com/astar/docs/iterator/movenextburst.html#MoveNextBurst) (iter) [l1index](https://arongranberg.com/astar/docs/iterator/l1index.html#l1index) (l2index, l2bitIndex) [l2index](https://arongranberg.com/astar/docs/iterator/l2index.html#l2index) (l3index, l3bitIndex) Public Variables ---------------- Current Public ##### [UnsafeSpan](https://arongranberg.com/astar/docs/unsafespan.html) Current Current Public ##### object Current bitSet Public ##### [HierarchicalBitset](https://arongranberg.com/astar/docs/hierarchicalbitset.html) bitSet l2bitIndex Public ##### int l2bitIndex l3bitIndex Public ##### int l3bitIndex l3index Public ##### int l3index result Public ##### [UnsafeSpan](https://arongranberg.com/astar/docs/unsafespan.html) result resultCount Public ##### int resultCount --- # AllocatorData - A* Pathfinding Project Struct AllocatorData ==================== Public Public Variables ---------------- freeHeads () Public ##### unsafe fixed int freeHeads () mem Public ##### UnsafeList mem --- # Writing Graph Generators - A* Pathfinding Project Writing Graph Generators ======================== All graphs in the A\* Pathfinding Project are written as add-ons to the system, which makes it (relatively) easy to add your own specialized graph types. In this tutorial, I will show you how to set up a basic Graph Generator which you can use with the system. The complete script can be found here [PolarGraphGenerator.cs](https://arongranberg.com/astar/docs/polargraphgeneratorcs.html) A Basic Graph ------------- The simplest graph possible looks like this: `using System.Collections.Generic; using UnityEngine; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) ; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) .[Serialization](https://arongranberg.com/astar/docs/serialization.html) ; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) .[Util](https://arongranberg.com/astar/docs/util2.html) ; using Unity.Jobs; // Inherit our new graph from the base graph type [JsonOptIn] // Make sure the class is not stripped out when using code stripping (see https://docs.unity3d.com/Manual/ManagedCodeStripping.html) [[Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) .[Util](https://arongranberg.com/astar/docs/util2.html) .Preserve] public class SimpleGraph : NavGraph { // This should return true if the graph is scanned and can be used for pathfinding public override bool isScanned => true; class SimpleGraphScanPromise : IGraphUpdatePromise { public SimpleGraph graph; // In this method you may run async calculations required for updating the graph. // After this coroutine has finished, the Apply method will be called. // Any JobHandles that are yielded by this method will be waited for before the next iteration, and before the Apply method is called. public IEnumerator Prepare() => null; public void Apply (IGraphUpdateContext ctx) { // Here we will place our code for scanning the graph // Destroy previous nodes (if any) graph.DestroyAllNodes(); } } protected override IGraphUpdatePromise ScanInternal () => new SimpleGraphScanPromise { graph = this }; public override void GetNodes(GraphNode.NodeActionWithData action, ref T data) { // This method should call the delegate with all nodes in the graph } } ` This graph will not generate any nodes, but it should show up greyed out in the Add New Graph list. So let's start creating some scanning logic! Scanning -------- First, create a new script containing the code above, but rename it to PolarGraph and save it as PolarGraph.cs. The ScanInternal method is called when the graph should be scanned. A Scan method should create a number of nodes and create connections between them. We will create a Polar Graph, i.e., sort of like a grid, but laid out as a circle with rings instead of rows. I will use "circles" to denote the number of concentric rings in the graph and "steps" as the number of nodes in each circle. Note that in the image below, what you are seeing are the connections between the nodes. The nodes themselves are placed at the intersections between those line segments. ![](https://arongranberg.com/astar/docs/images/polarGraph.png) The first step is to create a temporary array for holding the nodes and add some variables for configuring the graph. We will use the PointNode node type which is used by the PointGraph since it contains essentially the same things that we want to use. `public int circles = 10; public int steps = 20; public Vector3 center = Vector3.zero; public float scale = 2; // Here we will store all nodes in the graph PointNode[] nodes; GraphTransform transform; // Create a single node at the specified position PointNode CreateNode (Vector3 position) { var node = new PointNode(active); // Node positions are stored as Int3. We can convert a Vector3 to an Int3 like this node.position = (Int3)position; return node; } public override IEnumerable ScanInternal () { // Create a 2D array which will contain all nodes // This is just a temporary array to make it easier to reference different nodes PointNode[][] circleNodes = new PointNode[circles][]; yield break; } ` Editor ------ The graph does not yet show up in the Add New Graph list because that requires a graph editor which we will create now. Create a new script in either AstarPathfindingProject/Editor/GraphEditors/ (or if you have enabled Js support AstarPathfindingEditor/Editor/GraphEditors/) or in any other Editor folder. Name the script PolarGeneratorEditor.cs Below is a very simple editor for the polar graph. Copy this code into the file you just created. After you have done this, you should be able to create the graph. `using UnityEditor; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) ; [CustomGraphEditor(typeof(PolarGraph), "Polar Graph")] public class PolarGeneratorEditor : GraphEditor { // Here goes the GUI public override void OnInspectorGUI (NavGraph target) { var graph = target as PolarGraph; graph.circles = EditorGUILayout.IntField("Circles", graph.circles); graph.steps = EditorGUILayout.IntField("Steps", graph.steps); graph.scale = EditorGUILayout.FloatField("Scale", graph.scale); graph.center = EditorGUILayout.Vector3Field("Center", graph.center); } } ` The CustomGraphInspector attribute tells the system that this class is a custom editor for the graph of type PolarGraph, the display-name in the graphs list will be "Polar Graph". Try it out! Open the Graphs tab in the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) inspector, click Add Graph, and add the Polar Graph which should be in the list now. Adding nodes ------------ Now we need to get to work with actually creating a graph. Every code fragment below this point should go into the Scan function. We will use a matrix for placement to enable rotation, positioning and so on of the nodes. The first node in the array should be the center node which we will place at Vector3.zero. Node positions are stored as Int3s. They are like Vector3s but use integer coordinates instead of floating point coordinates. There is an explicit cast available between Vector3 and Int3. `// Destroy previous nodes (if any) graph.DestroyAllNodes(); var circles = graph.circles; var steps = graph.steps; // Create a 2D array which will contain all nodes // This is just a tempoary array to make it easier to reference different nodes PointNode[][] circleNodes = new PointNode[circles][]; // Create a matrix which just moves the nodes to #center // and scales their positions by #scale // The GraphTransform class has various utility methods for working with it graph.transform = new GraphTransform(Matrix4x4.TRS(graph.center, Quaternion.identity, Vector3.one*graph.scale)); // Place the center node in the center circleNodes[0] = new PointNode[] { graph.CreateNode(CalculateNodePosition(0, 0, graph.transform)) }; `Next. Assume we have a node at a given angle and in a given circle. We need to calculate the position for that node. `static Vector3 CalculateNodePosition (int circle, float angle, GraphTransform transform) { // Get the direction towards the node from the center var pos = new Vector3(Mathf.Sin(angle), 0, Mathf.Cos(angle)); // Multiply it with the circle number to get the node position in graph space pos *= circle; // Multiply it with the matrix to get the node position in world space pos = transform.Transform(pos); return pos; } `Now we will set up the rest of the graph, circle for circle, node for node `// The size of the angle (in radians) each step will use float anglesPerStep = (2*Mathf.PI)/steps; for (int circle = 1; circle < circles; circle++) { circleNodes[circle] = new PointNode[steps]; for (int step = 0; step < steps; step++) { // Get the angle to the node relative to the center float angle = step * anglesPerStep; Vector3 pos = CalculateNodePosition(circle, angle, graph.transform); circleNodes[circle][step] = graph.CreateNode(pos); } } `Now we have set up all the nodes to their correct positions, but they have no connections to other nodes, so let's add that: `// Iterate through all circles // circle 0 is just the center node so we skip that for now for (int circle = 1; circle < circles; circle++) { for (int step = 0; step < steps; step++) { // Get the current node PointNode node = circleNodes[circle][step]; // The nodes here will always have exactly four connections, like a grid, but polar. // Except for those in the last circle which will only have three connections int numConnections = circle < circles-1 ? 4 : 3; var connections = new Connection[numConnections]; // Get the next clockwise node in the current circle. // The last node in each circle should be linked to the first node // in the circle which is why we use the modulo operator. connections[0] = new Connection(circleNodes[circle][(step+1) % steps], 0, isOutgoing: true, isIncoming: true); // Counter clockwise node. Here we check for underflow instead connections[1] = new Connection(circleNodes[circle][(step-1+steps) % steps], 0, isOutgoing: true, isIncoming: true); // The node in the previous circle (in towards the center) if (circle > 1) { connections[2] = new Connection(circleNodes[circle-1][step], 0, isOutgoing: true, isIncoming: true); } else { // Create a connection to the middle node, special case connections[2] = new Connection(circleNodes[circle-1][0], 0, isOutgoing: true, isIncoming: true); } // Are there any more circles outside this one? if (numConnections == 4) { // The node in the next circle (out from the center) connections[3] = new Connection(circleNodes[circle+1][step], 0, isOutgoing: true, isIncoming: true); } // Set all connection costs based on the distance between the nodes for (int q = 0; q < connections.Length; q++) { // Node.position is an Int3, here we get the cost of moving between the two positions connections[q].cost = (uint)(node.position-connections[q].node.position).costMagnitude; } node.connections = connections; } } `The first node (the center) is a special case, it will have connections to all nodes in the first circle (or second depending on how you look at it). This means that it will have **steps** connections, because **steps** is the number of nodes in each circle. `// The center node is a special case, so we have to deal with it separately PointNode centerNode = circleNodes[0][0]; centerNode.connections = new Connection[steps]; // Assign all nodes in the first circle as connections to the center node for (int step = 0; step < steps; step++) { centerNode.connections[step] = new Connection( circleNodes[1][step], // centerNode.position is an Int3, here we get the cost of moving between the two positions (uint)(centerNode.position-circleNodes[1][step].position).costMagnitude, isOutgoing: true, isIncoming: true ); } `Now the only thing left to do is to make the nodes walkable; the default value is unwalkable. This tutorial will not cover checking for obstacles or similar, but if you read up on Unity's Physics class, you should be able to get that working. `// Store all nodes in the nodes array List allNodes = new List(); for (int i = 0; i < circleNodes.Length; i++) { allNodes.AddRange(circleNodes[i]); } graph.nodes = allNodes.ToArray(); // Set all the nodes to be walkable for (int i = 0; i < graph.nodes.Length; i++) { graph.nodes[i].Walkable = true; } `If you have placed all the previous snippets after each other in the Scan function as I wrote before, you will have a working scan function. Finally, to be able to scan the graph, the GetNodes method needs to be implemented. Since all our nodes are just stored in an array, it is very simple. `public override void GetNodes(GraphNode.NodeActionWithData action, ref T data) { if (nodes == null) return; for (int i = 0; i < nodes.Length; i++) { // Call the delegate action(nodes[i], ref data); } } `You should be able to create the graph, edit the parameters and if you click Scan, the graph will appear in the Scene View. Cool, huh? However, you might notice that if you deselect the inspector and then select it again, your settings have not been saved. This is because we need to add one last thing, serialization. All graph settings are serialized to JSON (see [http://www.json.org/](http://www.json.org/) ). For the fields to get serialized, we must add an attribute to each field. The JsonMember attribute will tell the serializer that we want to serialize that field. The complete script can be found here [PolarGraphGenerator.cs](https://arongranberg.com/astar/docs/polargraphgeneratorcs.html) More Stuff ---------- More methods can be overridden to customize other functionality. Especially the GetNearest and GetNearestForce methods, which control how the nearest node to a point is found. There is a default implementation, but it will search through all nodes in the graph every time, which can be a bit slow if your graph contains a lot of nodes. You can also override the OnDrawGizmos method if you want to draw the graph differently than the default implementation. If you need to serialize more information, you can override the SerializeExtraInfo, DeserializeExtraInfo and if you need to set up nodes after they have been loaded, you can override the PostDeserialization function. Explaining all functions is beyond the scope of this tutorial; you can have a look at how other graph types have implemented them. The End ------- You should now be able to use this graph like any other graph! I hope this tutorial has helped you get started writing graph generators. --- # BatchedEvents - A* Pathfinding Project Class BatchedEvents Extends [VersionedMonoBehaviour](https://arongranberg.com/astar/docs/versionedmonobehaviour.html) ====================================================================================================================== Public Helper for batching updates to many objects efficiently. ![](https://arongranberg.com/astar/docs/images/generated/inspectors/BatchedEvents@2x.png) Inner Types ----------- [Archetype](https://arongranberg.com/astar/docs/archetype.html) Public Static Methods --------------------- [Add](https://arongranberg.com/astar/docs/batchedevents/add.html) (obj, eventTypes, ..., \[archetypeVariant\]) [Find](https://arongranberg.com/astar/docs/batchedevents/find.html#Find) (key, predicate) [GetComponents](https://arongranberg.com/astar/docs/batchedevents/getcomponents.html#GetComponents) (eventTypes, transforms, components) [Has](https://arongranberg.com/astar/docs/batchedevents/has.html#Has) (obj) [ProcessEvent](https://arongranberg.com/astar/docs/batchedevents/processevent.html#ProcessEvent) (eventType) [Remove](https://arongranberg.com/astar/docs/batchedevents/remove.html#Remove) (obj) Public Enums ------------ Event Public ##### Event | | | | --- | --- | | Update= 1 << 0 | | | LateUpdate= 1 << 1 | | | FixedUpdate= 1 << 2 | | | Custom= 1 << 3 | | | None= 0 | | Private/Protected Members ------------------------- ArchetypeMask Private Static ##### const int ArchetypeMask = 0xFF << [ArchetypeOffset](https://arongranberg.com/astar/docs/batchedevents.html#ArchetypeOffset) ArchetypeOffset Private Static ##### const int ArchetypeOffset = 22 [Awake](https://arongranberg.com/astar/docs/versionedmonobehaviour/awake.html#Awake) () [CreateInstance](https://arongranberg.com/astar/docs/batchedevents/createinstance.html#CreateInstance) () [DelayedDestroy](https://arongranberg.com/astar/docs/batchedevents/delayeddestroy.html#DelayedDestroy) () [FixedUpdate](https://arongranberg.com/astar/docs/batchedevents/fixedupdate.html#FixedUpdate) () [LateUpdate](https://arongranberg.com/astar/docs/batchedevents/lateupdate.html#LateUpdate) () [OnDisable](https://arongranberg.com/astar/docs/batchedevents/ondisable.html#OnDisable) () [OnEnable](https://arongranberg.com/astar/docs/batchedevents/onenable.html#OnEnable) () [OnUpgradeSerializedData](https://arongranberg.com/astar/docs/versionedmonobehaviour/onupgradeserialize.html#OnUpgradeSerializedData) (migrations, unityThread) Handle serialization backwards compatibility. [Process](https://arongranberg.com/astar/docs/batchedevents/process.html#Process) (eventType, typeFilter) [Reset](https://arongranberg.com/astar/docs/versionedmonobehaviour/reset.html#Reset) () Handle serialization backwards compatibility. [Update](https://arongranberg.com/astar/docs/batchedevents/update.html#Update) () [UpgradeSerializedData](https://arongranberg.com/astar/docs/versionedmonobehaviour/upgradeserializedd.html#UpgradeSerializedData) (isUnityThread) data Private Static ##### [Archetype](https://arongranberg.com/astar/docs/archetype.html) \[\] data = new [Archetype](https://arongranberg.com/astar/docs/archetype.html) \[0\] instance Private Static ##### [BatchedEvents](https://arongranberg.com/astar/docs/batchedevents.html) instance isIterating Private Static ##### bool isIterating = false isIteratingOverTypeIndex Private Static ##### int isIteratingOverTypeIndex = -1 --- # NativeCircularBuffer - A* Pathfinding Project Struct NativeCircularBuffer Extends IReadOnlyList, IReadOnlyCollection ============================================================================ Public Implements an efficient circular buffer that can be appended to in both directions. See [CircularBuffer](https://arongranberg.com/astar/docs/circularbuffer.html) Public Methods -------------- [AddRange](https://arongranberg.com/astar/docs/nativecircularbuffer/addrange.html#AddRange) (items) Appends a list of items to the end of the buffer. [Clear](https://arongranberg.com/astar/docs/nativecircularbuffer/clear.html#Clear) () Resets the buffer's length to zero. [Clone](https://arongranberg.com/astar/docs/nativecircularbuffer/clone.html#Clone) () [Dispose](https://arongranberg.com/astar/docs/nativecircularbuffer/dispose.html#Dispose) () Releases the unmanaged memory held by this container. [GetAbsolute](https://arongranberg.com/astar/docs/nativecircularbuffer/getabsolute.html#GetAbsolute) (index) Indexes the buffer using absolute indices. [GetBoundaryValue](https://arongranberg.com/astar/docs/nativecircularbuffer/getboundaryvalue.html#GetBoundaryValue) (start) Return either the first element or the last element. [GetEnumerator](https://arongranberg.com/astar/docs/nativecircularbuffer/getenumerator.html) () [Grow](https://arongranberg.com/astar/docs/nativecircularbuffer/grow.html#Grow) () [MoveAbsolute](https://arongranberg.com/astar/docs/nativecircularbuffer/moveabsolute.html#MoveAbsolute) (startIndex, endIndex, deltaIndex) [NativeCircularBuffer](https://arongranberg.com/astar/docs/nativecircularbuffer/nativecircularbuffer.html) (...) ... [Pop](https://arongranberg.com/astar/docs/nativecircularbuffer/pop.html#Pop) (fromStart) Pops either from the start or from the end of the buffer. [PopEnd](https://arongranberg.com/astar/docs/nativecircularbuffer/popend.html#PopEnd) () Removes and returns the last element. [PopStart](https://arongranberg.com/astar/docs/nativecircularbuffer/popstart.html#PopStart) () Removes and returns the first element. [Push](https://arongranberg.com/astar/docs/nativecircularbuffer/push.html#Push) (toStart, item) Pushes a new item to the start or the end of the buffer. [PushEnd](https://arongranberg.com/astar/docs/nativecircularbuffer/pushend.html#PushEnd) (item) Pushes a new item to the end of the buffer. [PushStart](https://arongranberg.com/astar/docs/nativecircularbuffer/pushstart.html#PushStart) (item) Pushes a new item to the start of the buffer. [Splice](https://arongranberg.com/astar/docs/nativecircularbuffer/splice.html#Splice) (startIndex, toRemove, toInsert) Removes **toRemove** items from the buffer, starting at **startIndex**, and then inserts the **toInsert** items at **startIndex**. [SpliceAbsolute](https://arongranberg.com/astar/docs/nativecircularbuffer/spliceabsolute.html#SpliceAbsolute) (startIndex, toRemove, toInsert) Like [Splice](https://arongranberg.com/astar/docs/nativecircularbuffer/splice.html#Splice) , but **startIndex** is an absolute index. [SpliceUninitialized](https://arongranberg.com/astar/docs/nativecircularbuffer/spliceuninitialized.html#SpliceUninitialized) (startIndex, toRemove, toInsert) Like [Splice](https://arongranberg.com/astar/docs/nativecircularbuffer/splice.html#Splice) , but the newly inserted items are left in an uninitialized state. [SpliceUninitializedAbsolute](https://arongranberg.com/astar/docs/nativecircularbuffer/spliceuninitializeda.html#SpliceUninitializedAbsolute) (startIndex, toRemove, toInsert) Like [SpliceUninitialized](https://arongranberg.com/astar/docs/nativecircularbuffer/spliceuninitialized.html#SpliceUninitialized) , but **startIndex** is an absolute index. [TrimTo](https://arongranberg.com/astar/docs/nativecircularbuffer/trimto.html#TrimTo) (length) Lowers the length of the buffer to the given value, and does nothing if the given value is greater or equal to the current length. Public Variables ---------------- AbsoluteEndIndex Absolute index of the last item in the buffer, may be negative or greater than [Length](https://arongranberg.com/astar/docs/nativecircularbuffer.html#Length) . Public Readonly ##### int AbsoluteEndIndex Absolute index of the last item in the buffer, may be negative or greater than [Length](https://arongranberg.com/astar/docs/nativecircularbuffer.html#Length) . AbsoluteStartIndex Absolute index of the first item in the buffer, may be negative or greater than [Length](https://arongranberg.com/astar/docs/nativecircularbuffer.html#Length) . Public Readonly ##### int AbsoluteStartIndex Absolute index of the first item in the buffer, may be negative or greater than [Length](https://arongranberg.com/astar/docs/nativecircularbuffer.html#Length) . Allocator The allocator used to create the internal buffer. Public ##### AllocatorManager.AllocatorHandle Allocator The allocator used to create the internal buffer. Count Public Readonly ##### int IReadOnlyCollection { // Safe to update graphs here var node = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (transform.position).node; node.Walkable = false; })); ``[AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) (() => { // Safe to update graphs here var node = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (transform.position).node; node.position = (Int3)transform.position; }); `You can run work items over multiple frames: `[AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) (new AstarWorkItem(() => { // Called once, right before the // first call to the method below }, force => { // Called every frame until complete. // Signal that the work item is // complete by returning true. // The "force" parameter will // be true if the work item is // required to complete immediately. // In that case this method should // block and return true when done. return true; })); ` See [FlushWorkItems](https://arongranberg.com/astar/docs/astarpath/flushworkitems.html#FlushWorkItems) AddWorkItem (System.Action callback) Add a work item to be processed when pathfinding is paused. Public ##### void AddWorkItem ( | | | | | --- | --- | --- | | System.Action | callback | | ) Add a work item to be processed when pathfinding is paused. The callback will be called once when it is safe to update graphs. This is a convenience method that is equivalent to `AddWorkItem(new AstarWorkItem(callback)); ` See [AddWorkItem(AstarWorkItem)](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem3) AddWorkItem (System.Action<[IWorkItemContext](https://arongranberg.com/astar/docs/iworkitemcontext.html) \> callback) Add a work item to be processed when pathfinding is paused. Public ##### void AddWorkItem ( | | | | | --- | --- | --- | | System.Action<[IWorkItemContext](https://arongranberg.com/astar/docs/iworkitemcontext.html)
\> | callback | | ) Add a work item to be processed when pathfinding is paused. THe callback will be called once when it is safe to update graphs. This is a convenience method that is equivalent to `AddWorkItem(new AstarWorkItem(callback)); ` See [AddWorkItem(AstarWorkItem)](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem3) --- # Using high performance ECS - A* Pathfinding Project Using high performance ECS ========================== How to use Unity's Entity Component System together with this package. Your browser does not support the video tag. [Unity's ECS (Entity Component System)](https://unity.com/ecs) is a different way of building game code that, in many cases, allows much higher performance, compared to the classical approach of using MonoBehaviours. ECS has downsides, however, such as higher code complexity and more boilerplate in many cases, and it is seldom useful for a very small number of items (whether that is NPCs, buttons or bullets). ECS really shines when it can operate on a large number of items (in our case, agents), as it can parallelize calculations, and make use of unity's Burst compiler for batch-processing. Contents -------- * [Using ECS for movement scripts](https://arongranberg.com/astar/docs/ecs.html#ecs-using) * [When to use ECS, and when not to](https://arongranberg.com/astar/docs/ecs.html#ecs-when) * [Interacting with a baked FollowerEntity](https://arongranberg.com/astar/docs/ecs.html#ecs-pure-script) * [Using the FollowerEntityProxy](https://arongranberg.com/astar/docs/ecs.html#ecs-proxy) * [Accessing ECS components directly](https://arongranberg.com/astar/docs/ecs.html#ecs-direct) * [Other baked components](https://arongranberg.com/astar/docs/ecs.html#ecs-other-components) * [ECS physics](https://arongranberg.com/astar/docs/ecs.html#ecs-physics) * [Performance](https://arongranberg.com/astar/docs/ecs.html#ecs-performance) Using ECS for movement scripts ------------------------------ The A\* Pathfinding Project supports using ECS when using the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) movement script. With it, you can achieve good performance even with thousands of agents. There are two ways of using it: 1. Use the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) as a normal MonoBehaviour. Behind the scenes, it will always use ECS anyway, and you'll get most of the performance benefit out-of-the-box. This makes it easy to integrate with a classical MonoBehaviour workflow. 2. For even higher performance, place the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) in a [subscene](https://docs.unity3d.com/Packages/com.unity.entities@1.4/manual/conversion-subscenes.html) . Then it will be automatically baked into a pure entity, without any overhead from gameObjects and MonoBehaviours. However, then you'll have to write ECS-code to interact with it. Note Other built-in movement scripts have no support for ECS. See For an example of subscenes, check out the included example scene [High performance ECS](https://arongranberg.com/astar/docs/example_ecs.html) When to use ECS, and when not to -------------------------------- I recommend using ECS when you have a large number of agents (at least 100, likely more), so that the reduced overhead is actually noticable. Before that, you'll just be adding extra complexity to your game for pretty small wins. Keep in mind that the FollowerEntity always uses ECS behind the scenes, so you get most of the performance benefit out-of-the-box. If you are already using ECS for the rest of the game, then of course using ECS for the movement scripts is also reasonable. When in doubt, test both approaches and profile your game, and weigh that against the additional code complexity. In any case, I strongly recommend starting out with MonoBehaviours to prototype things. Interacting with a baked FollowerEntity --------------------------------------- When used in a subscene, you cannot use any properties, fields, or methods on the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) in play mode, since the component is baked away and won't even exist at runtime. Instead, you can either use ECS components directly, or you can use the wrapper [FollowerEntityProxy](https://arongranberg.com/astar/docs/followerentityproxy.html) which acts almost identically to the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component, but uses an entity as the source instead. ### Using the FollowerEntityProxy When you have a baked entity in a given world (how to get a reference to one is out of scope for this tutorial, check out Unity's ECS documentation), you can create a proxy wrapper to easily access most data: `var follower = new FollowerEntityProxy(world, entity); follower.maxSpeed = 5; follower.destination = new Vector3(1, 2, 3); if (follower.currentNode.Tag == 1) { Debug.Log("The agent is right now traversing a node with tag 1"); } `The interface is almost identical to the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) MonoBehaviour component. Note This proxy can only be used on the main thread, and not in jobs. In those cases, you'll need to use ECS components directly. See [FollowerEntityProxy](https://arongranberg.com/astar/docs/followerentityproxy.html) ### Accessing ECS components directly The [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) is baked into many components. You can find a list of them at [FollowerEntity Component List](https://arongranberg.com/astar/docs/followerentity.html#followerentity-ecs) . All settings of the movement script are reflected in one of those components. For example, to change the agent's speed, destination and read the current node, like above, we can do: `// Read and then write back var data = world.EntityManager.GetComponentData(entity); data.follower.speed = 5; world.EntityManager.SetComponentData(entity, data); world.EntityManager.SetComponentData(entity, new DestinationPoint { destination = new Vector3(1, 2, 3), facingDirection = Vector3.zero, }); var currentNode = world.EntityManager.GetComponentData(entity).pathTracer.startNode; if (currentNode.Tag == 1) { Debug.Log("The agent is right now traversing a node with tag 1"); } `In addition to being a bit more clunky, this has one important difference compared to using the proxy or MonoBehaviour: When using the proxy or MonoBehaviour to change properties, the code will try VERY hard to ensure that all other related properties are as up-to-date as possible. For example, when changing the destination of the agent, the [reachedDestination](https://arongranberg.com/astar/docs/followerentity.html#reachedDestination) property will immediately update to reflect this. When directly accessing ECS components, no such update is done. Therefore, related properties may be out of date until the next simulation loop for the agent runs (typically the next frame). This means it's also faster, of course. You'll just have to be aware of it. Note Unsure about in which component to find a given setting? Check the source code for the property on the [FollowerEntityProxy](https://arongranberg.com/astar/docs/followerentityproxy.html) that you are interested in. Most implementations are only a few lines, and you'll be able to see exactly how to access it. Other baked components ---------------------- There are a few other commonly used components which can be baked, among those are: * [AIDestinationSetter](https://arongranberg.com/astar/docs/aidestinationsetter.html) (bakes into a [DestinationEntity](https://arongranberg.com/astar/docs/destinationentity.html) ECS component) * [MoveInCircle](https://arongranberg.com/astar/docs/moveincircle.html) (bakes into a [DestinationMoveInCircle](https://arongranberg.com/astar/docs/destinationmoveincircle.html) ECS component) They work essentially the same when baked as when they are used as MonoBehaviours. ECS physics ----------- This package does not currently have any support for the [com.unity.physics package](https://docs.unity3d.com/Manual/com.unity.physics.html) . All physics is done using Unity's built-in PhysX engine. If you are simulating multiple worlds simultaneously (e.g. on a server) and have multiple physics scenes, you can use the [PhysicsSceneRef](https://arongranberg.com/astar/docs/physicssceneref.html) component to specify which physics scene to use for ground collision and such. Performance ----------- ![](https://arongranberg.com/astar/docs/images/scenes/ECS/ecs_profiler_annotated.png) When the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component is used in a subscene, performance is very good in most cases. Almost everything is done in separate worker threads, and the main thread is freed up to handle all your other game logic. It also parallelizes most computations, to make use of multiple CPU cores. In the above screenshot, you can see an annotated profiler capture from a standalone build of the [example scene](https://arongranberg.com/astar/docs/example_ecs.html) running with 5000 agents at around 120-200 fps. Your mileage may vary depending on your hardware. This particular test was done on a pretty high-end computer. Rendering in this test is also extremely simple, and in a real game you will likely have a lot more overhead from rendering and all kinds of other things. See [Best practices for good performance](https://arongranberg.com/astar/docs/followerentity.html#followerentity-bestpractices) , for more tips on performance when using the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component. --- # Adding custom nodes to point graphs - A* Pathfinding Project Adding custom nodes to point graphs =================================== Introduction ------------ The [Point graph](https://arongranberg.com/astar/docs/pointgraph.html) is a type of graph that is created from a set of points in space. Each node is a single point, and the nodes can have connections between each other. In some cases you may want to create a point graph completely using code, by adding all nodes and connections manually. See If you want even more customization, you can write a custom graph type: [Writing Graph Generators](https://arongranberg.com/astar/docs/writinggraphgenerators.html) . Adding nodes to a point graph ----------------------------- To add nodes to a point graph, you can use the [PointGraph.AddNode](https://arongranberg.com/astar/docs/pointgraph/addnode.html) method. This must be done during a graph update, for safety. `// This holds all graph data AstarData data = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) ; // Create a Point Graph. Identical to adding it via the AstarPath inspector PointGraph graph = data.AddGraph(); // Scan the graph to initialize it. It will just be empty afterwards, though. graph.Scan(); // Make sure we only modify the graph when all pathfinding threads are paused [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) (() => { // Add 2 nodes and connect them var node1 = graph.AddNode((Int3) new Vector3(1, 2, 3)); var node2 = graph.AddNode((Int3) new Vector3(4, 5, 6)); var cost = (uint)(node2.position - node1.position).costMagnitude; GraphNode.Connect(node1, node2, cost); }); // Run the above work item immediately [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[FlushWorkItems](https://arongranberg.com/astar/docs/astarpath/flushworkitems.html#FlushWorkItems) (); ` Note Scanning a point graph will recalculate it from scratch, and discard any custom nodes you may have added. If you don't want to calculate the node connections yourself, you can use a graph update object to do it for you. This code will recalculate all connections around the node, and connect it to other nodes using the graph's settings. `[AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) (() => { var node = graph.AddNode((Int3) new Vector3(1, 2, 3)); // Recalculate all connections around the node [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[UpdateGraphs](https://arongranberg.com/astar/docs/astarpath/updategraphs.html#UpdateGraphs3) (new Bounds((Vector3)node.position, Vector3.one*0.1f)); }); // Run the above updates immediately [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[FlushWorkItems](https://arongranberg.com/astar/docs/astarpath/flushworkitems.html#FlushWorkItems) (); [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[FlushGraphUpdates](https://arongranberg.com/astar/docs/astarpath/flushgraphupdates.html#FlushGraphUpdates) (); ` Removing nodes from a point graph --------------------------------- You can also remove nodes using the [PointGraph.RemoveNode](https://arongranberg.com/astar/docs/pointgraph/removenode.html#RemoveNode) method. `// Make sure we only modify the graph when all pathfinding threads are paused [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) (() => { // Find the node closest to some point var nearest = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (new Vector3(1, 2, 3)); // Check if it is a PointNode if (nearest.node is PointNode pnode) { // Remove the node. Assuming it belongs to the first point graph in the scene AstarPath.active.data.pointGraph.RemoveNode(pnode); } }); ` Associating nodes with GameObjects ---------------------------------- If you want to associate your custom nodes with GameObjects, you can use the [PointNode.gameObject](https://arongranberg.com/astar/docs/pointnode.html#gameObject) field: `// Associate a GameObject with a node var node = graph.AddNode((Int3) new Vector3(1, 2, 3)); node.gameObject = gameObject; `Later you can retrieve the GameObject from the node like this: `var node = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (transform.position).node; var pointNode = node as PointNode; if (pointNode != null) { Debug.Log("That node was created from the GameObject named " + pointNode.gameObject.name); } else { Debug.Log("That node is not a PointNode"); } ` Associating nodes with custom data ---------------------------------- If you want to add more custom data to your point nodes, you can create a subclass of the [PointNode](https://arongranberg.com/astar/docs/pointnode.html) class. `class CustomPointNode : PointNode { // Some custom data to store on the node public int importantAnswer; public CustomPointNode([AstarPath](https://arongranberg.com/astar/docs/astarpath.html) active) : base(active) {} } void AddCustomPointNode () { [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[AddWorkItem](https://arongranberg.com/astar/docs/astarpath/addworkitem.html#AddWorkItem2) (() => { var graph = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .pointGraph; graph.AddNode(new CustomPointNode([AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) ) { importantAnswer = 42 }, (Int3) new Vector3(1, 2, 3)); }); } ` Warning Nodes created in this way cannot be serialized (see [Saving and Loading Graphs](https://arongranberg.com/astar/docs/saveloadgraphs.html) ). --- # Header - A* Pathfinding Project Struct Header ============= Public Public Variables ---------------- length Public ##### uint length --- # SlabAllocator - A* Pathfinding Project Struct SlabAllocator ==================== Public A tiny slab allocator. Allocates spans of type T in power-of-two sized blocks. Note This allocator has no support for merging adjacent freed blocks. Therefore it is best suited for similarly sized allocations which are relatively small. Can be used in burst jobs. This is faster than allocating NativeArrays using the Temp allocator, and significantly faster than allocating them using the Persistent allocator. Inner Types ----------- [AllocatorData](https://arongranberg.com/astar/docs/allocatordata.html) [Header](https://arongranberg.com/astar/docs/header.html) [List](https://arongranberg.com/astar/docs/list.html) [NextBlock](https://arongranberg.com/astar/docs/nextblock.html) Public Methods -------------- [Allocate](https://arongranberg.com/astar/docs/slaballocator/allocate.html) (...) Allocates an array... [CheckDisposed](https://arongranberg.com/astar/docs/slaballocator/checkdisposed.html#CheckDisposed) () [Clear](https://arongranberg.com/astar/docs/slaballocator/clear.html#Clear) () Frees all existing allocations. [CopyTo](https://arongranberg.com/astar/docs/slaballocator/copyto.html#CopyTo) (other) [Dispose](https://arongranberg.com/astar/docs/slaballocator/dispose.html#Dispose) () Frees all unmanaged memory associated with this container. [Free](https://arongranberg.com/astar/docs/slaballocator/free.html#Free) (allocatedIndex) Frees a single allocation. [GetList](https://arongranberg.com/astar/docs/slaballocator/getlist.html#GetList) (allocatedIndex) [GetSpan](https://arongranberg.com/astar/docs/slaballocator/getspan.html#GetSpan) (allocatedIndex) Get the span representing the given allocation. [Realloc](https://arongranberg.com/astar/docs/slaballocator/realloc.html#Realloc) (allocatedIndex, nElements) [SlabAllocator](https://arongranberg.com/astar/docs/slaballocator/slaballocator.html#SlabAllocator) (initialCapacityBytes, allocator) Public Variables ---------------- ByteSize Public ##### int ByteSize IsCreated Public ##### bool IsCreated IsDebugAllocator Public ##### bool IsDebugAllocator data Public ##### unsafe[AllocatorData](https://arongranberg.com/astar/docs/allocatordata.html) \* data Public Static Variables ----------------------- AllocatedBit Public Static ##### const uint AllocatedBit = 1u << 30 InvalidAllocation Allocation which is always invalid. Public Static ##### const int InvalidAllocation = -2 Allocation which is always invalid. LengthMask Public Static ##### const uint LengthMask = [AllocatedBit](https://arongranberg.com/astar/docs/slaballocator.html#AllocatedBit) - 1 MaxAllocationSize Public Static ##### const int MaxAllocationSize = 1 << [MaxAllocationSizeIndex](https://arongranberg.com/astar/docs/slaballocator.html#MaxAllocationSizeIndex) MaxAllocationSizeIndex Public Static ##### const int MaxAllocationSizeIndex = 12 UsedBit Public Static ##### const uint UsedBit = 1u << 31 ZeroLengthArray Allocation representing a zero-length array. Public Static ##### const int ZeroLengthArray = -1 Allocation representing a zero-length array. Private/Protected Members ------------------------- [ElementsToSizeIndex](https://arongranberg.com/astar/docs/slaballocator/elementstosizeindex.html#ElementsToSizeIndex) (nElements) [SizeIndexToElements](https://arongranberg.com/astar/docs/slaballocator/sizeindextoelements.html#SizeIndexToElements) (sizeIndex) --- # Grid - A* Pathfinding Project Namespace Grid ============== Namespaces ---------- [Jobs](https://arongranberg.com/astar/docs/jobs.html) [Rules](https://arongranberg.com/astar/docs/rules.html) Classes ------- [FlatGridAdjacencyMapper](https://arongranberg.com/astar/docs/flatgridadjacencymapper.html) [GraphCollision](https://arongranberg.com/astar/docs/graphcollision.html) Handles collision checking for graphs. [GridAdjacencyMapper](https://arongranberg.com/astar/docs/gridadjacencymapper.html) [GridGraphNodeData](https://arongranberg.com/astar/docs/gridgraphnodedata.html) [GridGraphScanData](https://arongranberg.com/astar/docs/gridgraphscandata.html) [GridIterationUtilities](https://arongranberg.com/astar/docs/griditerationutilities.html) Helpers for iterating over grid graph data. [LayeredGridAdjacencyMapper](https://arongranberg.com/astar/docs/layeredgridadjacencymapper.html) Public Enums ------------ ColliderType Determines collision check shape. ##### ColliderType | | | | --- | --- | | Sphere | Uses a Sphere, Physics.CheckSphere.

In 2D this is a circle instead. | | Capsule | Uses a Capsule, Physics.CheckCapsule.

This will behave identically to the Sphere mode in 2D. | | Ray | Uses a Ray, Physics.Linecast.

In 2D this is a single point instead. | Determines collision check shape. See [GraphCollision](https://arongranberg.com/astar/docs/graphcollision.html) RayDirection Determines collision check ray direction. ##### RayDirection | | | | --- | --- | | Up | Casts the ray from the bottom upwards. | | Down | Casts the ray from the top downwards. | | Both | Casts two rays in both directions. | Determines collision check ray direction. --- # Spherical Worlds - A* Pathfinding Project Spherical Worlds ================ Tutorial on how to use pathfinding on non-planar surfaces. ![](https://arongranberg.com/astar/docs/images/spherical/shape_examples@2x.png) Contents -------- * [Introduction](https://arongranberg.com/astar/docs/spherical.html#spherical_intro) * [Configuring a graph](https://arongranberg.com/astar/docs/spherical.html#config-spherical-graphs) * [Movement scripts](https://arongranberg.com/astar/docs/spherical.html#spherical-movement) * [FollowerEntity](https://arongranberg.com/astar/docs/spherical.html#spherical-follower) * [AIPathAlignedToSurface](https://arongranberg.com/astar/docs/spherical.html#spherical-aipath) * [Local avoidance](https://arongranberg.com/astar/docs/spherical.html#spherical-local-avoidance) * [Tips for good non-planar navmeshes](https://arongranberg.com/astar/docs/spherical.html#spherical-tips) * [Graph updates](https://arongranberg.com/astar/docs/spherical.html#spherical-updates) Introduction ------------ In some games, you may need to use pathfinding and local avoidance on surfaces like planets or rings that do not always have the same direction as 'up'. In the image above, you can see a few example shapes of worlds. However, you can make them as complex as you'd like (almost, see below for some tips). Note In the package, you can find an example scene called [Spherical world](https://arongranberg.com/astar/docs/example_spherical.html) which shows how one can configure pathfinding and local avoidance for a spherical world. Your browser does not support the video tag. Configuring a graph ------------------- It is not possible to automatically generate a navmesh on a spherical world (or any other shape that is not at least somewhat planar) using either grid graphs or recast graphs. So you will have to model the navmesh by hand in a 3D modeling application and then import it into Unity. Both navmesh graphs and point graphs can be used. However, for most purposes, navmesh graphs are recommended. The way you set them up is pretty much identical to how it's done in the navmesh tutorial (see [Creating a navmesh manually](https://arongranberg.com/astar/docs/createnavmesh.html) ) with the difference that instead of a planar surface, you create, for example, a sphere. You should make sure that 'Recalculate Normals' is **disabled** in the navmesh graph settings. If that is left enabled, then normals will be recalculated assuming that the Y+ axis is up, which in this case it will not be everywhere. ![](https://arongranberg.com/astar/docs/images/spherical/navmesh_inspector@2x.png) Movement scripts ---------------- For moving characters across a curved surface, you can either use the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component, the [AIPathAlignedToSurface](https://arongranberg.com/astar/docs/aipathalignedtosurface.html) component, or write your own movement script. ### FollowerEntity The [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component supports spherical worlds out-of-the-box. The only thing you need to do is to change the [FollowerEntity.movementPlaneSource](https://arongranberg.com/astar/docs/followerentity.html#movementPlaneSource) field to **NavmeshNormal**. This will make the FollowerEntity use the normal of the navmesh below it to align itself to the surface. The FollowerEntity will also make sure that the gravity is relative to the character's up direction instead of the world's up direction. Movement Plane Source How to calculate which direction is "up" for the agent. In almost all cases, you should use the **Graph** option. This will make the agent use the graph's natural "up" direction. However, if you are using a spherical world, or a world with some other strange shape, then you may want to use the NavmeshNormal or Raycast options. See [Spherical Worlds](https://arongranberg.com/astar/docs/spherical.html) See This setting corresponds to the member [FollowerEntity.movementPlaneSource](https://arongranberg.com/astar/docs/followerentity.html#movementPlaneSource) The FollowerEntity is generally more robust compared to [AIPathAlignedToSurface](https://arongranberg.com/astar/docs/aipathalignedtosurface.html) . Your browser does not support the video tag. ### AIPathAlignedToSurface The [AIPathAlignedToSurface](https://arongranberg.com/astar/docs/aipathalignedtosurface.html) script inherits from AIPath and it changes a few things to make it more suitable for a curved surface. Firstly, it uses the normal of the ground below it to align itself to the surface. Secondly, it makes the gravity be relative to the character's up direction instead of the world's up direction. So if you, for example, set the gravity to (0, -10, 0) the character will be pulled downwards towards the surface it is standing on, even if it is on the bottom side of, say, a sphere. It is recommended to use the [funnel modifier](https://arongranberg.com/astar/docs/funnelmodifier.html) on navmesh graphs for a higher path quality; however, for that to work correctly on curved surfaces, you need to make sure [splitAtEveryPortal](https://arongranberg.com/astar/docs/funnelmodifier.html#splitAtEveryPortal) is enabled. If you use a mesh collider as ground, the [AIPathAlignedToSurface](https://arongranberg.com/astar/docs/aipathalignedtosurface.html) script will try to interpolate the surface normal to make movement across it much smoother. This will, however, only work if the mesh used for the collider is readable. So make sure you check the 'Read/Write Enabled' checkbox in the mesh asset importer. Local avoidance --------------- Local avoidance is supported on curved surfaces out of the box. The only thing you need to do is to, as usual, add an RVOSimulator to the scene and an RVOController to your agent (see [Local Avoidance](https://arongranberg.com/astar/docs/localavoidance.html) for more info about this), and then you have to set the [movement plane option](https://arongranberg.com/astar/docs/rvosimulator.html#movementPlane) on the RVOSimulator to 'Arbitrary'. The [AIPathAlignedToSurface](https://arongranberg.com/astar/docs/aipathalignedtosurface.html) script takes care of informing the RVOController about the orientation of the surface it is standing on. If you are writing your own movement script, you will have to set the [RVOController.movementPlane](https://arongranberg.com/astar/docs/rvocontroller.html#movementPlane) property to update the orientation. If you use the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component, you have to enable the local avoidance section on that component, instead of adding an RVOController to the agent. Tips for good non-planar navmeshes ---------------------------------- A good navmesh should have roughly equally sized triangles which are not too small (as that will cause pathfinding to be unnecessarily slow as it has to search more nodes) or too large (as that will reduce the precision too much). If you use the built-in movement scripts, you should try to avoid very drastic surface changes as then movement across the edge may look pretty bad. E.g., use a rounded cube instead of a normal cube. Below you can see some examples of good and bad navmeshes. These are, of course, very simple example navmeshes, but hopefully the general idea of what to avoid should come across. | | | | --- | --- | | ![](https://arongranberg.com/astar/docs/images/spherical/shape_cube@2x.png) | Not recommended.
This navmesh both has sharp corners (hard to move over them) and very large triangles (may be too large for good paths, note that paths are searched on a node by node basis). | | ![](https://arongranberg.com/astar/docs/images/spherical/shape_subcube@2x.png) | Not recommended.
This navmesh is subdivided so the size of the nodes is better, but it still has very sharp corners. | | ![](https://arongranberg.com/astar/docs/images/spherical/shape_roundcube_bad@2x.png) | Not recommended.
This navmesh has no sharp corners, but the triangles are of very different sizes, which is generally bad for the path quality. | | ![](https://arongranberg.com/astar/docs/images/spherical/shape_roundcube@2x.png) | Recommended.
This is a nice navmesh. | | ![](https://arongranberg.com/astar/docs/images/spherical/shape_twist@2x.png) | Recommended.
This is a nice navmesh. | | ![](https://arongranberg.com/astar/docs/images/spherical/shape_uvsphere@2x.png) | Not recommended.
This navmesh has triangles of very different sizes (especially near the poles), which is generally bad for the path quality. | | ![](https://arongranberg.com/astar/docs/images/spherical/shape_icosphere@2x.png) | Recommended.
This is a nice navmesh. | Graph updates ------------- Spherical graphs unfortunately do not support navmesh cutting at all. However, you can use regular graph updates to mark triangles as unwalkable or walkable as you see fit. See [Graph Updates during Runtime](https://arongranberg.com/astar/docs/graphupdates.html) --- # List - A* Pathfinding Project Struct List =========== Public Public Methods -------------- [Add](https://arongranberg.com/astar/docs/list/add.html#Add) (value) [Clear](https://arongranberg.com/astar/docs/list/clear.html#Clear) () [List](https://arongranberg.com/astar/docs/list/list.html#List) (allocator, allocationIndex) [RemoveAt](https://arongranberg.com/astar/docs/list/removeat.html#RemoveAt) (index) Public Variables ---------------- Length Public ##### int Length allocationIndex Public ##### int allocationIndex allocator Public ##### [SlabAllocator](https://arongranberg.com/astar/docs/slaballocator.html) allocator span Public ##### [UnsafeSpan](https://arongranberg.com/astar/docs/unsafespan.html) span this\[int index\] Public ##### ref T this\[int index\] --- # ConstantPath - A* Pathfinding Project Class ConstantPath Extends [Path](https://arongranberg.com/astar/docs/path.html) ================================================================================= Public Finds all nodes within a specified distance from the start. This class will search outwards from the start point and find all nodes which it costs less than [EndingConditionDistance.maxGScore](https://arongranberg.com/astar/docs/endingconditiondistance.html#maxGScore) to reach, this is usually the same as the distance to them multiplied with 1000. The path can be called like: `// Here you create a new path and set how far it should search. ConstantPath cpath = ConstantPath.Construct(transform.position, 20000, null); [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[StartPath](https://arongranberg.com/astar/docs/astarpath/startpath.html#StartPath) (cpath); // Block until the path has been calculated. You can also calculate it asynchronously // by providing a callback in the constructor above. cpath.BlockUntilCalculated(); // Draw a line upwards from all nodes within range for (int i = 0; i < cpath.allNodes.Count; i++) { Debug.DrawRay((Vector3)cpath.allNodes[i].position, Vector3.up, Color.red, 2f); } `When the path has been calculated, all nodes it searched will be stored in the variable [ConstantPath.allNodes](https://arongranberg.com/astar/docs/constantpath.html#allNodes) (remember that you need to cast it from [Path](https://arongranberg.com/astar/docs/path.html) to [ConstantPath](https://arongranberg.com/astar/docs/constantpath.html) first to get the variable). This list will be sorted by the cost to reach that node (more specifically the G score if you are familiar with the terminology for search algorithms). ![](https://arongranberg.com/astar/docs/images/constantPath.png) A\* Pro Feature This is an A\* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A\* Pathfinding Project or the functionality might be limited. The Pro version can be bought [here](http://www.arongranberg.com/astar/buy) Public Methods -------------- [OnVisitNode](https://arongranberg.com/astar/docs/constantpath/onvisitnode.html#OnVisitNode) (ctx, pathNode, hScore, gScore) Called for every node that the path visits. Public Static Methods --------------------- [Construct](https://arongranberg.com/astar/docs/constantpath/construct.html#Construct) (start, maxGScore, callback=null) Constructs a [ConstantPath](https://arongranberg.com/astar/docs/constantpath.html) starting from the specified point. Public Variables ---------------- allNodes Contains all nodes the path found. Public ##### List<[GraphNode](https://arongranberg.com/astar/docs/graphnode.html) \> allNodes Contains all nodes the path found. This list will be sorted by G score (cost/distance to reach the node). endingCondition Determines when the path calculation should stop. Public ##### [PathEndingCondition](https://arongranberg.com/astar/docs/pathendingcondition.html) endingCondition Determines when the path calculation should stop. This is set up automatically in the constructor to an instance of the [Pathfinding.EndingConditionDistance](https://arongranberg.com/astar/docs/endingconditiondistance.html) class with a **maxGScore** is specified in the constructor. See [Pathfinding.PathEndingCondition](https://arongranberg.com/astar/docs/pathendingcondition.html) for examples originalStartPoint Public ##### [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) originalStartPoint startNode Public ##### [GraphNode](https://arongranberg.com/astar/docs/graphnode.html) startNode startPoint Public ##### [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) startPoint Inherited Public Members ------------------------ [BlockUntilCalculated](https://arongranberg.com/astar/docs/path/blockuntilcalculated.html#BlockUntilCalculated) () Blocks until this path has been calculated and returned. [Claim](https://arongranberg.com/astar/docs/path/claim.html#Claim) (o) Increase the reference count on this path by 1 (for pooling). CompleteState Current state of the path. Public ##### [PathCompleteState](https://arongranberg.com/astar/docs/pathfinding.html#PathCompleteState) CompleteState Current state of the path. [Error](https://arongranberg.com/astar/docs/path/error.html#Error) () Aborts the path because of an error. [FailWithError](https://arongranberg.com/astar/docs/path/failwitherror.html#FailWithError) (msg) Causes the path to fail and sets [errorLog](https://arongranberg.com/astar/docs/path.html#errorLog) to **msg**. [GetTotalLength](https://arongranberg.com/astar/docs/path/gettotallength.html#GetTotalLength) () Total Length of the path. [IsDone](https://arongranberg.com/astar/docs/path/isdone.html#IsDone) () True if this path is done calculating. MarkerOpenCandidateConnectionsToEnd Public Static Readonly ##### Unity.Profiling.ProfilerMarker MarkerOpenCandidateConnectionsToEnd = new Unity.Profiling.ProfilerMarker("OpenCandidateConnectionsToEnd") MarkerTrace Public Static Readonly ##### Unity.Profiling.ProfilerMarker MarkerTrace = new Unity.Profiling.ProfilerMarker("Trace") PipelineState Returns the state of the path in the pathfinding pipeline. Public ##### [PathState](https://arongranberg.com/astar/docs/pathfinding.html#PathState) PipelineState Returns the state of the path in the pathfinding pipeline. [Release](https://arongranberg.com/astar/docs/path/release.html#Release) (o, silent=…) Reduces the reference count on the path by 1 (pooling). [UseSettings](https://arongranberg.com/astar/docs/path/usesettings.html#UseSettings) (settings) Copies the given settings into this path. [WaitForPath](https://arongranberg.com/astar/docs/path/waitforpath.html#WaitForPath) () Waits until this path has been calculated and returned. callback Callback to call when the path is complete. Public ##### [OnPathDelegate](https://arongranberg.com/astar/docs/pathfinding.html#OnPathDelegate) callback Callback to call when the path is complete. This is usually sent to the [Seeker](https://arongranberg.com/astar/docs/seeker.html) component which post processes the path and then calls a callback to the script which requested the path duration How long it took to calculate this path in milliseconds. Public ##### float duration How long it took to calculate this path in milliseconds. error If the path failed, this is true. Public ##### bool error If the path failed, this is true. This typically happens if there's no valid node close enough to the start point of the path, or if there's no node close enough to the target point that is reachable from the start point. The [errorLog](https://arongranberg.com/astar/docs/path.html#errorLog) will have more information about what happened. See [errorLog](https://arongranberg.com/astar/docs/path.html#errorLog) [Error messages](https://arongranberg.com/astar/docs/errormessages.html) This is equivalent to checking path.CompleteState == PathCompleteState.Error errorLog Additional info on why a path failed. Public ##### string errorLog Additional info on why a path failed. See [AstarPath.logPathResults](https://arongranberg.com/astar/docs/astarpath.html#logPathResults) [Error messages](https://arongranberg.com/astar/docs/errormessages.html) heuristic Determines which heuristic to use. Public ##### [Heuristic](https://arongranberg.com/astar/docs/pathfinding.html#Heuristic) heuristic Determines which heuristic to use. heuristicScale Scale of the heuristic values. Public ##### float heuristicScale = 1F Scale of the heuristic values. See [AstarPath.heuristicScale](https://arongranberg.com/astar/docs/astarpath.html#heuristicScale) immediateCallback Immediate callback to call when the path is complete. Public ##### [OnPathDelegate](https://arongranberg.com/astar/docs/pathfinding.html#OnPathDelegate) immediateCallback Immediate callback to call when the path is complete. Warning This may be called from a separate thread. Usually you do not want to use this one. See [callback](https://arongranberg.com/astar/docs/path.html#callback) nearestNodeConstraint Constraint for how to search for nodes that are traversable by this path. Public ##### [NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) nearestNodeConstraint Constraint for how to search for nodes that are traversable by this path. This constraint is what the path uses to search for closest nodes to the start and end points. This is derived from the [traversalConstraint](https://arongranberg.com/astar/docs/path.html#traversalConstraint) and the [nearestNodeDistanceMetric](https://arongranberg.com/astar/docs/path.html#nearestNodeDistanceMetric) . See [AstarPath.GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html) [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint.html) [nearestNodeDistanceMetric](https://arongranberg.com/astar/docs/path.html#nearestNodeDistanceMetric) nearestNodeDistanceMetric Distance metric to use when searching for the start and end nodes in the graph. Public ##### [DistanceMetric](https://arongranberg.com/astar/docs/distancemetric.html) nearestNodeDistanceMetric Distance metric to use when searching for the start and end nodes in the graph. By default, the euclidean distance metric is used. This allows the path to, for example, find the closest start node to the start point, as measured using "normal" distance. However, you can change this to instead measure distance by ignoring the Y coordinate. This is quite useful for characters, as it will find the node right below the agents feet, even if the agent is slightly above the ground on a slope. See [DistanceMetric](https://arongranberg.com/astar/docs/distancemetric.html) [NearestNodeConstraint.distanceMetric](https://arongranberg.com/astar/docs/nearestnodeconstraint.html#distanceMetric) path Holds the path as a [GraphNode](https://arongranberg.com/astar/docs/graphnode.html) list. Public ##### List<[GraphNode](https://arongranberg.com/astar/docs/graphnode.html) \> path Holds the path as a [GraphNode](https://arongranberg.com/astar/docs/graphnode.html) list. These are all nodes that the path traversed, as calculated by the pathfinding algorithm. This may not be the same nodes as the post processed path traverses. See [vectorPath](https://arongranberg.com/astar/docs/path.html#vectorPath) pathID ID of this path. Public ##### ushort pathID ID of this path. Used to distinguish between different paths searchedNodes Number of nodes this path has searched. Public ##### int searchedNodes Number of nodes this path has searched. traversalConstraint Constrains which nodes the path can traverse. Public ##### [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint.html) traversalConstraint = [TraversalConstraint.None](https://arongranberg.com/astar/docs/traversalconstraint.html#None) Constrains which nodes the path can traverse. By default, all walkable nodes are traversable. But you can modify this to, for example, only allow nodes with a certain tag to be traversed, or supply completely custom rules by using an [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) . See [TraversalConstraint](https://arongranberg.com/astar/docs/traversalconstraint.html) [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) traversalCosts Specifies the cost of traversing different nodes. Public ##### [TraversalCosts](https://arongranberg.com/astar/docs/traversalcosts.html) traversalCosts Specifies the cost of traversing different nodes. By default, nodes have no special costs associated with them. But you can modify this to, for example, make nodes with a certain tag more expensive to traverse, or supply completely custom rules by using an [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) . See [TraversalCosts](https://arongranberg.com/astar/docs/traversalcosts.html) [ITraversalProvider](https://arongranberg.com/astar/docs/itraversalprovider.html) vectorPath Holds the (possibly post-processed) path as a Vector3 list. Public ##### List<[Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) \> vectorPath Holds the (possibly post-processed) path as a Vector3 list. This list may be modified by path modifiers to be smoother or simpler compared to the raw path generated by the pathfinding algorithm. See [Using Modifiers](https://arongranberg.com/astar/docs/modifiers2.html) [path](https://arongranberg.com/astar/docs/path.html#path) Private/Protected Members ------------------------- [CalculateStep](https://arongranberg.com/astar/docs/path/calculatestep.html#CalculateStep) (ctx, targetTick) Calculates the path until completed or until the time has passed **targetTick**. [Cleanup](https://arongranberg.com/astar/docs/constantpath/cleanup.html#Cleanup) (ctx) Always called after the path has been calculated. [DebugString](https://arongranberg.com/astar/docs/path/debugstring.html#DebugString) (builder, logMode) Returns a string with information about it. [DebugStringPrefix](https://arongranberg.com/astar/docs/path/debugstringprefix.html#DebugStringPrefix) (logMode, text) Writes text shared for all overrides of DebugString to the string builder. [DebugStringSuffix](https://arongranberg.com/astar/docs/path/debugstringsuffix.html#DebugStringSuffix) (logMode, text) Writes text shared for all overrides of DebugString to the string builder. [OnEnterPool](https://arongranberg.com/astar/docs/constantpath/onenterpool.html#OnEnterPool) () Called when the path enters the pool. [OnFoundEndNode](https://arongranberg.com/astar/docs/constantpath/onfoundendnode.html#OnFoundEndNode) (ctx, pathNode, hScore, gScore) Called when a valid node has been found for the end of the path. [OnHeapExhausted](https://arongranberg.com/astar/docs/constantpath/onheapexhausted.html#OnHeapExhausted) (ctx) Called when there are no more nodes to search. [Prepare](https://arongranberg.com/astar/docs/constantpath/prepare.html#Prepare) (ctx) Called before the path is started. [PrepareBase](https://arongranberg.com/astar/docs/path/preparebase.html#PrepareBase2) (pathHandler) Prepares low level path variables for calculation. [Reset](https://arongranberg.com/astar/docs/constantpath/reset.html#Reset) () Reset the path to default values. [ReturnPath](https://arongranberg.com/astar/docs/path/returnpath.html#ReturnPath2) () Calls callback to return the calculated path. [Setup](https://arongranberg.com/astar/docs/constantpath/setup.html#Setup) (start, maxGScore, callback) Sets up a [ConstantPath](https://arongranberg.com/astar/docs/constantpath.html) starting from the specified point. [Trace](https://arongranberg.com/astar/docs/constantpath/trace.html) (ctx, fromPathNodeIndex, \[reverse\]) completeState Backing field for [CompleteState](https://arongranberg.com/astar/docs/path.html#CompleteState) . Protected ##### [PathCompleteState](https://arongranberg.com/astar/docs/pathfinding.html#PathCompleteState) completeState Backing field for [CompleteState](https://arongranberg.com/astar/docs/path.html#CompleteState) . hasBeenReset True if the Reset function has been called. Protected ##### bool hasBeenReset True if the Reset function has been called. Used to alert users when they are doing something wrong. --- # Rules - A* Pathfinding Project Namespace Rules =============== Classes ------- [CustomGridGraphRuleEditorAttribute](https://arongranberg.com/astar/docs/customgridgraphruleeditorattribute.html) [GridGraphRule](https://arongranberg.com/astar/docs/gridgraphrule.html) Custom rule for a grid graph. [GridGraphRules](https://arongranberg.com/astar/docs/gridgraphrules.html) Container for all rules in a grid graph. [IGridGraphRuleEditor](https://arongranberg.com/astar/docs/igridgraphruleeditor.html) Common interface for all grid graph rule editors. [RuleAnglePenalty](https://arongranberg.com/astar/docs/ruleanglepenalty.html) Applies penalty based on the slope of the surface below the node. [RuleElevationPenalty](https://arongranberg.com/astar/docs/ruleelevationpenalty.html) Applies penalty based on the elevation of the node. [RulePerLayerModifications](https://arongranberg.com/astar/docs/ruleperlayermodifications.html) Modifies nodes based on the layer of the surface under the node. [RuleTexture](https://arongranberg.com/astar/docs/ruletexture.html) Modifies nodes based on the contents of a texture. --- # GetNearestBorder - A* Pathfinding Project Function [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .GetNearestBorder ========================================================================================== ![](https://arongranberg.com/astar/docs/images/navmesh_contour.png) GetNearestBorder ([Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) position, [GraphNode](https://arongranberg.com/astar/docs/graphnode.html) sourceNode, out[GraphHitInfo](https://arongranberg.com/astar/docs/graphhitinfo.html) hit) Finds the closest navmesh border to the given position. Public ##### bool GetNearestBorder ( | | | | | --- | --- | --- | | [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) | position | The position to search from. | | [GraphNode](https://arongranberg.com/astar/docs/graphnode.html) | sourceNode | The node to search from. Only borders connected (directly or indirectly) to this node will be considered. This could for example be the node that an agent is currently standing on. | | out[GraphHitInfo](https://arongranberg.com/astar/docs/graphhitinfo.html) | hit | Information about the closest border, if any was found. | ) Finds the closest navmesh border to the given position. ![](https://arongranberg.com/astar/docs/images/navmesh_contour.png) Your browser does not support the video tag. `var origin = target.position; using (Draw.WithLineWidth(2)) { if ([AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearestBorder](https://arongranberg.com/astar/docs/astarpath/getnearestborder.html#GetNearestBorder) (origin, NearestNodeConstraint.Walkable, out var hit)) { Draw.Arrow(origin, hit.point, [Palette](https://arongranberg.com/astar/docs/pid.html#Palette) .Yellow); Draw.SphereOutline(origin, 0.1f, [Palette](https://arongranberg.com/astar/docs/pid.html#Palette) .Yellow); Draw.SphereOutline(hit.point, 0.1f, [Palette](https://arongranberg.com/astar/docs/pid.html#Palette) .Yellow); Draw.Ray(hit.tangentOrigin, hit.tangent, [Palette](https://arongranberg.com/astar/docs/pid.html#Palette) .Purple); } } ` Return True if a border was found, false otherwise. Note hit.node will always be null, as it is currently not possible for the code to figure out which border belongs to what node. You can call [AstarPath.GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html) with hit.point if you need this information. See [GraphUtilities.GetContours](https://arongranberg.com/astar/docs/graphutilities/getcontours.html) [GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html) [FollowerEntity.nearestNavmeshBorder](https://arongranberg.com/astar/docs/followerentity.html#nearestNavmeshBorder) GetNearestBorder ([Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) position, [NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) constraint, out[GraphHitInfo](https://arongranberg.com/astar/docs/graphhitinfo.html) hit) Finds the closest navmesh border to the given position. Public ##### bool GetNearestBorder ( | | | | | --- | --- | --- | | [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) | position | The position to search from. | | [NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) | constraint | Constraint for which nodes are acceptable for the agent to stand on. | | out[GraphHitInfo](https://arongranberg.com/astar/docs/graphhitinfo.html) | hit | Information about the closest border, if any was found. | ) Finds the closest navmesh border to the given position. Return True if a border was found, false otherwise. ![](https://arongranberg.com/astar/docs/images/navmesh_contour.png) Your browser does not support the video tag. `var origin = target.position; using (Draw.WithLineWidth(2)) { if ([AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearestBorder](https://arongranberg.com/astar/docs/astarpath/getnearestborder.html#GetNearestBorder) (origin, NearestNodeConstraint.Walkable, out var hit)) { Draw.Arrow(origin, hit.point, [Palette](https://arongranberg.com/astar/docs/pid.html#Palette) .Yellow); Draw.SphereOutline(origin, 0.1f, [Palette](https://arongranberg.com/astar/docs/pid.html#Palette) .Yellow); Draw.SphereOutline(hit.point, 0.1f, [Palette](https://arongranberg.com/astar/docs/pid.html#Palette) .Yellow); Draw.Ray(hit.tangentOrigin, hit.tangent, [Palette](https://arongranberg.com/astar/docs/pid.html#Palette) .Purple); } } `This method will first find the nearest node to the specified position using the specified constraint. You can think of this as the node the agent is currently standing on. Then, it will search for the closest border to that node, which is connected to it. The constraint is only used to find the nearest node, it does not inform what borders are found afterwards. Notably, if an agent cannot traverse a given tag, it will still not consider a border between that tag and a node with a walkable tag as a valid border. On a point graph, this method will always return false, since point nodes do not have any borders as such. Note hit.node will always be null, as it is currently not possible for the code to figure out which border belongs to what node. You can call [AstarPath.GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html) with hit.point if you need this information. See [GraphUtilities.GetContours](https://arongranberg.com/astar/docs/graphutilities/getcontours.html) [GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html) [FollowerEntity.nearestNavmeshBorder](https://arongranberg.com/astar/docs/followerentity.html#nearestNavmeshBorder) --- # Linecast - A* Pathfinding Project Function [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .Linecast ================================================================================== Linecast ([Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) start, [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) end) True if there is an obstacle between **start** and **end** on the navmesh. Public ##### bool Linecast ( | | | | | --- | --- | --- | | [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) | start | | | [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) | end | | ) True if there is an obstacle between **start** and **end** on the navmesh. This is a simple api to check if there is an obstacle between two points. If you need more detailed information, you can use [GridGraph.Linecast](https://arongranberg.com/astar/docs/gridgraph/linecast.html) or [NavmeshBase.Linecast](https://arongranberg.com/astar/docs/navmeshbase/linecast.html) (for navmesh/recast graphs). Those overloads can also return which nodes the line passed through, and allow you use custom node filtering. `var start = transform.position; var end = start + Vector3.forward * 10; if ([AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[Linecast](https://arongranberg.com/astar/docs/astarpath/linecast.html#Linecast) (start, end)) { Debug.DrawLine(start, end, Color.red); } else { Debug.DrawLine(start, end, Color.green); } ` Note Only grid, recast and navmesh graphs support linecasts. The closest raycastable graph to the start point will be used for the linecast. Linecasts cannot pass through off-mesh links. Your browser does not support the video tag. See [NavmeshBase.Linecast](https://arongranberg.com/astar/docs/navmeshbase/linecast.html) [GridGraph.Linecast](https://arongranberg.com/astar/docs/gridgraph/linecast.html) [IRaycastableGraph](https://arongranberg.com/astar/docs/iraycastablegraph.html) [Detecting obstacles along a line](https://arongranberg.com/astar/docs/linecasting.html) , for more details about linecasting Linecast ([Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) start, [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) end, out[GraphHitInfo](https://arongranberg.com/astar/docs/graphhitinfo.html) hit) True if there is an obstacle between **start** and **end** on the navmesh. Public ##### bool Linecast ( | | | | | --- | --- | --- | | [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) | start | | | [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) | end | | | out[GraphHitInfo](https://arongranberg.com/astar/docs/graphhitinfo.html) | hit | | ) True if there is an obstacle between **start** and **end** on the navmesh. This is a simple api to check if there is an obstacle between two points. If you need more detailed information, you can use [GridGraph.Linecast](https://arongranberg.com/astar/docs/gridgraph/linecast.html) or [NavmeshBase.Linecast](https://arongranberg.com/astar/docs/navmeshbase/linecast.html) (for navmesh/recast graphs). Those overloads can also return which nodes the line passed through, and allow you use custom node filtering. `var start = transform.position; var end = start + Vector3.forward * 10; if ([AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[Linecast](https://arongranberg.com/astar/docs/astarpath/linecast.html#Linecast) (start, end, out var hit)) { Debug.DrawLine(start, end, Color.red); Debug.DrawRay(hit.point, Vector3.up, Color.red); } else { Debug.DrawLine(start, end, Color.green); } ` Note Only grid, recast and navmesh graphs support linecasts. The closest raycastable graph to the start point will be used for the linecast. Linecasts cannot pass through off-mesh links. Your browser does not support the video tag. See [NavmeshBase.Linecast](https://arongranberg.com/astar/docs/navmeshbase/linecast.html) [GridGraph.Linecast](https://arongranberg.com/astar/docs/gridgraph/linecast.html) [IRaycastableGraph](https://arongranberg.com/astar/docs/iraycastablegraph.html) [Detecting obstacles along a line](https://arongranberg.com/astar/docs/linecasting.html) , for more details about linecasting --- # Voxelization - A* Pathfinding Project Namespace Voxelization ====================== Namespaces ---------- [Burst](https://arongranberg.com/astar/docs/burst.html) Classes ------- [Int3PolygonClipper](https://arongranberg.com/astar/docs/int3polygonclipper.html) Utility for clipping polygons. [VoxelPolygonClipper](https://arongranberg.com/astar/docs/voxelpolygonclipper.html) Utility for clipping polygons. --- # Writing Custom Grid Graph Rules - A* Pathfinding Project Writing Custom Grid Graph Rules =============================== This tutorial assumes you are at least somewhat familiar with grid graph rules. If not, take a look at [Grid Graph Rules](https://arongranberg.com/astar/docs/gridrules.html) first. Contents -------- * [Why write a grid graph rule](https://arongranberg.com/astar/docs/gridruleswrite.html#grid-rules-write-why) * [How a rule works conceptually](https://arongranberg.com/astar/docs/gridruleswrite.html#grid-rules-write-concept) * [Unity Job System or Main Thread](https://arongranberg.com/astar/docs/gridruleswrite.html#grid-rules-write-jobsystem) * [Writing a simple example rule](https://arongranberg.com/astar/docs/gridruleswrite.html#gridgraphrule-simple) * [Writing a rule that uses the Unity Job System](https://arongranberg.com/astar/docs/gridruleswrite.html#gridgraphrule-burst) * [Connection filters using the Unity Job System](https://arongranberg.com/astar/docs/gridruleswrite.html#gridgraphrule-connection-filter) * [Data layout](https://arongranberg.com/astar/docs/gridruleswrite.html#gridgraphrule-data-layout) Why write a grid graph rule --------------------------- Sometimes you want to modify the scanning process in some way. Maybe your game has its own rules about which nodes are walkable, and you want to sync that with the grid graph. You could iterate through all the nodes after the graph has been scanned and apply whatever modifications you want, but this adds complexity and doesn't play nicely with graph updates. When writing the logic as a grid graph rule, it will work seamlessly with graph updates and scripts such as the [ProceduralGraphMover](https://arongranberg.com/astar/docs/proceduralgraphmover.html) . And you can easily use the Unity Job system and the Burst compiler to speed up the code significantly. There are also some helper methods included to make it very easy to, for example, create a filter for which connections in the grid should be valid and which ones are not valid. How a rule works conceptually ----------------------------- A rule conceptually works like this: 1. The rule registers itself and hooks into the scanning process. 2. When the graph is scanned or updated, it will call those hooks. 3. Inside the hooks, the rule can modify the graph data as it wishes. A rule can register itself to hook into different points in the scanning process. These points are called passes. Most rules only use a single pass, but they can register multiple ones if needed. Pass Where in the scanning process a rule will be executed. Check the documentation for [GridGraphScanData](https://arongranberg.com/astar/docs/gridgraphscandata.html) to see which data fields are valid in which passes. | | | | --- | --- | | BeforeCollision | Before the collision testing phase but after height testing.

This is very early. Most data is not valid by this point.

You can use this if you want to modify the node positions and still have it picked up by the collision testing code. | | BeforeConnections | Before connections are calculated.

At this point height testing and collision testing has been done (if they are enabled).

This is the most common pass to use. If you are modifying walkability here then connections and erosion will be calculated properly. | | AfterConnections | After connections are calculated.

If you are modifying connections directly you should do that in this pass.

Note

If erosion is used then this pass will be executed twice. One time before erosion and one time after erosion when the connections are calculated again. | | AfterErosion | After erosion is calculated but before connections have been recalculated.

If no erosion is used then this pass will not be executed. | | PostProcess | After everything else.

This pass is executed after everything else is done. You should not modify walkability in this pass because then the node connections will not be up to date. | | AfterApplied | After the graph update has been applied to the graph.

This pass can only be added as a main-thread pass. If many updates are applied to the graph at the same time, this pass will only execute once after all updates have been applied.

Warning

No data in the context except the reference to the graph is valid at this point. It has all been disposed. You cannot modify any data in this pass. | See This setting corresponds to the member [GridGraphRule.Pass](https://arongranberg.com/astar/docs/gridgraphrule.html#Pass) Rules are called both when scanning a graph and when the graph is being updated. However, when the graph is being updated, it will only provide data for a smaller sub-rectangle of the grid. Your grid graph rule must take this into account and not just assume it is used on the whole graph all the time (see also [Data layout](https://arongranberg.com/astar/docs/gridruleswrite.html#gridgraphrule-data-layout) ). Rules can be placed anywhere in your project. They will be found dynamically, and you will be able to add them using the 'Add Rule' button in the grid graph inspector. You can also add a custom editor GUI to your rule if you want to be able to change its settings from the inspector. Unity Job System or Main Thread ------------------------------- You have two options for how to run rules: * Run them on the main thread. This is easier, has less boilerplate, and you can access non-thread-safe data from the rule. * Run them using the Unity Job System. This has some additional boilerplate, but the job can be run in parallel with other grid graph scanning code, and it can use the Burst compiler. This makes it possible to write very fast jobs this way. For your first rule, I'd recommend writing one that runs on the main thread, and if you need the performance, you can switch to the job system. In the following sections, a few examples of rules will be shown. Writing a simple example rule ----------------------------- Let's write a simple rule that sets the walkability for the nodes based on a [noise function](https://en.wikipedia.org/wiki/Perlin_noise) . The result will look something like this: ![](https://arongranberg.com/astar/docs/images/grid_perlin.png) To do this, we need to iterate through every node and set its walkability. `using UnityEngine; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) ; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) .[Graphs](https://arongranberg.com/astar/docs/graphs2.html) .[Grid](https://arongranberg.com/astar/docs/grid.html) .[Rules](https://arongranberg.com/astar/docs/rules.html) ; // Mark with the Preserve attribute to ensure that this class is not removed when bytecode stripping is used. See https://docs.unity3d.com/Manual/IL2CPP-BytecodeStripping.html [[Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) .[Util](https://arongranberg.com/astar/docs/util2.html) .Preserve] public class RuleExampleNodes : GridGraphRule { public float perlinNoiseScale = 10.0f; public float perlinNoiseThreshold = 0.4f; public override void Register (GridGraphRules rules) { // The Register method will be called once the first time the rule is used // and it will be called again if any settings for the rule changes in the inspector. // Use this part to do any precalculations that you need later. // Hook into the grid graph's calculation code rules.AddMainThreadPass(Pass.BeforeConnections, context => { // This callback is called when scanning the graph and during graph updates. // Here you can modify the graph data as you wish. // The context.data object contains all the node data as NativeArrays // Not all data is valid for all passes since it may not have been calculated at that time. // You can find more info about that on the documentation for the GridGraphScanData object. // Get the data arrays we need var nodeWalkable = context.data.nodes.walkable; var nodePositions = context.data.nodes.positions; // We iterate through all nodes and mark them as walkable or unwalkable based on some perlin noise for (int i = 0; i < nodePositions.Length; i++) { var position = nodePositions[i]; nodeWalkable[i] &= Mathf.PerlinNoise(position.x / perlinNoiseScale, position.z / perlinNoiseScale) > perlinNoiseThreshold; } }); } } ` See In the callback for when the rule is being executed, you get a context object with a lot of data about the graph. Take a look at the [GridGraphRules.Context](https://arongranberg.com/astar/docs/context.html) class for more info about what data there is to use. In particular, the data field of that class, which is an instance of the [GridGraphScanData](https://arongranberg.com/astar/docs/gridgraphscandata.html) class. You can place this anywhere, and it will show up when clicking the "Add Rule" button in the GridGraph inspector. Every rule also needs a corresponding editor script to be able to show its settings. You should place this script in an [Editor folder](https://docs.unity3d.com/Manual/SpecialFolders.html) . `using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) .[Graphs](https://arongranberg.com/astar/docs/graphs2.html) .[Grid](https://arongranberg.com/astar/docs/grid.html) .[Rules](https://arongranberg.com/astar/docs/rules.html) ; using UnityEditor; using UnityEngine; namespace [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) { [CustomGridGraphRuleEditor(typeof(RuleExampleNodes), "Simple Example Rule")] public class RuleExampleNodesEditor : IGridGraphRuleEditor { public void OnInspectorGUI (GridGraph graph, GridGraphRule rule) { var target = rule as RuleExampleNodes; target.perlinNoiseScale = EditorGUILayout.FloatField("Noise Scale", target.perlinNoiseScale); target.perlinNoiseThreshold = EditorGUILayout.FloatField("Noise Threshold", target.perlinNoiseThreshold); } public void OnSceneGUI (GridGraph graph, GridGraphRule rule) { } } } ` Now the rule will work! Below, you can see a video of how this simple rule works. Your browser does not support the video tag. Writing a rule that uses the Unity Job System --------------------------------------------- When using the Unity Job System, we will use the [AddJobSystemPass](https://arongranberg.com/astar/docs/gridgraphrules/addjobsystempass.html#AddJobSystemPass) method instead of [AddMainThreadPass](https://arongranberg.com/astar/docs/gridgraphrules/addmainthreadpass.html#AddMainThreadPass) . In this method, you should only schedule jobs, not access the data itself. We can rewrite our previous simple rule to use the job system. We will also use a nice helper function [GridIterationUtilities.ForEachNode](https://arongranberg.com/astar/docs/griditerationutilities/foreachnode.html#ForEachNode) . To use it, our job struct needs to implement the [GridIterationUtilities.INodeModifier](https://arongranberg.com/astar/docs/inodemodifier.html) interface. It will be called once for every relevant node. Note that during graph updates, it may only be called for a few nodes, not all nodes in the graph. `using UnityEngine; using Unity.Collections; using Unity.Jobs; using Unity.Burst; using Unity.Mathematics; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) ; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) .[Jobs](https://arongranberg.com/astar/docs/jobs3.html) ; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) .[Graphs](https://arongranberg.com/astar/docs/graphs2.html) .[Grid](https://arongranberg.com/astar/docs/grid.html) ; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) .[Graphs](https://arongranberg.com/astar/docs/graphs2.html) .[Grid](https://arongranberg.com/astar/docs/grid.html) .[Rules](https://arongranberg.com/astar/docs/rules.html) ; [[Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) .[Util](https://arongranberg.com/astar/docs/util2.html) .Preserve] public class RuleExampleNodesBurst : GridGraphRule { public float perlinNoiseScale = 10.0f; public float perlinNoiseThreshold = 0.4f; public override void Register (GridGraphRules rules) { // Here we use the job system instead of running the rule on the main thread. // Note that in that case we should *only schedule jobs* inside the callback. // The data is not safe to access directly in the callback. rules.AddJobSystemPass(Pass.BeforeConnections, context => { // This callback is called when scanning the graph and during graph updates. // The only thing we do is to schedule a job using the Unity job system. // You do not have to deal with dependencies yourself // just make sure you use the appropriate [ReadOnly] or [WriteOnly] tags // See https://docs.unity3d.com/Manual/JobSystem.html for more info. // The context.data object contains all the node data as NativeArrays new JobExample { bounds = context.data.nodes.bounds, nodeWalkable = context.data.nodes.walkable, nodePositions = context.data.nodes.positions, nodeNormals = context.data.nodes.normals, perlinNoiseScale = perlinNoiseScale, perlinNoiseThreshold = perlinNoiseThreshold, }.Schedule(context.tracker); }); } [BurstCompile] struct JobExample : IJob, GridIterationUtilities.INodeModifier { public IntBounds bounds; public float perlinNoiseScale; public float perlinNoiseThreshold; public NativeArray nodeWalkable; [ReadOnly] public NativeArray nodePositions; [ReadOnly] public NativeArray nodeNormals; public void Execute () { // Used to efficiently iterate through all nodes that are being calculated. // The nodeNormals array is used by the ForEachNode function to determine if a node exists. // The normal is (0,0,0) if and only if the node doesn't exist (important for layered grid graphs). GridIterationUtilities.ForEachNode(bounds.size, nodeNormals, ref this); } public void ModifyNode (int dataIndex, int dataX, int dataLayer, int dataZ) { var position = nodePositions[dataIndex]; nodeWalkable[dataIndex] &= Mathf.PerlinNoise(position.x / perlinNoiseScale, position.z / perlinNoiseScale) > perlinNoiseThreshold; } } } ` Note Normally when the Unity Job System is used, you have to specify the dependencies of the jobs manually. This is tedious and error-prone, so a helper script is used which will read the \[ReadOnly\] and \[WriteOnly\] attributes that you use on fields in the job structs and automatically calculate the dependencies for you. For more info, take a look at the [JobDependencyTracker](https://arongranberg.com/astar/docs/jobdependencytracker.html) class. Connection filters using the Unity Job System --------------------------------------------- Another common situation is that you want to control which node connections are traversable and which ones are not. You can do this easily with the [IConnectionFilter](https://arongranberg.com/astar/docs/iconnectionfilter.html) interface and the [FilterNodeConnections](https://arongranberg.com/astar/docs/griditerationutilities/filternodeconnecti.html#FilterNodeConnections) function. `using UnityEngine; using Unity.Collections; using Unity.Jobs; using Unity.Burst; using Unity.Mathematics; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) ; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) .[Jobs](https://arongranberg.com/astar/docs/jobs3.html) ; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) .[Graphs](https://arongranberg.com/astar/docs/graphs2.html) .[Grid](https://arongranberg.com/astar/docs/grid.html) .[Rules](https://arongranberg.com/astar/docs/rules.html) ; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) .[Graphs](https://arongranberg.com/astar/docs/graphs2.html) .[Grid](https://arongranberg.com/astar/docs/grid.html) ; [[Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) .[Util](https://arongranberg.com/astar/docs/util2.html) .Preserve] public class RuleExampleConnection : GridGraphRule { public override void Register (GridGraphRules rules) { rules.AddJobSystemPass(Pass.AfterConnections, context => { new JobExample { bounds = context.data.nodes.bounds, nodeConnections = context.data.nodes.connections, nodeWalkable = context.data.nodes.walkable, nodePositions = context.data.nodes.positions, layeredDataLayout = context.data.nodes.layeredDataLayout, }.Schedule(context.tracker); }); } [BurstCompile] struct JobExample : IJob, GridIterationUtilities.IConnectionFilter { public IntBounds bounds; public NativeArray nodeConnections; [WriteOnly] public NativeArray nodeWalkable; [ReadOnly] public NativeArray nodePositions; public bool layeredDataLayout; public void Execute () { GridIterationUtilities.FilterNodeConnections(bounds, nodeConnections, layeredDataLayout, ref this); } public bool IsValidConnection (int dataIndex, int dataX, int dataLayer, int dataZ, int direction, int neighbourDataIndex) { // Get our position and the adjacent node's position var position = nodePositions[dataIndex]; var neighbourPosition = nodePositions[neighbourDataIndex]; // Only allow a connection if the adjacent node differs less // than 1 meter from this one along the Y coordinate. // This is similar to "Max Climb" in the GridGraph settings. return math.abs(position.y - neighbourPosition.y) < 1.0f; } } } ` See [Data layout](https://arongranberg.com/astar/docs/gridruleswrite.html#gridgraphrule-data-layout) for details about how the nodes are laid out in memory. The IsValidConnection method will be called for every connection that is being updated. It will only be called for connections that are valid at that point in the scanning process. This means that you cannot enable connections that were previously disabled. Data layout ----------- When a grid graph is scanned or updated, all the temporary data is stored in NativeArrays. When only a small section of the grid graph is updated, these temporary arrays will be smaller than the whole graph, so you cannot access them with the same indices as the normal nodes. Note The code uses the naming convention **dataX** and **dataZ** to refer to the x and z coordinates in the NativeArrays used in this graph update/scan. ![](https://arongranberg.com/astar/docs/images/gridgraph/grid_data_layout.svg) **dataX** and **dataZ** may not correspond to the x and z coordinates in the actual graph, since graph updates usually only affect a small portion of the graph. You can convert them to the grid x and z coordinates like this: `gridX = dataX + bounds.xmin; gridZ = dataZ + bounds.zmin; ` If you do not use the [IConnectionFilter](https://arongranberg.com/astar/docs/iconnectionfilter.html) , you can access the neighbours of a node using the [GridIterationUtilities.GetNeighbourDataIndex](https://arongranberg.com/astar/docs/griditerationutilities/getneighbourdatain.html#GetNeighbourDataIndex) method. --- # Jobs - A* Pathfinding Project Namespace Jobs ============== Classes ------- [JobAllocateNodes](https://arongranberg.com/astar/docs/joballocatenodes2.html) Allocates and deallocates nodes in a grid graph. [JobCalculateGridConnections](https://arongranberg.com/astar/docs/jobcalculategridconnections.html) Calculates the grid connections for all nodes. [JobCheckCollisions](https://arongranberg.com/astar/docs/jobcheckcollisions.html) Checks if nodes are obstructed by obstacles or not. [JobColliderHitsToBooleans](https://arongranberg.com/astar/docs/jobcolliderhitstobooleans.html) Fills the output with true or false depending on if the collider hit was a hit. [JobCopyBuffers](https://arongranberg.com/astar/docs/jobcopybuffers.html) Copies 3D arrays with grid data from one shape to another. [JobErosion](https://arongranberg.com/astar/docs/joberosion.html) Calculates erosion. [JobFilterDiagonalConnections](https://arongranberg.com/astar/docs/jobfilterdiagonalconnections.html) Filters out diagonal connections that are not allowed in layered grid graphs. [JobMergeRaycastCollisionHits](https://arongranberg.com/astar/docs/jobmergeraycastcollisionhits.html) Calculates if either of the two input hits actually hit something. [JobNodeGridLayout](https://arongranberg.com/astar/docs/jobnodegridlayout.html) Calculates the default node positions for a grid graph. [JobNodeWalkability](https://arongranberg.com/astar/docs/jobnodewalkability.html) Calculates for each grid node if it should be walkable or not. [JobPrepareCapsuleCommands](https://arongranberg.com/astar/docs/jobpreparecapsulecommands.html) Prepares a set of capsule commands for collision checking in a grid graph. [JobPrepareGridRaycast](https://arongranberg.com/astar/docs/jobpreparegridraycast.html) Prepares a set of raycast commands for a grid graph. [JobPrepareGridRaycastThick](https://arongranberg.com/astar/docs/jobpreparegridraycastthick.html) Prepares a set of thick raycast commands for a grid graph. [JobPrepareRaycasts](https://arongranberg.com/astar/docs/jobprepareraycasts.html) Prepares a set of raycast commands for a grid graph. [JobPrepareSphereCommands](https://arongranberg.com/astar/docs/jobpreparespherecommands.html) Prepares a set of sphere commands for collision checking in a grid graph. [JobReadNodeData](https://arongranberg.com/astar/docs/jobreadnodedata.html) Reads node data from managed [GridNodeBase](https://arongranberg.com/astar/docs/gridnodebase.html) objects into unmanaged arrays. [JobRelocateNodes](https://arongranberg.com/astar/docs/jobrelocatenodes.html) Moves all nodes to new positions. [JobWriteNodeData](https://arongranberg.com/astar/docs/jobwritenodedata.html) Writes node data from unmanaged arrays into managed [GridNodeBase](https://arongranberg.com/astar/docs/gridnodebase.html) objects. --- # NextBlock - A* Pathfinding Project Struct NextBlock ================ Public Public Variables ---------------- next Public ##### int next --- # Navmesh - A* Pathfinding Project Namespace Navmesh ================= Namespaces ---------- [Jobs](https://arongranberg.com/astar/docs/jobs2.html) [Voxelization](https://arongranberg.com/astar/docs/voxelization.html) Classes ------- [CircleGeometryUtilities](https://arongranberg.com/astar/docs/circlegeometryutilities.html) [ColliderMeshBuilder2D](https://arongranberg.com/astar/docs/collidermeshbuilder2d.html) [NavmeshTile](https://arongranberg.com/astar/docs/navmeshtile.html) A single tile in a recast or navmesh graph. [NavmeshUpdates](https://arongranberg.com/astar/docs/navmeshupdates.html) Helper for navmesh cut objects. [RecastBuilder](https://arongranberg.com/astar/docs/recastbuilder.html) Helper methods for scanning a recast graph. [RecastMeshGatherer](https://arongranberg.com/astar/docs/recastmeshgatherer.html) [RelevantGraphSurface](https://arongranberg.com/astar/docs/relevantgraphsurface.html) Pruning of recast navmesh regions. [TileBuilder](https://arongranberg.com/astar/docs/tilebuilder.html) Settings for building tile meshes in a recast graph. [TileCutter](https://arongranberg.com/astar/docs/tilecutter.html) [TileHandler](https://arongranberg.com/astar/docs/tilehandler.html) Utility class for updating tiles of navmesh/recast graphs. [TileHandlerCache](https://arongranberg.com/astar/docs/tilehandlercache.html) [TileLayout](https://arongranberg.com/astar/docs/tilelayout.html) Represents the position and size of a tile grid for a recast/navmesh graph. [TileMesh](https://arongranberg.com/astar/docs/tilemesh.html) A tile in a navmesh graph. [TileMeshes](https://arongranberg.com/astar/docs/tilemeshes.html) Represents a rectangular group of tiles of a recast graph. [TileMeshesUnsafe](https://arongranberg.com/astar/docs/tilemeshesunsafe.html) Unsafe representation of a [TileMeshes](https://arongranberg.com/astar/docs/tilemeshes.html) struct. Public Typedefs --------------- NativeHashMapVector2IntInt ##### Unity.Collections.NativeHashMap NativeHashMapVector2IntInt --- # FollowerEntity - A* Pathfinding Project Class FollowerEntity Extends [VersionedMonoBehaviour](https://arongranberg.com/astar/docs/versionedmonobehaviour.html) , [IAstarAI](https://arongranberg.com/astar/docs/iastarai.html) , [ISerializationCallbackReceiver](https://docs.unity3d.com/ScriptReference/ISerializationCallbackReceiver.html) ======================================================================================================================================================================================================================================================================================================== Public Movement script that uses ECS. ![](https://arongranberg.com/astar/docs/images/generated/inspectors/FollowerEntity@2x.png) This script is a replacement for the [AIPath](https://arongranberg.com/astar/docs/aipath.html) and [RichAI](https://arongranberg.com/astar/docs/richai.html) scripts. This script is a movement script. It takes care of moving an agent along a path, updating the path, and so on. Contents -------- * [Introduction](https://arongranberg.com/astar/docs/followerentity.html#followerentity-intro) * [Features](https://arongranberg.com/astar/docs/followerentity.html#followerentity-features) * [Inspector](https://arongranberg.com/astar/docs/followerentity.html#followerentity-inspector) * [ECS](https://arongranberg.com/astar/docs/followerentity.html#followerentity-ecs) * [Usage in ECS subscenes](https://arongranberg.com/astar/docs/followerentity.html#followerentity-subscenes) * [Differences compared to AIPath and RichAI](https://arongranberg.com/astar/docs/followerentity.html#followerentity-differences) * [Best practices for good performance](https://arongranberg.com/astar/docs/followerentity.html#followerentity-bestpractices) * [Time scaling](https://arongranberg.com/astar/docs/followerentity.html#followerentity-timescale) Introduction ------------ The intended way to use this script is to use these two components: * [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) * [AIDestinationSetter](https://arongranberg.com/astar/docs/aidestinationsetter.html) (optional, you can instead set the [destination](https://arongranberg.com/astar/docs/followerentity.html#destination) property manually) Of note is that this component shouldn't be used with a [Seeker](https://arongranberg.com/astar/docs/seeker.html) component. It has its own settings for pathfinding instead, which are stored in the [pathfindingSettings](https://arongranberg.com/astar/docs/followerentity.html#pathfindingSettings) field. When used with local avoidance, it also has its own settings for local avoidance which are stored in the [rvoSettings](https://arongranberg.com/astar/docs/followerentity.html#rvoSettings) field, instead of using a separate [RVOController](https://arongranberg.com/astar/docs/rvocontroller.html) component. Other than that, you can use it just like the other movement scripts in this package. Features -------- * Uses Unity's ECS (Entity Component System) to move the agent. This means it is highly-performant and is able to utilize multiple threads. You do not need to know anything about ECS to be able to use it. * Supports local avoidance (see [Local Avoidance](https://arongranberg.com/astar/docs/localavoidance.html) ). * Supports movement in both 2D and 3D games. * Supports movement on spherical on non-planar worlds (see [Spherical Worlds](https://arongranberg.com/astar/docs/spherical.html) ). * Supports movement on grid graphs as well as navmesh/recast graphs. * Not recommended on hexagonal graphs at the moment (though it does mostly work). * Does **not** support movement on point graphs at the moment. This may be added in a future update. * Supports time-scales greater than 1. The agent will automatically run multiple simulation steps per frame if the time-scale is greater than 1, to ensure stability. * Supports off-mesh links. See [Off-mesh links](https://arongranberg.com/astar/docs/offmeshlinks2.html) for more info. * Knows which node it is traversing at all times (see [currentNode](https://arongranberg.com/astar/docs/followerentity.html#currentNode) ). * Automatically stops when trying to reach a crowded destination when using local avoidance. * Clamps the agent to the navmesh at all times. * Follows paths very smoothly. * Can keep a desired distance to walls. * Can approach its destination with a desired facing direction. Inspector --------- **Shape** Radius Radius of the agent in world units. This is visualized in the scene view as a yellow cylinder around the character. Note that this does not affect pathfinding in any way. The graph used completely determines where the agent can move. Note The [Pathfinding.AILerp](https://arongranberg.com/astar/docs/ailerp.html) script doesn't really have any use of knowing the radius or the height of the character, so this property will always return 0 in that script. See This setting corresponds to the member [radius](https://arongranberg.com/astar/docs/followerentity.html#radius) Height Height of the agent in world units. This is visualized in the scene view as a yellow cylinder around the character. This value is used for various heuristics, and for visualization purposes. For example, the destination is only considered reached if the destination is not above the agent's head, and it's not more than half the agent's height below its feet. If local lavoidance is enabled, this is also used to filter out collisions with agents and obstacles that are too far above or below the agent. See This setting corresponds to the member [height](https://arongranberg.com/astar/docs/followerentity.html#height) Orientation Determines which direction the agent moves in. For 3D games you most likely want the ZAxisIsForward option as that is the convention for 3D games. For 2D games you most likely want the YAxisIsForward option as that is the convention for 2D games. When using ZAxisForward, the +Z axis will be the forward direction of the agent, +Y will be upwards, and +X will be the right direction. When using YAxisForward, the +Y axis will be the forward direction of the agent, +Z will be upwards, and +X will be the right direction. Note This only affects the rotation of the GameObject's Transform, not the entity's internal rotation. Thus it has no effect when the agent is baked in a subscene, since there is no Transform object in that case. ![](https://arongranberg.com/astar/docs/images/aibase_forward_axis.png) See This setting corresponds to the member [orientation](https://arongranberg.com/astar/docs/followerentity.html#orientation) **Movement** Speed Max speed in world units per second. See This setting corresponds to the member [maxSpeed](https://arongranberg.com/astar/docs/followerentity.html#maxSpeed) Rotation Speed Desired rotation speed in degrees per second. If the agent is in an open area and gets a new destination directly behind itself, it will start to rotate around with exactly this rotation speed. The agent will slow down its rotation speed as it approaches its desired facing direction. So for example, when it is only 90 degrees away from its desired facing direction, it will only rotate with about half this speed. See [maxRotationSpeed](https://arongranberg.com/astar/docs/pidmovement.html#maxRotationSpeed) See This setting corresponds to the member [rotationSpeed](https://arongranberg.com/astar/docs/followerentity.html#rotationSpeed) Max Rotation Speed Maximum rotation speed in degrees per second. If the agent would have to rotate faster than this, it will instead slow down to get more time to rotate. The agent may want to rotate faster than [rotationSpeed](https://arongranberg.com/astar/docs/pidmovement.html#rotationSpeed) if there's not enough space, so that it has to move in a more narrow arc. It may also want to rotate faster if it is very close to its destination and it wants to make sure it ends up on the right spot without any circling. It is recommended to keep this at a value slightly larger than [rotationSpeed](https://arongranberg.com/astar/docs/pidmovement.html#rotationSpeed) . See [rotationSpeed](https://arongranberg.com/astar/docs/pidmovement.html#rotationSpeed) See This setting corresponds to the member [maxRotationSpeed](https://arongranberg.com/astar/docs/followerentity.html#maxRotationSpeed) Allow Rotating On The Spot If rotation on the spot is allowed or not. When the agent wants to turn significantly, enabling this will make it turn on the spot instead of moving in an arc. This can make for more responsive and natural movement for humanoid characters. See This setting corresponds to the member [movementSettings.follower.allowRotatingOnSpot](https://arongranberg.com/astar/docs/pidmovement.html#allowRotatingOnSpot) Max On Spot Rotation Speed Maximum rotation speed in degrees per second while rotating on the spot. Only used if [allowRotatingOnSpot](https://arongranberg.com/astar/docs/pidmovement.html#allowRotatingOnSpot) is enabled. See This setting corresponds to the member [movementSettings.follower.maxOnSpotRotationSpeed](https://arongranberg.com/astar/docs/pidmovement.html#maxOnSpotRotationSpeed) Slowdown Time When Turning On Spot Time for the agent to slow down to a complete stop when rotating on the spot. If set to zero, the agent will instantly stop and start to turn around. Only used if [allowRotatingOnSpot](https://arongranberg.com/astar/docs/pidmovement.html#allowRotatingOnSpot) is enabled. See This setting corresponds to the member [movementSettings.follower.slowdownTimeWhenTurningOnSpot](https://arongranberg.com/astar/docs/pidmovement.html#slowdownTimeWhenTurningOnSpot) Position Smoothing How much to smooth the visual position of the agent. This does not affect movement, but smoothes out the position of the agent visually. Recommended values are between 0.0 and 0.5. A value of zero will disable smoothing completely. This will make the agent seem to lag slightly behind the internal position of the agent. It may also cut corners slightly. The unit for this field is seconds. See This setting corresponds to the member [positionSmoothing](https://arongranberg.com/astar/docs/followerentity.html#positionSmoothing) Rotation Smoothing How much to smooth the visual rotation of the agent. This does not affect movement, but smoothes out how the agent rotates visually. Recommended values are between 0.0 and 0.5. A value of zero will disable smoothing completely. The smoothing is done primarily using an exponential moving average, but with a small linear term to make the rotation converge faster when the agent is almost facing the desired direction. Adding smoothing will make the visual rotation of the agent lag a bit behind the actual rotation. Too much smoothing may make the agent seem sluggish, and appear to move sideways. The unit for this field is seconds. See This setting corresponds to the member [rotationSmoothing](https://arongranberg.com/astar/docs/followerentity.html#rotationSmoothing) Slowdown Time Time for the agent to slow down to a complete stop when it approaches the destination point, in seconds. One can calculate the deceleration like: [speed](https://arongranberg.com/astar/docs/pidmovement.html#speed) /[slowdownTime](https://arongranberg.com/astar/docs/pidmovement.html#slowdownTime) (with units m/s^2). See This setting corresponds to the member [movementSettings.follower.slowdownTime](https://arongranberg.com/astar/docs/pidmovement.html#slowdownTime) Stop Distance How far away from the destination should the agent aim to stop, in world units. If the agent is within this distance from the destination point it will be considered to have reached the destination. Even if you want the agent to stop precisely at a given point, it is recommended to keep this slightly above zero. If it is exactly zero, the agent may have a hard time deciding that it has actually reached the end of the path, due to floating point errors and such. Note This will not be multiplied the agent's scale. See This setting corresponds to the member [movementSettings.stopDistance](https://arongranberg.com/astar/docs/movementsettings.html#stopDistance) Lead In Radius When Approaching Destination How wide of a turn to make when approaching a destination for which a desired facing direction has been set. The following video shows three agents, one with no facing direction set, and then two agents with varying values of the lead in radius. Your browser does not support the video tag. Setting this to zero will make the agent move directly to the end of the path and rotate on the spot to face the desired facing direction, once it is there. When approaching a destination for which no desired facing direction has been set, this field has no effect. Warning Setting this to a too small (but non-zero) value may look bad if the agent cannot rotate fast enough to stay on the arc. This will be multiplied by the agent's scale to get the actual radius. See This setting corresponds to the member [movementSettings.follower.leadInRadiusWhenApproachingDestination](https://arongranberg.com/astar/docs/pidmovement.html#leadInRadiusWhenApproachingDestination) Desired Wall Distance How big of a distance to try to keep from obstacles. Typically around 1 or 2 times the agent radius is a good value for this. Try to avoid making it so large that there might not be enough space for the agent to keep this amount of distance from obstacles. It may start to move less optimally if it is not possible to keep this distance. This works well in open spaces, but if your game consists of a lot of tight corridors, a low, or zero value may be better. This will be multiplied by the agent's scale to get the actual distance. See This setting corresponds to the member [movementSettings.follower.desiredWallDistance](https://arongranberg.com/astar/docs/pidmovement.html#desiredWallDistance) Gravity Enables or disables gravity. If gravity is enabled, the agent will accelerate downwards, and use a raycast to check if it should stop falling. This has no effect if the agent's [orientation](https://arongranberg.com/astar/docs/followerentity.html#orientation) is set to YAxisForward (2D mode). Gravity does not really make sense for top-down 2D games. The gravity setting is also hidden from the inspector in this mode. See [groundMask](https://arongranberg.com/astar/docs/followerentity.html#groundMask) See This setting corresponds to the member [enableGravity](https://arongranberg.com/astar/docs/followerentity.html#enableGravity) Raycast Ground Mask Determines which layers the agent will stand on. The agent will use a raycast each frame to check if it should stop falling. This layer mask should ideally not contain the agent's own layer, if the agent has a collider, as this may cause it to try to stand on top of itself. See This setting corresponds to the member [groundMask](https://arongranberg.com/astar/docs/followerentity.html#groundMask) Movement Plane Source How to calculate which direction is "up" for the agent. In almost all cases, you should use the **Graph** option. This will make the agent use the graph's natural "up" direction. However, if you are using a spherical world, or a world with some other strange shape, then you may want to use the NavmeshNormal or Raycast options. See [Spherical Worlds](https://arongranberg.com/astar/docs/spherical.html) See This setting corresponds to the member [movementPlaneSource](https://arongranberg.com/astar/docs/followerentity.html#movementPlaneSource) **Pathfinding** Traversable Graphs [Graphs](https://arongranberg.com/astar/docs/graphs2.html) that this agent can use. This field determines which graphs will be considered when searching for the start and end nodes of a path. It is useful in numerous situations, for example if you want to make one graph for small units and one graph for large units, or one graph for people and one graph for ships. This is a bitmask so if you for example want to make the agent only use graph index 3 then you can set this to: `settings.graphMask = GraphMask.FromGraphIndex(3); ` See [Bitmask Tutorial](https://arongranberg.com/astar/docs/bitmasks.html) Note that this field only stores which graph indices that are allowed. This means that if the graphs change their ordering then this mask may no longer be correct. If you know the name of the graph you can use the [Pathfinding.GraphMask.FromGraphName](https://arongranberg.com/astar/docs/graphmask/fromgraphname.html#FromGraphName) method: `GraphMask mask1 = GraphMask.FromGraphName("My Grid Graph"); GraphMask mask2 = GraphMask.FromGraphName("My Other Grid Graph"); NearestNodeConstraint nn = NearestNodeConstraint.Walkable; nn.graphMask = mask1 | mask2; // Find the node closest to somePoint which is either in 'My Grid Graph' OR in 'My Other Grid Graph' var info = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html#GetNearest) (somePoint, nn); ` See [Multiple agent types](https://arongranberg.com/astar/docs/multipleagenttypes.html) See This setting corresponds to the member [pathfindingSettings.graphMask](https://arongranberg.com/astar/docs/pathrequestsettings.html#graphMask) Tags/Cost per world unit Multiplier for the cost of moving some distance across a node with a given tag. This will be multiplied by the traversed distance in millimeters (see [Int3.Precision](https://arongranberg.com/astar/docs/int3.html#Precision) ) to get the final cost. The default value is 1, which means that the cost will be the same as the distance. If you set this to 2, the cost will be twice as high as the distance. For example, moving 1 world unit across a node with tag 0 will cost 1000 \* tagCostMultipliers\[0\] units of movement cost. If null (the default), all tags will be treated as having a multiplier of 1. Note Prefer to make tags more costly (cost multiplier >1), rather than making them cheaper than the default (cost multiplier <1). If you set any cost multiplier to less than 1, you'll also need to reduce [AstarPath.heuristicScale](https://arongranberg.com/astar/docs/astarpath.html#heuristicScale) to the lowest cost multiplier that you use in the project, otherwise the pathfinding algorithm may not find the optimal path. Alternatively you could compensate with a higher [tagEntryCosts](https://arongranberg.com/astar/docs/traversalcosts.html#tagEntryCosts) value, so that the agent can never move to the target with a lower cost than the default. See [https://en.wikipedia.org/wiki/Admissible\_heuristic](https://en.wikipedia.org/wiki/Admissible_heuristic) . This array must be of length 32. In the inspector, this value is displayed as "Cost per world unit", and is shown as multiplied by 1000 ( [Int3.Precision](https://arongranberg.com/astar/docs/int3.html#Precision) ), to make it the cost per world unit. While in code, it is a multiplier of the default cost. ![](https://arongranberg.com/astar/docs/images/tagpopup@2x.png) `var traversalCosts = new TraversalCosts(); // Make tags 1 and 4 have a higher penalty var [tagCostMultipliers](https://arongranberg.com/astar/docs/traversalcosts.html#tagCostMultipliers) = new float[32]; [tagCostMultipliers](https://arongranberg.com/astar/docs/traversalcosts.html#tagCostMultipliers) [1] = 2.5f; [tagCostMultipliers](https://arongranberg.com/astar/docs/traversalcosts.html#tagCostMultipliers) [4] = 5.0f; traversalCosts.tagCostMultipliers = [tagCostMultipliers](https://arongranberg.com/astar/docs/traversalcosts.html#tagCostMultipliers) ; var path = ABPath.Construct(Vector3.zero, Vector3.one); path.traversalCosts = traversalCosts; ` See [TraversalCosts.GetTraversalCostMultiplier](https://arongranberg.com/astar/docs/traversalcosts/gettraversalcostmultiplier.html#GetTraversalCostMultiplier) [TraversalCosts.tagEntryCosts](https://arongranberg.com/astar/docs/traversalcosts.html#tagEntryCosts) [Seeker.tagCostMultipliers](https://arongranberg.com/astar/docs/seeker.html#tagCostMultipliers) [PathRequestSettings.tagCostMultipliers](https://arongranberg.com/astar/docs/pathrequestsettings.html#tagCostMultipliers) See This setting corresponds to the member [pathfindingSettings.tagCostMultipliers](https://arongranberg.com/astar/docs/pathrequestsettings.html#tagCostMultipliers) Tags/Traversable The tags which this agent can traverse. This is a bitmask. Each bit indicates that the agent can traverse nodes with the corresponding tag. If a bit is not set, the agent will treat it as if it is not traversable. The default value is -1, which sets all bits, and indicates that the agent can traverse all tags. ![](https://arongranberg.com/astar/docs/images/tagpopup@2x.png) See [Bitmask Tutorial](https://arongranberg.com/astar/docs/bitmasks.html) [Working with tags](https://arongranberg.com/astar/docs/tags.html) See This setting corresponds to the member [pathfindingSettings.traversableTags](https://arongranberg.com/astar/docs/pathrequestsettings.html#traversableTags) Recalculate Paths Automatically Policy to use when recalculating paths. See [Pathfinding.AutoRepathPolicy.Mode](https://arongranberg.com/astar/docs/autorepathpolicy.html#Mode) for more details. See This setting corresponds to the member [autoRepath.mode](https://arongranberg.com/astar/docs/autorepathpolicy2.html#mode) Period Number of seconds between each automatic path recalculation for Mode.EveryNSeconds, and the maximum interval for Mode.Dynamic. See This setting corresponds to the member [autoRepath.period](https://arongranberg.com/astar/docs/autorepathpolicy2.html#period) **Local Avoidance** Enable Local Avoidance True if local avoidance is enabled for this agent. Enabling this will automatically add a [Pathfinding.ECS.RVO.RVOAgent](https://arongranberg.com/astar/docs/rvoagent.html) component to the entity. See [Local Avoidance](https://arongranberg.com/astar/docs/localavoidance.html) Note When the agent is used in a subscene, this field has no effect at runtime. Instead, add or remove the [Pathfinding.ECS.RVO.RVOAgent](https://arongranberg.com/astar/docs/rvoagent.html) component. See [rvoSettings](https://arongranberg.com/astar/docs/followerentity.html#rvoSettings) See This setting corresponds to the member [enableLocalAvoidance](https://arongranberg.com/astar/docs/followerentity.html#enableLocalAvoidance) Agent Time Horizon How far into the future to look for collisions with other agents (in seconds) See This setting corresponds to the member [rvoSettings.agentTimeHorizon](https://arongranberg.com/astar/docs/rvoagent.html#agentTimeHorizon) Obstacle Time Horizon How far into the future to look for collisions with obstacles (in seconds) See This setting corresponds to the member [rvoSettings.obstacleTimeHorizon](https://arongranberg.com/astar/docs/rvoagent.html#obstacleTimeHorizon) Max Neighbours Max number of other agents to take into account. A smaller value can reduce CPU load, a higher value can lead to better local avoidance quality. See This setting corresponds to the member [rvoSettings.maxNeighbours](https://arongranberg.com/astar/docs/rvoagent.html#maxNeighbours) Layer Specifies the avoidance layer for this agent. The [collidesWith](https://arongranberg.com/astar/docs/rvoagent.html#collidesWith) mask on other agents will determine if they will avoid this agent. See This setting corresponds to the member [rvoSettings.layer](https://arongranberg.com/astar/docs/rvoagent.html#layer) Collides With Layer mask specifying which layers this agent will avoid. You can set it as CollidesWith = RVOLayer.DefaultAgent | RVOLayer.Layer3 | RVOLayer.Layer6 ... This can be very useful in games which have multiple teams of some sort. For example you usually want the agents in one team to avoid each other, but you do not want them to avoid the enemies. This field only affects which other agents that this agent will avoid, it does not affect how other agents react to this agent. See [Bitmask Tutorial](https://arongranberg.com/astar/docs/bitmasks.html) [http://en.wikipedia.org/wiki/Mask\_(computing)](http://en.wikipedia.org/wiki/Mask_(computing)) See This setting corresponds to the member [rvoSettings.collidesWith](https://arongranberg.com/astar/docs/rvoagent.html#collidesWith) Priority How strongly other agents will avoid this agent. Usually a value between 0 and 1. Agents with similar priorities will avoid each other with an equal strength. If an agent sees another agent with a higher priority than itself it will avoid that agent more strongly. In the extreme case (e.g this agent has a priority of 0 and the other agent has a priority of 1) it will treat the other agent as being a moving obstacle. Similarly if an agent sees another agent with a lower priority than itself it will avoid that agent less. In general the avoidance strength for this agent is: `if this.priority > 0 or other.priority > 0: avoidanceStrength = other.priority / (this.priority + other.priority); else: avoidanceStrength = 0.5 ` See This setting corresponds to the member [rvoSettings.priority](https://arongranberg.com/astar/docs/rvoagent.html#priority) Locked A locked unit cannot move. Other units will still avoid it but avoidance quality is not the best. See This setting corresponds to the member [rvoSettings.locked](https://arongranberg.com/astar/docs/rvoagent.html#locked) **Debug** Movement Debug Rendering Enables or disables debug drawing for this agent. This is a bitmask with multiple flags so that you can choose exactly what you want to debug. See [PIDMovement.DebugFlags](https://arongranberg.com/astar/docs/pidmovement.html#DebugFlags) [Bitmask Tutorial](https://arongranberg.com/astar/docs/bitmasks.html) See This setting corresponds to the member [debugFlags](https://arongranberg.com/astar/docs/followerentity.html#debugFlags) Local Avoidance Debug Rendering Enables drawing debug information in the scene view. See This setting corresponds to the member [rvoSettings.debug](https://arongranberg.com/astar/docs/rvoagent.html#debug) **Debug Info Foldout** Reached Destination True if the ai has reached the [destination](https://arongranberg.com/astar/docs/followerentity.html#destination) . The agent considers the destination reached when it is within [stopDistance](https://arongranberg.com/astar/docs/followerentity.html#stopDistance) world units from the [destination](https://arongranberg.com/astar/docs/followerentity.html#destination) . Additionally, the destination must not be above the agent's head, and it must not be more than half the agent's height below its feet. If a facing direction was specified when setting the destination, this will only return true once the agent is approximately facing the correct orientation. This value will be updated immediately when the [destination](https://arongranberg.com/astar/docs/followerentity.html#destination) is changed. `IEnumerator [Start](https://arongranberg.com/astar/docs/followerentity/start.html#Start) () { ai.destination = somePoint; // Start to search for a path to the destination immediately ai.SearchPath(); // Wait until the agent has reached the destination while (!ai.reachedDestination) { yield return null; } // The agent has reached the destination now } ` Note The agent may not be able to reach the destination. In that case this property may never become true. Sometimes [reachedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedEndOfPath) is more appropriate. See [stopDistance](https://arongranberg.com/astar/docs/followerentity.html#stopDistance) [remainingDistance](https://arongranberg.com/astar/docs/followerentity.html#remainingDistance) [reachedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedEndOfPath) [reachedCrowdedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedCrowdedEndOfPath) See This setting corresponds to the member [reachedDestination](https://arongranberg.com/astar/docs/followerentity.html#reachedDestination) Reached End Of Path True if the agent has reached the end of the current path. The agent considers the end of the path reached when it is within [stopDistance](https://arongranberg.com/astar/docs/followerentity.html#stopDistance) world units from the end of the path. Additionally, the end of the path must not be above the agent's head, and it must not be more than half the agent's height below its feet. If a facing direction was specified when setting the destination, this will only return true once the agent is approximately facing the correct orientation. This value will be updated immediately when the [destination](https://arongranberg.com/astar/docs/followerentity.html#destination) is changed. Note Reaching the end of the path does not imply that it has reached its desired destination, as the destination may not even be possible to reach. Sometimes [reachedDestination](https://arongranberg.com/astar/docs/followerentity.html#reachedDestination) is more appropriate. See [remainingDistance](https://arongranberg.com/astar/docs/followerentity.html#remainingDistance) [reachedDestination](https://arongranberg.com/astar/docs/followerentity.html#reachedDestination) [reachedCrowdedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedCrowdedEndOfPath) See This setting corresponds to the member [reachedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedEndOfPath) Reached (maybe crowded) End Of Path Like [reachedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedEndOfPath) , but will also return true if the end of the path is crowded, and this agent has stopped because it cannot get closer. This is only relevant if the agent is using local avoidance. Otherwise, this will be identical to [reachedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedEndOfPath) . If the agent has a stale path (e.g. because the destination changed significantly, or a graph update happened near the agent), false will be returned until the path has been recalculated (typically in the next one or two frames). You can see a visualization of this state by enabling "Reached State" in the [Local Avoidance Debug Rendering](https://arongranberg.com/astar/docs/rvoagent.html#debug) field. Note The agent may not be completely stopped when this is true. It knows that there are other agents in the way, but it might still be able to slowly make some progress. Check the [velocity](https://arongranberg.com/astar/docs/followerentity.html#velocity) property to see if the agent is actually moving. In the video below, the agents will get a red ring around them when this property is true. Your browser does not support the video tag. See [Local Avoidance](https://arongranberg.com/astar/docs/localavoidance.html) . [ReachedEndOfPath](https://arongranberg.com/astar/docs/rvo2.html#ReachedEndOfPath) See This setting corresponds to the member [reachedCrowdedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedCrowdedEndOfPath) Has Path True if this agent currently has a valid path that it follows. This is true if the agent has a path and the path is not stale. A path may become stale if the graph is updated close to the agent and it hasn't had time to recalculate its path yet. See This setting corresponds to the member [hasPath](https://arongranberg.com/astar/docs/followerentity.html#hasPath) Path Pending True if a path is currently being calculated. See This setting corresponds to the member [pathPending](https://arongranberg.com/astar/docs/followerentity.html#pathPending) Destination Position in the world that this agent should move to. If no destination has been set yet, then (+infinity, +infinity, +infinity) will be returned. Setting this property will immediately try to repair the path if the agent already has a path. This will also immediately update properties like [reachedDestination](https://arongranberg.com/astar/docs/followerentity.html#reachedDestination) , [reachedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedEndOfPath) and [remainingDistance](https://arongranberg.com/astar/docs/followerentity.html#remainingDistance) . The agent may do a full path recalculation if the local repair was not sufficient, but this will at earliest happen in the next simulation step. `IEnumerator [Start](https://arongranberg.com/astar/docs/followerentity/start.html#Start) () { ai.destination = somePoint; // Wait until the AI has reached the destination while (!ai.reachedEndOfPath) { yield return null; } // The agent has reached the destination now } ` See [SetDestination](https://arongranberg.com/astar/docs/followerentity/setdestination.html#SetDestination) , which also allows you to set a facing direction for the agent. See This setting corresponds to the member [destination](https://arongranberg.com/astar/docs/followerentity.html#destination) Remaining Distance Approximate remaining distance along the current path to the end of the path. This is an approximation for performance reasons, and the agent also does not know the true distance at all times. It tends to be a bit lower than the true distance. It will get more accurate as the agent gets closer to the end of the path. If you want a more accurate distance (at a higher performance cost), you can call GetRemainingPath and sum the length of it. Note This is the distance to the end of the path, which may or may not be the same as the destination. If the character cannot reach the destination it will try to move as close as possible to it. This value will update immediately if the [destination](https://arongranberg.com/astar/docs/followerentity.html#destination) property is changed, or if the agent is moved using the [position](https://arongranberg.com/astar/docs/followerentity.html#position) property or the [Teleport](https://arongranberg.com/astar/docs/followerentity/teleport.html#Teleport) method. If the agent has no path, or if the current path is stale (e.g. if the graph has been updated close to the agent, and it hasn't had time to recalculate its path), this will return positive infinity. See [reachedDestination](https://arongranberg.com/astar/docs/followerentity.html#reachedDestination) [reachedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedEndOfPath) [pathPending](https://arongranberg.com/astar/docs/followerentity.html#pathPending) See This setting corresponds to the member [remainingDistance](https://arongranberg.com/astar/docs/followerentity.html#remainingDistance) Speed Actual velocity that the agent is moving with, including gravity. In world units per second. This is useful for, for example, selecting which animations to play, and at what speeds. Note Any value set here will be overriden during the next simulation step. Nevertheless, it can be useful to set this value if you have disabled the agent's movement logic using e.g. [simulateMovement](https://arongranberg.com/astar/docs/followerentity.html#simulateMovement) . This value is only an output statistic. It is not used to control the agent's movement. See [desiredVelocity](https://arongranberg.com/astar/docs/followerentity.html#desiredVelocity) See This setting corresponds to the member [velocity](https://arongranberg.com/astar/docs/followerentity.html#velocity) ECS --- This script uses Unity's ECS (Entity Component System) to move the agent. This means it is highly-performant and is able to utilize multiple threads. Internally, an entity is created for the agent with the following components: * LocalTransform * [MovementState](https://arongranberg.com/astar/docs/movementstate.html) * [MovementSettings](https://arongranberg.com/astar/docs/movementsettings.html) * [MovementControl](https://arongranberg.com/astar/docs/movementcontrol.html) * [ManagedSettings](https://arongranberg.com/astar/docs/managedsettings.html) * [SearchState](https://arongranberg.com/astar/docs/searchstate.html) * [MovementStatistics](https://arongranberg.com/astar/docs/movementstatistics.html) * [AgentCylinderShape](https://arongranberg.com/astar/docs/agentcylindershape.html) * [ResolvedMovement](https://arongranberg.com/astar/docs/resolvedmovement.html) * [GravityState](https://arongranberg.com/astar/docs/gravitystate.html) * [DestinationPoint](https://arongranberg.com/astar/docs/destinationpoint.html) * [AgentMovementPlane](https://arongranberg.com/astar/docs/agentmovementplane.html) * [ManagedState](https://arongranberg.com/astar/docs/managedstate.html) - actually created during the first frame by [InitManagedStateSystem](https://arongranberg.com/astar/docs/initmanagedstatesystem.html) * [ECS.RVO.RVOAgent](https://arongranberg.com/astar/docs/rvoagent.html) (if local avoidance is enabled) * [SimulateMovement](https://arongranberg.com/astar/docs/simulatemovement.html) - tag component (if [simulateMovement](https://arongranberg.com/astar/docs/followerentity.html#simulateMovement) is enabled) * [SimulateMovementRepair](https://arongranberg.com/astar/docs/simulatemovementrepair.html) - tag component * [SimulateMovementControl](https://arongranberg.com/astar/docs/simulatemovementcontrol.html) - tag component * [SimulateMovementFinalize](https://arongranberg.com/astar/docs/simulatemovementfinalize.html) - tag component * [SyncPositionWithTransform](https://arongranberg.com/astar/docs/syncpositionwithtransform.html) - tag component (if [updatePosition](https://arongranberg.com/astar/docs/followerentity.html#updatePosition) is enabled) * [SyncRotationWithTransform](https://arongranberg.com/astar/docs/syncrotationwithtransform.html) - tag component (if [updateRotation](https://arongranberg.com/astar/docs/followerentity.html#updateRotation) is enabled) * [OrientationYAxisForward](https://arongranberg.com/astar/docs/orientationyaxisforward.html) - tag component (if [orientation](https://arongranberg.com/astar/docs/followerentity.html#orientation) is [OrientationMode](https://arongranberg.com/astar/docs/pathfinding.html#OrientationMode) .YAxisForward) * [ReadyToTraverseOffMeshLink](https://arongranberg.com/astar/docs/readytotraverseoffmeshlink.html) - tag component, always exists, but enabled if the agent is about to start traversing an off-mesh link * [AgentShouldRecalculatePath](https://arongranberg.com/astar/docs/agentshouldrecalculatepath.html) - tag component, always exists, but enabled internally if the agent should recalculate its path. * [AgentMovementPlaneSource](https://arongranberg.com/astar/docs/agentmovementplanesource.html) - shared component * [PhysicsSceneRef](https://arongranberg.com/astar/docs/physicssceneref.html) - shared component Then this script barely does anything by itself. It is a thin wrapper around the ECS components. Instead, actual movement calculations are carried out by the following systems: * [SyncTransformsToEntitiesSystem](https://arongranberg.com/astar/docs/synctransformstoentitiessystem.html) - Updates the entity's transform from the GameObject. * [MovementPlaneFromGraphSystem](https://arongranberg.com/astar/docs/movementplanefromgraphsystem.html) - Updates the agent's movement plane. * [SyncDestinationTransformSystem](https://arongranberg.com/astar/docs/syncdestinationtransformsystem.html) - Updates the destination point if the destination transform moves. * [SchedulePathSearchSystem](https://arongranberg.com/astar/docs/schedulepathsearchsystem.html) - Schedules path calculations when necessary. * [TraverseOffMeshLinkSystem](https://arongranberg.com/astar/docs/traverseoffmeshlinksystem.html) - Handles off-mesh link traversal. * [RepairPathSystem](https://arongranberg.com/astar/docs/repairpathsystem.html) - Keeps the agent's path up to date. * [FollowerControlSystem](https://arongranberg.com/astar/docs/followercontrolsystem.html) - Calculates how the agent wants to move. * [RVOSystem](https://arongranberg.com/astar/docs/rvosystem.html) - Local avoidance calculations. * [FallbackResolveMovementSystem](https://arongranberg.com/astar/docs/fallbackresolvemovementsystem.html) - NOOP system for if local avoidance is disabled. * [AIMoveSystem](https://arongranberg.com/astar/docs/aimovesystem.html) - Performs the actual movement. In fact, as long as you create the appropriate ECS components, you do not even need this script. You can use the systems directly. This component can be baked or used as a normal monobehaviour, depending on if it is in a subscene or not. When used outside a subscene, this script will continue to work even in standalone games. It is designed to be easily used without having to care too much about the underlying ECS implementation. See [Using high performance ECS](https://arongranberg.com/astar/docs/ecs.html) Usage in ECS subscenes ---------------------- This component can be used in subscenes and it will automatically be baked into a high-performance ECS entity. Using a subscene will give you the highest performance, as you'll avoid the performance and memory overhead of keeping a GameObject and this component around. However, it makes it a bit harder to use, since you cannot use the MonoBehaviour API. I recommend using subscenes if you have a lot of agents (>1000) and you need the best performance possible. However, in the prototyping stage, using a MonoBehaviour is often far easier, so I recommend using this component as a MonoBehaviour in the beginning. Even when not using a subscene, [ECS](https://arongranberg.com/astar/docs/ecs2.html) will be used behind the scenes, so you'll still get most of the performance benefits of using ECS. If you have the [AIDestinationSetter](https://arongranberg.com/astar/docs/aidestinationsetter.html) component on the same GameObject, it will be automatically converted to a [DestinationEntity](https://arongranberg.com/astar/docs/destinationentity.html) component in the subscene. Note When used in a subscene, you cannot use any properties, fields, or methods on this component in play mode, since this component is baked away and won't even exist at runtime. Instead, you can either use [ECS](https://arongranberg.com/astar/docs/ecs2.html) components directly, or you can use the wrapper [FollowerEntityProxy](https://arongranberg.com/astar/docs/followerentityproxy.html) which acts almost identically to this component, but uses an entity as the source instead. `var follower = new FollowerEntityProxy([world](https://arongranberg.com/astar/docs/followerentity.html#world) , [entity](https://arongranberg.com/astar/docs/followerentity.html#entity) ); follower.maxSpeed = 5; follower.destination = new Vector3(1, 2, 3); if (follower.currentNode.Tag == 1) { Debug.Log("The agent is right now traversing a node with tag 1"); } ` See [FollowerEntityProxy](https://arongranberg.com/astar/docs/followerentityproxy.html) [https://docs.unity3d.com/Packages/com.unity.entities@1.4/manual/conversion-subscenes.html](https://docs.unity3d.com/Packages/com.unity.entities@1.4/manual/conversion-subscenes.html) [Using high performance ECS](https://arongranberg.com/astar/docs/ecs.html) Differences compared to AIPath and RichAI ----------------------------------------- This movement script has been written to remedy several inconsistency issues with other movement scrips, to provide very smooth movement, and "just work" for most games. For example, it goes to great lengths to ensure that the [reachedDestination](https://arongranberg.com/astar/docs/followerentity.html#reachedDestination) and [reachedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedEndOfPath) properties are as accurate as possible at all times, even before it has had time to recalculate its path to account for a new [destination](https://arongranberg.com/astar/docs/followerentity.html#destination) . It does this by locally repairing the path (if possible) immediately when the destination changes instead of waiting for a path recalculation. This also has a bonus effect that the agent can often work just fine with moving targets, even if it almost never recalculates its path (though the repaired path may not always be optimal), and it leads to very responsive movement. In contrast to other movement scripts, this movement script does not use path modifiers at all. Instead, this script contains its own internal [FunnelModifier](https://arongranberg.com/astar/docs/funnelmodifier.html) which it uses to simplify the path before it follows it. In also doesn't use a separate [RVOController](https://arongranberg.com/astar/docs/rvocontroller.html) component for local avoidance, but instead it stores local avoidance settings in [rvoSettings](https://arongranberg.com/astar/docs/followerentity.html#rvoSettings) . Best practices for good performance ----------------------------------- Here are some tips for how to improve performance when using this script. As always, make sure to profile your game first, to see what is actually causing performance problems. **Disable unused features** This script has some optional parts. Local avoidance, for example. Local avoidance is used to make sure that agents do not overlap with each other. However, if you do not need it, you can disable it to improve performance. **Don't change the destination unnecessarily** Repairing the path each frame can be a significant part of the movement calculation time. The [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) will perform better if the [destination](https://arongranberg.com/astar/docs/followerentity.html#destination) is static, or moves seldom. For example, updating the destination every 10 frames will be faster than updating it every frame, but to the player, both will look basically the same. Note Repairing the path is different from recalculating it from scratch. The agent will recalculate the path from scratch relatively seldom, but it will repair it every frame, if necessary, to account for small changes in the agent's position and destination. **Disable debug rendering** Debug rendering has some performance costs in the Unity Editor. Disable all [debugFlags](https://arongranberg.com/astar/docs/followerentity.html#debugFlags) and [rvoSettings.debug](https://arongranberg.com/astar/docs/rvoagent.html#debug) to improve performance. However, in standalone builds, these are automatically disabled and have no cost. **Be aware of property access costs** Using ECS components has some downsides. Accessing properties on this script is significantly slower compared to accessing properties on other movement scripts. This is because on each property access, the script has to make sure no jobs are running concurrently, which is a relatively expensive operation. **Slow** is a relative term, though. This only starts to matter if you have lots of agents, maybe a hundred or so. So don't be scared of using it. But if you have a lot of agents, it is recommended to not access properties on this script more often than required. Avoid setting fields to the same value over and over again every frame, for example. If you have a moving target, try to use the [AIDestinationSetter](https://arongranberg.com/astar/docs/aidestinationsetter.html) component instead of setting the [destination](https://arongranberg.com/astar/docs/followerentity.html#destination) property manually, as that is faster than setting the [destination](https://arongranberg.com/astar/docs/followerentity.html#destination) property every frame. You can instead write custom ECS systems to access the properties on the ECS components directly. This is much faster. For example, if you want to make the agent follow a particular entity, you could create a new DestinationEntity component which just holds an entity reference, and then create a system that every frame copies that entity's position to the [DestinationPoint.destination](https://arongranberg.com/astar/docs/destinationpoint.html#destination) field (a component that this entity will always have). **Use subscenes** If you have a lot of agents, moving the GameObject into a subscene will give you the best performance. This is because subscenes are baked into ECS entities, which have a much lower memory overhead than GameObjects, and avoids other GameObject overhead. See [Using high performance ECS](https://arongranberg.com/astar/docs/ecs.html) [Usage in ECS subscenes](https://arongranberg.com/astar/docs/followerentity.html#followerentity-subscenes) Time scaling ------------ This component will automatically run multiple simulation steps per frame if the time scale is greater than 1. This is done to ensure that the movement remains stable even at high time scales. One case when this happens is when fast-forwarding games, which is common in some types of city builders and other types of simulation games. This will impact performance at high time scales, but it is necessary to ensure that the movement remains stable. Public Methods -------------- [DrawGizmos](https://arongranberg.com/astar/docs/followerentity/drawgizmos.html#DrawGizmos) () [GetRemainingPath](https://arongranberg.com/astar/docs/followerentity/getremainingpath.html) (buffer, \[partsBuffer\], stale) Fills **buffer** with the remaining path. [Move](https://arongranberg.com/astar/docs/followerentity/move.html#Move) (deltaPosition) Move the agent. [SearchPath](https://arongranberg.com/astar/docs/followerentity/searchpath.html#SearchPath) () Recalculate the current path. [SetDestination](https://arongranberg.com/astar/docs/followerentity/setdestination.html#SetDestination) (destination, facingDirection=…) Set the position in the world that this agent should move to. [SetPath](https://arongranberg.com/astar/docs/followerentity/setpath.html#SetPath) (path, updateDestinationFromPath=true) Make the AI follow the specified path. [Teleport](https://arongranberg.com/astar/docs/followerentity/teleport.html#Teleport) (newPosition, clearPath=true) Instantly move the agent to a new position. Public Static Methods --------------------- [CreateEntity](https://arongranberg.com/astar/docs/followerentity/createentity.html#CreateEntity) (position, rotation, scale, shape, movement, autoRepath, managedState, orientation, movementPlaneSource, updatePosition, updateRotation, enableGravity, enableLocalAvoidance, rvoSettings, managedSettings, physicsScene) Creates an entity with the given data. Public Variables ---------------- autoRepath Policy for when the agent recalculates its path. Public ##### [ECS.AutoRepathPolicy](https://arongranberg.com/astar/docs/autorepathpolicy2.html) autoRepath Policy for when the agent recalculates its path. See [ECS.AutoRepathPolicy](https://arongranberg.com/astar/docs/autorepathpolicy2.html) canMove Enables or disables movement completely. Public ##### bool canMove Enables or disables movement completely. If you want the agent to stand still, but still react to local avoidance and use gravity: use [isStopped](https://arongranberg.com/astar/docs/iastarai.html#isStopped) instead. This is also useful if you want to have full control over when the movement calculations run. Take a look at [MovementUpdate](https://arongranberg.com/astar/docs/iastarai/movementupdate.html#MovementUpdate) See [canSearch](https://arongranberg.com/astar/docs/iastarai.html#canSearch) [isStopped](https://arongranberg.com/astar/docs/iastarai.html#isStopped) Deprecated Renamed to [simulateMovement](https://arongranberg.com/astar/docs/iastarai.html#simulateMovement) to avoid confusion with the [isStopped](https://arongranberg.com/astar/docs/iastarai.html#isStopped) property. currentNode Node which the agent is currently traversing. Public ##### [GraphNode](https://arongranberg.com/astar/docs/graphnode.html) currentNode Node which the agent is currently traversing. You can, for example, use this to make the agent use a different animation when traversing nodes with a specific tag. Note Will be null if the agent does not have a path, or if the node under the agent has just been destroyed by a graph update. When traversing an off-mesh link, this will return the final non-link node in the path before the agent started traversing the link. debugFlags Enables or disables debug drawing for this agent. Public ##### [PIDMovement.DebugFlags](https://arongranberg.com/astar/docs/pidmovement.html#DebugFlags) debugFlags Enables or disables debug drawing for this agent. This is a bitmask with multiple flags so that you can choose exactly what you want to debug. See [PIDMovement.DebugFlags](https://arongranberg.com/astar/docs/pidmovement.html#DebugFlags) [Bitmask Tutorial](https://arongranberg.com/astar/docs/bitmasks.html) desiredVelocity Velocity that this agent wants to move with. Public ##### [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) desiredVelocity Velocity that this agent wants to move with. Includes gravity and local avoidance if applicable. In world units per second. See [velocity](https://arongranberg.com/astar/docs/followerentity.html#velocity) Note The [Pathfinding.AILerp](https://arongranberg.com/astar/docs/ailerp.html) movement script doesn't use local avoidance or gravity so this property will always be identical to [velocity](https://arongranberg.com/astar/docs/followerentity.html#velocity) on that component. desiredVelocityWithoutLocalAvoidance Velocity that this agent wants to move with before taking local avoidance into account. Public ##### [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) desiredVelocityWithoutLocalAvoidance Velocity that this agent wants to move with before taking local avoidance into account. Includes gravity. In world units per second. Setting this property will set the current velocity that the agent is trying to move with, including gravity. This can be useful if you want to make the agent come to a complete stop in a single frame or if you want to modify the velocity in some way. `// Set the velocity to zero, but keep the current gravity var newVelocity = new Vector3(0, ai.desiredVelocityWithoutLocalAvoidance.y, 0); ai.desiredVelocityWithoutLocalAvoidance = newVelocity; ` Note The [Pathfinding.AILerp](https://arongranberg.com/astar/docs/ailerp.html) movement script doesn't use local avoidance so this property will always be identical to [velocity](https://arongranberg.com/astar/docs/followerentity.html#velocity) on that component. Warning Trying to set this property on an [AILerp](https://arongranberg.com/astar/docs/ailerp.html) component will throw an exception since its velocity cannot meaningfully be changed abitrarily. If you are not using local avoidance then this property will in almost all cases be identical to [desiredVelocity](https://arongranberg.com/astar/docs/followerentity.html#desiredVelocity) plus some noise due to floating point math. See [velocity](https://arongranberg.com/astar/docs/followerentity.html#velocity) [desiredVelocity](https://arongranberg.com/astar/docs/followerentity.html#desiredVelocity) [Move](https://arongranberg.com/astar/docs/followerentity/move.html#Move) [MovementUpdate](https://arongranberg.com/astar/docs/followerentity/movementupdate.html#MovementUpdate) destination Position in the world that this agent should move to. Public ##### [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) destination Position in the world that this agent should move to. If no destination has been set yet, then (+infinity, +infinity, +infinity) will be returned. Setting this property will immediately try to repair the path if the agent already has a path. This will also immediately update properties like [reachedDestination](https://arongranberg.com/astar/docs/followerentity.html#reachedDestination) , [reachedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedEndOfPath) and [remainingDistance](https://arongranberg.com/astar/docs/followerentity.html#remainingDistance) . The agent may do a full path recalculation if the local repair was not sufficient, but this will at earliest happen in the next simulation step. `IEnumerator [Start](https://arongranberg.com/astar/docs/followerentity/start.html#Start) () { ai.destination = somePoint; // Wait until the AI has reached the destination while (!ai.reachedEndOfPath) { yield return null; } // The agent has reached the destination now } ` See [SetDestination](https://arongranberg.com/astar/docs/followerentity/setdestination.html#SetDestination) , which also allows you to set a facing direction for the agent. destinationFacingDirection Direction the agent will try to face when it reaches the destination. Public ##### [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) destinationFacingDirection Direction the agent will try to face when it reaches the destination. If this is zero, the agent will not try to face any particular direction. The following video shows three agents, one with no facing direction set, and then two agents with varying values of the [lead in radius](https://arongranberg.com/astar/docs/pidmovement.html#leadInRadiusWhenApproachingDestination) . Your browser does not support the video tag. To set this, use [SetDestination](https://arongranberg.com/astar/docs/followerentity/setdestination.html#SetDestination) . See [MovementSettings.follower.leadInRadiusWhenApproachingDestination](https://arongranberg.com/astar/docs/pidmovement.html#leadInRadiusWhenApproachingDestination) [SetDestination](https://arongranberg.com/astar/docs/followerentity/setdestination.html#SetDestination) enableGravity Enables or disables gravity. Public ##### bool? enableGravity Enables or disables gravity. If gravity is enabled, the agent will accelerate downwards, and use a raycast to check if it should stop falling. This has no effect if the agent's [orientation](https://arongranberg.com/astar/docs/followerentity.html#orientation) is set to YAxisForward (2D mode). Gravity does not really make sense for top-down 2D games. The gravity setting is also hidden from the inspector in this mode. See [groundMask](https://arongranberg.com/astar/docs/followerentity.html#groundMask) enableLocalAvoidance True if local avoidance is enabled for this agent. Public ##### bool? enableLocalAvoidance True if local avoidance is enabled for this agent. Enabling this will automatically add a [Pathfinding.ECS.RVO.RVOAgent](https://arongranberg.com/astar/docs/rvoagent.html) component to the entity. See [Local Avoidance](https://arongranberg.com/astar/docs/localavoidance.html) Note When the agent is used in a subscene, this field has no effect at runtime. Instead, add or remove the [Pathfinding.ECS.RVO.RVOAgent](https://arongranberg.com/astar/docs/rvoagent.html) component. See [rvoSettings](https://arongranberg.com/astar/docs/followerentity.html#rvoSettings) endOfPath End point of path the agent is currently following. Public ##### [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) endOfPath End point of path the agent is currently following. If the agent has no path (or if it's not calculated yet), this will return the [destination](https://arongranberg.com/astar/docs/followerentity.html#destination) instead. If the agent has no destination it will return the agent's current position. The end of the path is usually identical or very close to the [destination](https://arongranberg.com/astar/docs/followerentity.html#destination) , but it may differ if the path for example was blocked by a wall, so that the agent couldn't get any closer. See [GetRemainingPath](https://arongranberg.com/astar/docs/followerentity/getremainingpath.html#GetRemainingPath) entity Entity which this movement script represents. Public ##### Entity entity Entity which this movement script represents. This is the same as **proxy.entity**, but is provided for convenience. It is only valid when this script is enabled. See FollowerEntityProxy entityExists True if this component's entity exists. Public ##### bool entityExists True if this component's entity exists. This is typically true if the component is active and enabled and the game is running. See [entity](https://arongranberg.com/astar/docs/followerentity.html#entity) groundMask Determines which layers the agent will stand on. Public ##### [LayerMask](https://docs.unity3d.com/ScriptReference/LayerMask.html) groundMask Determines which layers the agent will stand on. The agent will use a raycast each frame to check if it should stop falling. This layer mask should ideally not contain the agent's own layer, if the agent has a collider, as this may cause it to try to stand on top of itself. hasPath True if this agent currently has a valid path that it follows. Public ##### bool hasPath True if this agent currently has a valid path that it follows. This is true if the agent has a path and the path is not stale. A path may become stale if the graph is updated close to the agent and it hasn't had time to recalculate its path yet. height Height of the agent in world units. Public ##### float height Height of the agent in world units. This is visualized in the scene view as a yellow cylinder around the character. This value is used for various heuristics, and for visualization purposes. For example, the destination is only considered reached if the destination is not above the agent's head, and it's not more than half the agent's height below its feet. If local lavoidance is enabled, this is also used to filter out collisions with agents and obstacles that are too far above or below the agent. isStopped Gets or sets if the agent should stop moving. Public ##### bool? isStopped Gets or sets if the agent should stop moving. If this is set to true the agent will immediately start to slow down as quickly as it can to come to a full stop. The agent will still react to local avoidance and gravity (if applicable), but it will not try to move in any particular direction. The current path of the agent will not be cleared, so when this is set to false again the agent will continue moving along the previous path. This is a purely user-controlled parameter, so for example it is not set automatically when the agent stops moving because it has reached the target. Use [reachedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedEndOfPath) for that. If this property is set to true while the agent is traversing an off-mesh link ([RichAI](https://arongranberg.com/astar/docs/richai.html) script only), then the agent will continue traversing the link and stop once it has completed it. Note This is not the same as the [simulateMovement](https://arongranberg.com/astar/docs/followerentity.html#simulateMovement) setting which some movement scripts have. The [simulateMovement](https://arongranberg.com/astar/docs/followerentity.html#simulateMovement) setting disables movement calculations completely (which among other things makes it not be affected by local avoidance or gravity). For the [AILerp](https://arongranberg.com/astar/docs/ailerp.html) movement script which doesn't use gravity or local avoidance anyway changing this property is very similar to changing [simulateMovement](https://arongranberg.com/astar/docs/followerentity.html#simulateMovement) . The [steeringTarget](https://arongranberg.com/astar/docs/followerentity.html#steeringTarget) property will continue to indicate the point which the agent would move towards if it would not be stopped. For most movement scripts, this will make the agent slow down quickly, but not instantly stop. If you want to instantly stop the agent, you could either disable the whole component instead (but then it will not react to local avoidance, of course, and it will clear its current path), or you could set [desiredVelocityWithoutLocalAvoidance](https://arongranberg.com/astar/docs/followerentity.html#desiredVelocityWithoutLocalAvoidance) to Vector3.zero, which will stop it immediately. isTraversingOffMeshLink True if the agent is currently traversing an off-mesh link. Public ##### bool isTraversingOffMeshLink True if the agent is currently traversing an off-mesh link. See [Off-mesh links](https://arongranberg.com/astar/docs/offmeshlinks2.html) [onTraverseOffMeshLink](https://arongranberg.com/astar/docs/followerentity.html#onTraverseOffMeshLink) [offMeshLink](https://arongranberg.com/astar/docs/followerentity.html#offMeshLink) localAvoidanceTemporarilyDisabled True if the agent's local avoidance is temporarily disabled, due to traversing an off-mesh link. Public ##### bool localAvoidanceTemporarilyDisabled True if the agent's local avoidance is temporarily disabled, due to traversing an off-mesh link. When traversing an off-mesh link, the traversal code may temporarily disable local avoidance to allow the agent to traverse the link without being pushed around by other agents. See [AgentOffMeshLinkLocalAvoidanceDisabled](https://arongranberg.com/astar/docs/agentoffmeshlinklocalavoidancedisabled.html) [AgentOffMeshLinkTraversalContext.DisableLocalAvoidance](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext/disablel.html#DisableLocalAvoidance) When the agent is not traversing an off-mesh link, this will always return false. Note A false value does not imply that the agent is actually using local avoidance. See [enableLocalAvoidance](https://arongranberg.com/astar/docs/followerentity.html#enableLocalAvoidance) for that. maxRotationSpeed Maximum rotation speed in degrees per second. Public ##### float maxRotationSpeed Maximum rotation speed in degrees per second. If the agent would have to rotate faster than this, it will instead slow down to get more time to rotate. The agent may want to rotate faster than [rotationSpeed](https://arongranberg.com/astar/docs/pidmovement.html#rotationSpeed) if there's not enough space, so that it has to move in a more narrow arc. It may also want to rotate faster if it is very close to its destination and it wants to make sure it ends up on the right spot without any circling. It is recommended to keep this at a value slightly larger than [rotationSpeed](https://arongranberg.com/astar/docs/pidmovement.html#rotationSpeed) . See [rotationSpeed](https://arongranberg.com/astar/docs/pidmovement.html#rotationSpeed) maxSpeed Max speed in world units per second. Public ##### float maxSpeed Max speed in world units per second. movementOverrides Provides callbacks during various parts of the movement calculations. Public ##### [ManagedMovementOverrides](https://arongranberg.com/astar/docs/managedmovementoverrides.html) movementOverrides Provides callbacks during various parts of the movement calculations. With this property you can register callbacks that will be called during various parts of the movement calculations. These can be used to modify movement of the agent. The following example demonstrates how one can hook into one of the available phases and modify the agent's movement. In this case, the movement is modified to become wavy. Your browser does not support the video tag. `using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) ; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) .[ECS](https://arongranberg.com/astar/docs/ecs2.html) ; using Unity.Entities; using Unity.[Mathematics](https://arongranberg.com/astar/docs/mathematics.html) ; using Unity.Transforms; using UnityEngine; public class MovementModifierNoise : MonoBehaviour { public float strength = 1; public float frequency = 1; float phase; public void [Start](https://arongranberg.com/astar/docs/followerentity/start.html#Start) () { // Register a callback to modify the movement. // This will be called during every simulation step for the agent. // This may be called multiple times per frame if the time scale is high or fps is low, // or less than once per frame, if the fps is very high. GetComponent().movementOverrides.AddBeforeControlCallback(MovementOverride); // Randomize a phase, to make different agents behave differently phase = UnityEngine.Random.value * 1000; } public void [OnDisable](https://arongranberg.com/astar/docs/followerentity/ondisable.html#OnDisable) () { // Remove the callback when the component is disabled GetComponent().movementOverrides.RemoveBeforeControlCallback(MovementOverride); } public void MovementOverride (Entity [entity](https://arongranberg.com/astar/docs/followerentity.html#entity) , float dt, ref LocalTransform localTransform, ref AgentCylinderShape [shape](https://arongranberg.com/astar/docs/followerentity.html#shape) , ref AgentMovementPlane [movementPlane](https://arongranberg.com/astar/docs/followerentity.html#movementPlane) , ref DestinationPoint [destination](https://arongranberg.com/astar/docs/followerentity.html#destination) , ref MovementState movementState, ref MovementSettings [movementSettings](https://arongranberg.com/astar/docs/followerentity.html#movementSettings) ) { // Rotate the next corner the agent is moving towards around the agent by a random angle. // This will make the agent appear to move in a drunken fashion. // Don't modify the movement as much if we are very close to the end of the path var strengthMultiplier = Mathf.Min(1, movementState.remainingDistanceToEndOfPart / Mathf.Max([shape](https://arongranberg.com/astar/docs/followerentity.html#shape) .[radius](https://arongranberg.com/astar/docs/agentcylindershape.html#radius) , [movementSettings](https://arongranberg.com/astar/docs/followerentity.html#movementSettings) .[follower](https://arongranberg.com/astar/docs/movementsettings.html#follower) .[slowdownTime](https://arongranberg.com/astar/docs/pidmovement.html#slowdownTime) * [movementSettings](https://arongranberg.com/astar/docs/followerentity.html#movementSettings) .[follower](https://arongranberg.com/astar/docs/movementsettings.html#follower) .[speed](https://arongranberg.com/astar/docs/pidmovement.html#speed) )); strengthMultiplier *= strengthMultiplier; // Generate a smoothly varying rotation angle var rotationAngleRad = strength * strengthMultiplier * (Mathf.PerlinNoise1D(Time.time * frequency + phase) - 0.5f); // Clamp it to at most plus or minus 90 degrees rotationAngleRad = Mathf.Clamp(rotationAngleRad, -math.PI*0.5f, math.PI*0.5f); // Convert the rotation angle to a world-space quaternion. // We use the movement plane to rotate around the agent's up axis, // making this code work in both 2D and 3D games. var [rotation](https://arongranberg.com/astar/docs/followerentity.html#rotation) = [movementPlane](https://arongranberg.com/astar/docs/followerentity.html#movementPlane) .value.[ToWorldRotation](https://arongranberg.com/astar/docs/nativemovementplane/toworldrotation.html#ToWorldRotation) (rotationAngleRad); // Rotate the direction to the next corner around the agent movementState.nextCorner = localTransform.Position + math.mul([rotation](https://arongranberg.com/astar/docs/followerentity.html#rotation) , movementState.nextCorner - localTransform.Position); } } `There are a few different phases that you can register callbacks for: * **BeforeControl:** Called before the agent's movement is calculated. At this point, the agent has a valid path, and the next corner that is moving towards has been calculated. * **AfterControl:** Called after the agent's desired movement is calculated. The agent has stored its desired movement in the [MovementControl](https://arongranberg.com/astar/docs/movementcontrol.html) component. Local avoidance has not yet run. * **BeforeMovement:** Called right before the agent's movement is applied. At this point the agent's final movement (including local avoidance) is stored in the [ResolvedMovement](https://arongranberg.com/astar/docs/resolvedmovement.html) component, which you may modify. Warning If any agent has a callback registered here, a sync point will be created for all agents when the callback runs. This can make the simulation not able to utilize multiple threads as effectively. If you have a lot of agents, consider using a custom entity component system instead. But as always, profile first to see if this is actually a problem for your game. The callbacks may be called multiple times per frame, if the fps is low, or if the time scale is high. It may also be called less than once per frame if the fps is very high. Each callback is provided with a **dt** parameter, which is the time in seconds since the last simulation step. You should prefer using this instead of Time.deltaTime. See [simulateMovement](https://arongranberg.com/astar/docs/followerentity.html#simulateMovement) [updatePosition](https://arongranberg.com/astar/docs/followerentity.html#updatePosition) [updateRotation](https://arongranberg.com/astar/docs/followerentity.html#updateRotation) Note This API is unstable. It may change in future versions. movementPlane The plane the agent is moving in. Public ##### [NativeMovementPlane](https://arongranberg.com/astar/docs/nativemovementplane.html) movementPlane The plane the agent is moving in. This is typically the ground plane, which will be the XZ plane in a 3D game, and the XY plane in a 2D game. Ultimately it depends on the graph orientation. If you are doing pathfinding on a spherical world (see [Spherical Worlds](https://arongranberg.com/astar/docs/spherical.html) ), the the movement plane will be the tangent plane of the sphere at the agent's position. movementPlaneSource How to calculate which direction is "up" for the agent. Public ##### [MovementPlaneSource](https://arongranberg.com/astar/docs/ecs2.html#MovementPlaneSource) movementPlaneSource How to calculate which direction is "up" for the agent. In almost all cases, you should use the **Graph** option. This will make the agent use the graph's natural "up" direction. However, if you are using a spherical world, or a world with some other strange shape, then you may want to use the NavmeshNormal or Raycast options. See [Spherical Worlds](https://arongranberg.com/astar/docs/spherical.html) movementSettings Various movement settings. Public ##### [MovementSettings](https://arongranberg.com/astar/docs/movementsettings.html) movementSettings Various movement settings. Some of these settings are exposed on the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) directly. For example [maxSpeed](https://arongranberg.com/astar/docs/followerentity.html#maxSpeed) . Note The return value is a struct. If you want to change some settings, you'll need to modify the returned struct and then assign it back to this property. nearestNavmeshBorder Border of the navmesh closest to the agent's current position. Public ##### [GraphHitInfo](https://arongranberg.com/astar/docs/graphhitinfo.html) nearestNavmeshBorder Border of the navmesh closest to the agent's current position. The border of the navmesh is what separates the walkable and unwalkable part of the world. ![](https://arongranberg.com/astar/docs/images/navmesh_contour.png) Your browser does not support the video tag. If no border could be found (for example if the agent has no path), then the **hit.point** field will be positive infinity. Note hit.node will always be null, as it is currently not possible for the code to figure out which border belongs to what node. You can call [AstarPath.GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html) with hit.point if you need this information. See [currentNode](https://arongranberg.com/astar/docs/followerentity.html#currentNode) [AstarPath.GetNearestBorder](https://arongranberg.com/astar/docs/astarpath/getnearestborder.html) offMeshLink The off-mesh link that the agent is currently traversing. Public ##### [OffMeshLinks.OffMeshLinkTracer](https://arongranberg.com/astar/docs/offmeshlinktracer.html) offMeshLink The off-mesh link that the agent is currently traversing. This will be a default [OffMeshLinks.OffMeshLinkTracer](https://arongranberg.com/astar/docs/offmeshlinktracer.html) if the agent is not traversing an off-mesh link (the [OffMeshLinks.OffMeshLinkTracer.link](https://arongranberg.com/astar/docs/offmeshlinktracer.html#link) field will be null). Note If the off-mesh link is destroyed while the agent is traversing it, this property will still return the link. But be careful about accessing properties like [OffMeshLinkSource.gameObject](https://arongranberg.com/astar/docs/offmeshlinksource.html#gameObject) , as that may refer to a destroyed gameObject. See [Off-mesh links](https://arongranberg.com/astar/docs/offmeshlinks2.html) [onTraverseOffMeshLink](https://arongranberg.com/astar/docs/followerentity.html#onTraverseOffMeshLink) [isTraversingOffMeshLink](https://arongranberg.com/astar/docs/followerentity.html#isTraversingOffMeshLink) onTraverseOffMeshLink Callback to be called when an agent starts traversing an off-mesh link. Public ##### [IOffMeshLinkHandler](https://arongranberg.com/astar/docs/ioffmeshlinkhandler.html) onTraverseOffMeshLink Callback to be called when an agent starts traversing an off-mesh link. The handler will be called when the agent starts traversing an off-mesh link. It allows you to to control the agent for the full duration of the link traversal. Use the passed context struct to get information about the link and to control the agent. `using UnityEngine; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) ; using System.[Collections](https://arongranberg.com/astar/docs/collections.html) ; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) .[ECS](https://arongranberg.com/astar/docs/ecs2.html) ; namespace Pathfinding.Examples { public class FollowerJumpLink : MonoBehaviour, IOffMeshLinkHandler, IOffMeshLinkStateMachine { // Register this class as the handler for off-mesh links when the component is enabled void [OnEnable](https://arongranberg.com/astar/docs/followerentity/onenable.html#OnEnable) () => GetComponent().onTraverseOffMeshLink = this; void [OnDisable](https://arongranberg.com/astar/docs/followerentity/ondisable.html#OnDisable) () => GetComponent().onTraverseOffMeshLink = null; IOffMeshLinkStateMachine IOffMeshLinkHandler.GetOffMeshLinkStateMachine(AgentOffMeshLinkTraversalContext context) => this; void IOffMeshLinkStateMachine.OnFinishTraversingOffMeshLink (AgentOffMeshLinkTraversalContext context) { Debug.Log("An agent finished traversing an off-mesh link"); } void IOffMeshLinkStateMachine.OnAbortTraversingOffMeshLink () { Debug.Log("An agent aborted traversing an off-mesh link"); } IEnumerable IOffMeshLinkStateMachine.OnTraverseOffMeshLink (AgentOffMeshLinkTraversalContext ctx) { var start = (Vector3)ctx.link.relativeStart; var end = (Vector3)ctx.link.relativeEnd; var dir = end - start; // Disable local avoidance while traversing the off-mesh link. // If it was enabled, it will be automatically re-enabled when the agent finishes traversing the link. ctx.DisableLocalAvoidance(); // Move and rotate the agent to face the other side of the link. // When reaching the off-mesh link, the agent may be facing the wrong direction. while (!ctx.MoveTowards( [position](https://arongranberg.com/astar/docs/followerentity.html#position) : start, [rotation](https://arongranberg.com/astar/docs/followerentity.html#rotation) : Quaternion.LookRotation(dir, ctx.movementPlane.up), gravity: true, slowdown: true).reached) { yield return null; } var bezierP0 = start; var bezierP1 = start + Vector3.up*5; var bezierP2 = end + Vector3.up*5; var bezierP3 = end; var jumpDuration = 1.0f; // Animate the AI to jump from the start to the end of the link for (float t = 0; t < jumpDuration; t += ctx.deltaTime) { ctx.transform.Position = AstarSplines.CubicBezier(bezierP0, bezierP1, bezierP2, bezierP3, Mathf.SmoothStep(0, 1, t / jumpDuration)); yield return null; } } } } ` Warning Off-mesh links can be destroyed or disabled at any moment. The built-in code will attempt to make the agent continue following the link even if it is destroyed, but if you write your own traversal code, you should be aware of this. You can alternatively set the corresponding property property on the off-mesh link ( [NodeLink2.onTraverseOffMeshLink](https://arongranberg.com/astar/docs/nodelink2.html#onTraverseOffMeshLink) ) to specify a callback for a specific off-mesh link. Note The agent's off-mesh link handler takes precedence over the link's off-mesh link handler, if both are set. See [Off-mesh links](https://arongranberg.com/astar/docs/offmeshlinks2.html) for more details and example code [isTraversingOffMeshLink](https://arongranberg.com/astar/docs/followerentity.html#isTraversingOffMeshLink) orientation Determines which direction the agent moves in. Public ##### [OrientationMode](https://arongranberg.com/astar/docs/pathfinding.html#OrientationMode) orientation Determines which direction the agent moves in. For 3D games you most likely want the ZAxisIsForward option as that is the convention for 3D games. For 2D games you most likely want the YAxisIsForward option as that is the convention for 2D games. When using ZAxisForward, the +Z axis will be the forward direction of the agent, +Y will be upwards, and +X will be the right direction. When using YAxisForward, the +Y axis will be the forward direction of the agent, +Z will be upwards, and +X will be the right direction. Note This only affects the rotation of the GameObject's Transform, not the entity's internal rotation. Thus it has no effect when the agent is baked in a subscene, since there is no Transform object in that case. ![](https://arongranberg.com/astar/docs/images/aibase_forward_axis.png) pathPending True if a path is currently being calculated. Public ##### bool pathPending True if a path is currently being calculated. pathfindingSettings Pathfinding settings. Public ##### ref[PathRequestSettings](https://arongranberg.com/astar/docs/pathrequestsettings.html) pathfindingSettings Pathfinding settings. The settings in this struct controls how the agent calculates paths to its destination. This is analogous to the [Seeker](https://arongranberg.com/astar/docs/seeker.html) component used for other movement scripts. See [PathRequestSettings](https://arongranberg.com/astar/docs/pathrequestsettings.html) position Position of the agent. Public ##### Vector3? position Position of the agent. In world space. See [rotation](https://arongranberg.com/astar/docs/followerentity.html#rotation) If you want to move the agent you may use [Teleport](https://arongranberg.com/astar/docs/followerentity/teleport.html#Teleport) or [Move](https://arongranberg.com/astar/docs/followerentity/move.html#Move) . positionSmoothing How much to smooth the visual position of the agent. Public ##### float positionSmoothing How much to smooth the visual position of the agent. This does not affect movement, but smoothes out the position of the agent visually. Recommended values are between 0.0 and 0.5. A value of zero will disable smoothing completely. This will make the agent seem to lag slightly behind the internal position of the agent. It may also cut corners slightly. The unit for this field is seconds. radius Radius of the agent in world units. Public ##### float radius Radius of the agent in world units. This is visualized in the scene view as a yellow cylinder around the character. Note that this does not affect pathfinding in any way. The graph used completely determines where the agent can move. Note The [Pathfinding.AILerp](https://arongranberg.com/astar/docs/ailerp.html) script doesn't really have any use of knowing the radius or the height of the character, so this property will always return 0 in that script. reachedCrowdedEndOfPath Like [reachedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedEndOfPath) , but will also return true if the end of the path is crowded, and this agent has stopped because it cannot get closer. Public ##### bool reachedCrowdedEndOfPath Like [reachedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedEndOfPath) , but will also return true if the end of the path is crowded, and this agent has stopped because it cannot get closer. This is only relevant if the agent is using local avoidance. Otherwise, this will be identical to [reachedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedEndOfPath) . If the agent has a stale path (e.g. because the destination changed significantly, or a graph update happened near the agent), false will be returned until the path has been recalculated (typically in the next one or two frames). You can see a visualization of this state by enabling "Reached State" in the [Local Avoidance Debug Rendering](https://arongranberg.com/astar/docs/rvoagent.html#debug) field. Note The agent may not be completely stopped when this is true. It knows that there are other agents in the way, but it might still be able to slowly make some progress. Check the [velocity](https://arongranberg.com/astar/docs/followerentity.html#velocity) property to see if the agent is actually moving. In the video below, the agents will get a red ring around them when this property is true. Your browser does not support the video tag. See [Local Avoidance](https://arongranberg.com/astar/docs/localavoidance.html) . [ReachedEndOfPath](https://arongranberg.com/astar/docs/rvo2.html#ReachedEndOfPath) reachedDestination True if the ai has reached the [destination](https://arongranberg.com/astar/docs/followerentity.html#destination) . Public ##### bool reachedDestination True if the ai has reached the [destination](https://arongranberg.com/astar/docs/followerentity.html#destination) . The agent considers the destination reached when it is within [stopDistance](https://arongranberg.com/astar/docs/followerentity.html#stopDistance) world units from the [destination](https://arongranberg.com/astar/docs/followerentity.html#destination) . Additionally, the destination must not be above the agent's head, and it must not be more than half the agent's height below its feet. If a facing direction was specified when setting the destination, this will only return true once the agent is approximately facing the correct orientation. This value will be updated immediately when the [destination](https://arongranberg.com/astar/docs/followerentity.html#destination) is changed. `IEnumerator [Start](https://arongranberg.com/astar/docs/followerentity/start.html#Start) () { ai.destination = somePoint; // Start to search for a path to the destination immediately ai.SearchPath(); // Wait until the agent has reached the destination while (!ai.reachedDestination) { yield return null; } // The agent has reached the destination now } ` Note The agent may not be able to reach the destination. In that case this property may never become true. Sometimes [reachedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedEndOfPath) is more appropriate. See [stopDistance](https://arongranberg.com/astar/docs/followerentity.html#stopDistance) [remainingDistance](https://arongranberg.com/astar/docs/followerentity.html#remainingDistance) [reachedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedEndOfPath) [reachedCrowdedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedCrowdedEndOfPath) reachedEndOfPath True if the agent has reached the end of the current path. Public ##### bool reachedEndOfPath True if the agent has reached the end of the current path. The agent considers the end of the path reached when it is within [stopDistance](https://arongranberg.com/astar/docs/followerentity.html#stopDistance) world units from the end of the path. Additionally, the end of the path must not be above the agent's head, and it must not be more than half the agent's height below its feet. If a facing direction was specified when setting the destination, this will only return true once the agent is approximately facing the correct orientation. This value will be updated immediately when the [destination](https://arongranberg.com/astar/docs/followerentity.html#destination) is changed. Note Reaching the end of the path does not imply that it has reached its desired destination, as the destination may not even be possible to reach. Sometimes [reachedDestination](https://arongranberg.com/astar/docs/followerentity.html#reachedDestination) is more appropriate. See [remainingDistance](https://arongranberg.com/astar/docs/followerentity.html#remainingDistance) [reachedDestination](https://arongranberg.com/astar/docs/followerentity.html#reachedDestination) [reachedCrowdedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedCrowdedEndOfPath) remainingDistance Approximate remaining distance along the current path to the end of the path. Public ##### float remainingDistance Approximate remaining distance along the current path to the end of the path. This is an approximation for performance reasons, and the agent also does not know the true distance at all times. It tends to be a bit lower than the true distance. It will get more accurate as the agent gets closer to the end of the path. If you want a more accurate distance (at a higher performance cost), you can call GetRemainingPath and sum the length of it. Note This is the distance to the end of the path, which may or may not be the same as the destination. If the character cannot reach the destination it will try to move as close as possible to it. This value will update immediately if the [destination](https://arongranberg.com/astar/docs/followerentity.html#destination) property is changed, or if the agent is moved using the [position](https://arongranberg.com/astar/docs/followerentity.html#position) property or the [Teleport](https://arongranberg.com/astar/docs/followerentity/teleport.html#Teleport) method. If the agent has no path, or if the current path is stale (e.g. if the graph has been updated close to the agent, and it hasn't had time to recalculate its path), this will return positive infinity. See [reachedDestination](https://arongranberg.com/astar/docs/followerentity.html#reachedDestination) [reachedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedEndOfPath) [pathPending](https://arongranberg.com/astar/docs/followerentity.html#pathPending) rotation Rotation of the agent. Public ##### [Quaternion](https://docs.unity3d.com/ScriptReference/Quaternion.html) rotation Rotation of the agent. In world space. The entity internally always treats the Z axis as forward, but this property respects the [orientation](https://arongranberg.com/astar/docs/followerentity.html#orientation) field. So it will return either a rotation with the Y axis as forward, or Z axis as forward, depending on the [orientation](https://arongranberg.com/astar/docs/followerentity.html#orientation) field. Note if [updateRotation](https://arongranberg.com/astar/docs/followerentity.html#updateRotation) is true (which is the default), this will also set the transform's rotation. If [updateRotation](https://arongranberg.com/astar/docs/followerentity.html#updateRotation) is false, only the agent's internal rotation will be set. This will return the agent's rotation even if [updateRotation](https://arongranberg.com/astar/docs/followerentity.html#updateRotation) is false. See [position](https://arongranberg.com/astar/docs/followerentity.html#position) rotationSmoothing How much to smooth the visual rotation of the agent. Public ##### float rotationSmoothing How much to smooth the visual rotation of the agent. This does not affect movement, but smoothes out how the agent rotates visually. Recommended values are between 0.0 and 0.5. A value of zero will disable smoothing completely. The smoothing is done primarily using an exponential moving average, but with a small linear term to make the rotation converge faster when the agent is almost facing the desired direction. Adding smoothing will make the visual rotation of the agent lag a bit behind the actual rotation. Too much smoothing may make the agent seem sluggish, and appear to move sideways. The unit for this field is seconds. rotationSpeed Desired rotation speed in degrees per second. Public ##### float rotationSpeed Desired rotation speed in degrees per second. If the agent is in an open area and gets a new destination directly behind itself, it will start to rotate around with exactly this rotation speed. The agent will slow down its rotation speed as it approaches its desired facing direction. So for example, when it is only 90 degrees away from its desired facing direction, it will only rotate with about half this speed. See [maxRotationSpeed](https://arongranberg.com/astar/docs/pidmovement.html#maxRotationSpeed) rvoSettings Local avoidance settings. Public ##### [RVOAgent](https://arongranberg.com/astar/docs/rvoagent.html) ? rvoSettings Local avoidance settings. simulateMovement Enables or disables movement completely. Public ##### bool? simulateMovement Enables or disables movement completely. If you want the agent to stand still, but still react to local avoidance and use gravity: use [isStopped](https://arongranberg.com/astar/docs/followerentity.html#isStopped) instead. Disabling this will remove the [SimulateMovement](https://arongranberg.com/astar/docs/simulatemovement.html) component from the entity, which prevents most systems from running for this entity. When disabled, the [velocity](https://arongranberg.com/astar/docs/followerentity.html#velocity) property, and many other informational properties, will no longer update. See [autoRepath](https://arongranberg.com/astar/docs/followerentity.html#autoRepath) [isStopped](https://arongranberg.com/astar/docs/followerentity.html#isStopped) steeringTarget Point on the path which the agent is currently moving towards. Public ##### [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) steeringTarget Point on the path which the agent is currently moving towards. This is usually a point a small distance ahead of the agent or the end of the path. If the agent does not have a path at the moment, then the agent's current position will be returned. stopDistance How far away from the destination should the agent aim to stop, in world units. Public ##### float stopDistance How far away from the destination should the agent aim to stop, in world units. If the agent is within this distance from the destination point it will be considered to have reached the destination. Even if you want the agent to stop precisely at a given point, it is recommended to keep this slightly above zero. If it is exactly zero, the agent may have a hard time deciding that it has actually reached the end of the path, due to floating point errors and such. Note This will not be multiplied the agent's scale. updatePosition Determines if the character's position should be coupled to the Transform's position. Public ##### bool updatePosition Determines if the character's position should be coupled to the Transform's position. If false then all movement calculations will happen as usual, but the GameObject that this component is attached to will not move. Instead, only the [position](https://arongranberg.com/astar/docs/followerentity.html#position) property and the internal entity's position will change. This is useful if you want to control the movement of the character using some other means, such as root motion, but still want the AI to move freely. Note This has no effect when the agent is baked in a subscene, since there is no Transform to sync with. See [simulateMovement](https://arongranberg.com/astar/docs/followerentity.html#simulateMovement) which in contrast to this field will disable all [movement](https://arongranberg.com/astar/docs/followerentity.html#movement) calculations. [updateRotation](https://arongranberg.com/astar/docs/followerentity.html#updateRotation) updateRotation Determines if the character's rotation should be coupled to the Transform's rotation. Public ##### bool updateRotation Determines if the character's rotation should be coupled to the Transform's rotation. If false then all movement calculations will happen as usual, but the GameObject that this component is attached to will not rotate. Instead, only the [rotation](https://arongranberg.com/astar/docs/followerentity.html#rotation) property and the internal entity's rotation will change. This is particularly useful for 2D games where you want the Transform to stay in the same orientation, and instead swap out the displayed sprite to indicate the direction the character is facing. You can enable [PIDMovement.DebugFlags](https://arongranberg.com/astar/docs/pidmovement.html#DebugFlags) .Rotation in [debugFlags](https://arongranberg.com/astar/docs/followerentity.html#debugFlags) to draw a gizmos arrow in the scene view to indicate the agent's internal rotation. Note This has no effect when the agent is baked in a subscene, since there is no Transform to sync with. See [updatePosition](https://arongranberg.com/astar/docs/followerentity.html#updatePosition) [rotation](https://arongranberg.com/astar/docs/followerentity.html#rotation) [orientation](https://arongranberg.com/astar/docs/followerentity.html#orientation) velocity Actual velocity that the agent is moving with, including gravity. Public ##### [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) velocity Actual velocity that the agent is moving with, including gravity. In world units per second. This is useful for, for example, selecting which animations to play, and at what speeds. Note Any value set here will be overriden during the next simulation step. Nevertheless, it can be useful to set this value if you have disabled the agent's movement logic using e.g. [simulateMovement](https://arongranberg.com/astar/docs/followerentity.html#simulateMovement) . This value is only an output statistic. It is not used to control the agent's movement. See [desiredVelocity](https://arongranberg.com/astar/docs/followerentity.html#desiredVelocity) world The world in which the [entity](https://arongranberg.com/astar/docs/followerentity.html#entity) resides. Public ##### World world The world in which the [entity](https://arongranberg.com/astar/docs/followerentity.html#entity) resides. This is the same as **proxy.world**, but is provided for convenience. It is only valid when this script is enabled. See FollowerEntityProxy Private/Protected Members ------------------------- [Awake](https://arongranberg.com/astar/docs/versionedmonobehaviour/awake.html#Awake) () [CancelCurrentPathRequest](https://arongranberg.com/astar/docs/followerentity/cancelcurrentpathrequest.html#CancelCurrentPathRequest) () [FinalizeMovement](https://arongranberg.com/astar/docs/followerentity/finalizemovement.html#FinalizeMovement) (nextPosition, nextRotation) Move the agent. [FindComponents](https://arongranberg.com/astar/docs/followerentity/findcomponents.html#FindComponents) () FollowerEntityMigrations Private ##### FollowerEntityMigrations | | | | --- | --- | | MigratePathfindingSettings= 1 << 0 | | | MigrateMovementPlaneSource= 1 << 1 | | | MigrateAutoRepathPolicy= 1 << 2 | | | MigrateManagedSettings= 1 << 3 | | [MovementUpdate](https://arongranberg.com/astar/docs/followerentity/movementupdate.html#MovementUpdate) (deltaTime, nextPosition, nextRotation) Calculate how the agent will move during this frame. [OnDisable](https://arongranberg.com/astar/docs/followerentity/ondisable.html#OnDisable) () Called when the component is disabled or about to be destroyed. [OnEnable](https://arongranberg.com/astar/docs/followerentity/onenable.html#OnEnable) () [OnUpgradeSerializedData](https://arongranberg.com/astar/docs/followerentity/onupgradeserializeddata.html) (migrations, unityThread) [RegisterRuntimeBaker](https://arongranberg.com/astar/docs/followerentity/registerruntimebaker.html#RegisterRuntimeBaker) (baker) [Reset](https://arongranberg.com/astar/docs/versionedmonobehaviour/reset.html#Reset) () Handle serialization backwards compatibility. [Start](https://arongranberg.com/astar/docs/followerentity/start.html#Start) () [UpgradeSerializedData](https://arongranberg.com/astar/docs/versionedmonobehaviour/upgradeserializedd.html#UpgradeSerializedData) (isUnityThread) archetype Private Static ##### EntityArchetype archetype archetypeWorld Private Static ##### World archetypeWorld autoRepathBacking Private ##### [ECS.AutoRepathPolicy](https://arongranberg.com/astar/docs/autorepathpolicy2.html) autoRepathBacking = [ECS.AutoRepathPolicy.Default](https://arongranberg.com/astar/docs/autorepathpolicy2.html#Default) enableGravityBacking Private ##### bool enableGravityBacking = true enableLocalAvoidanceBacking Private ##### bool enableLocalAvoidanceBacking = false managedSettings Private ##### [ManagedSettings](https://arongranberg.com/astar/docs/managedsettings.html) managedSettings = new [ManagedSettings](https://arongranberg.com/astar/docs/managedsettings.html) { [pathfindingSettings](https://arongranberg.com/astar/docs/followerentity.html#pathfindingSettings) = [PathRequestSettings.Default](https://arongranberg.com/astar/docs/pathrequestsettings.html#Default) , } managedState Private ##### [ManagedState](https://arongranberg.com/astar/docs/managedstate.html) managedState = new [ManagedState](https://arongranberg.com/astar/docs/managedstate.html) { [enableLocalAvoidance](https://arongranberg.com/astar/docs/followerentity.html#enableLocalAvoidance) = false, [pathfindingSettings](https://arongranberg.com/astar/docs/followerentity.html#pathfindingSettings) = [PathRequestSettings.Default](https://arongranberg.com/astar/docs/pathrequestsettings.html#Default) , } movement Private ##### [MovementSettings](https://arongranberg.com/astar/docs/movementsettings.html) movement = new [MovementSettings](https://arongranberg.com/astar/docs/movementsettings.html) { follower = new [PIDMovement](https://arongranberg.com/astar/docs/pidmovement.html) { [rotationSpeed](https://arongranberg.com/astar/docs/followerentity.html#rotationSpeed) = 600, speed = 5, [maxRotationSpeed](https://arongranberg.com/astar/docs/followerentity.html#maxRotationSpeed) = 720, maxOnSpotRotationSpeed = 720, slowdownTime = 0.5f, desiredWallDistance = 0.5f, allowRotatingOnSpot = true, leadInRadiusWhenApproachingDestination = 1f, }, [stopDistance](https://arongranberg.com/astar/docs/followerentity.html#stopDistance) = 0.2f, [rotationSmoothing](https://arongranberg.com/astar/docs/followerentity.html#rotationSmoothing) = 0f, [groundMask](https://arongranberg.com/astar/docs/followerentity.html#groundMask) = -1, [isStopped](https://arongranberg.com/astar/docs/followerentity.html#isStopped) = false, [debugFlags](https://arongranberg.com/astar/docs/followerentity.html#debugFlags) = PIDMovement.DebugFlags.Path, } movementPlaneSourceBacking Private ##### [MovementPlaneSource](https://arongranberg.com/astar/docs/ecs2.html#MovementPlaneSource) movementPlaneSourceBacking = MovementPlaneSource.Graph onSearchPath Called when the agent recalculates its path. Private ##### Action onSearchPath Called when the agent recalculates its path. This is called both for automatic path recalculations (see [canSearch](https://arongranberg.com/astar/docs/followerentity.html#canSearch) ) and manual ones (see [SearchPath](https://arongranberg.com/astar/docs/followerentity/searchpath.html#SearchPath) ). See Take a look at the [Pathfinding.AIDestinationSetter](https://arongranberg.com/astar/docs/aidestinationsetter.html) source code for an example of how it can be used. orientationBacking Determines which direction the agent moves in. Private ##### [OrientationMode](https://arongranberg.com/astar/docs/pathfinding.html#OrientationMode) orientationBacking Determines which direction the agent moves in. See [orientation](https://arongranberg.com/astar/docs/followerentity.html#orientation) proxy Proxy for the entity which this movement script represents. Private ##### [FollowerEntityProxy](https://arongranberg.com/astar/docs/followerentityproxy.html) proxy Proxy for the entity which this movement script represents. An entity will be created when this script is enabled, and destroyed when this script is disabled. Check the class documentation to see which components it usually has, and what systems typically affect it. rvoSettingsBacking Private ##### [RVOAgent](https://arongranberg.com/astar/docs/rvoagent.html) rvoSettingsBacking = [RVOAgent.Default](https://arongranberg.com/astar/docs/rvoagent.html#Default) shape Private ##### [AgentCylinderShape](https://arongranberg.com/astar/docs/agentcylindershape.html) shape = new [AgentCylinderShape](https://arongranberg.com/astar/docs/agentcylindershape.html) { [height](https://arongranberg.com/astar/docs/followerentity.html#height) = 2, [radius](https://arongranberg.com/astar/docs/followerentity.html#radius) = 0.5f, } syncPosition Determines if the character's position should be coupled to the Transform's position. Private ##### bool syncPosition = true Determines if the character's position should be coupled to the Transform's position. If false then all movement calculations will happen as usual, but the GameObject that this component is attached to will not move. Instead, only the [position](https://arongranberg.com/astar/docs/followerentity.html#position) property and the internal entity's position will change. This is useful if you want to control the movement of the character using some other means, such as root motion, but still want the AI to move freely. Note This has no effect when the agent is baked in a subscene, since there is no Transform to sync with. See [simulateMovement](https://arongranberg.com/astar/docs/followerentity.html#simulateMovement) which in contrast to this field will disable all [movement](https://arongranberg.com/astar/docs/followerentity.html#movement) calculations. [updateRotation](https://arongranberg.com/astar/docs/followerentity.html#updateRotation) syncRotation Determines if the character's rotation should be coupled to the Transform's rotation. Private ##### bool syncRotation = true Determines if the character's rotation should be coupled to the Transform's rotation. If false then all movement calculations will happen as usual, but the GameObject that this component is attached to will not rotate. Instead, only the [rotation](https://arongranberg.com/astar/docs/followerentity.html#rotation) property and the internal entity's rotation will change. This is particularly useful for 2D games where you want the Transform to stay in the same orientation, and instead swap out the displayed sprite to indicate the direction the character is facing. You can enable [PIDMovement.DebugFlags](https://arongranberg.com/astar/docs/pidmovement.html#DebugFlags) .Rotation in [debugFlags](https://arongranberg.com/astar/docs/followerentity.html#debugFlags) to draw a gizmos arrow in the scene view to indicate the agent's internal rotation. Note This has no effect when the agent is baked in a subscene, since there is no Transform to sync with. See [updatePosition](https://arongranberg.com/astar/docs/followerentity.html#updatePosition) [rotation](https://arongranberg.com/astar/docs/followerentity.html#rotation) [orientation](https://arongranberg.com/astar/docs/followerentity.html#orientation) tr Cached transform component. Private ##### [Transform](https://docs.unity3d.com/ScriptReference/Transform.html) tr Cached transform component. Deprecated Members ------------------ canSearch Enables or disables recalculating the path at regular intervals. Public ##### bool canSearch Enables or disables recalculating the path at regular intervals. Setting this to false does not stop any active path requests from being calculated or stop it from continuing to follow the current path. Note that this only disables automatic path recalculations. If you call the [SearchPath()](https://arongranberg.com/astar/docs/followerentity/searchpath.html#SearchPath) method a path will still be calculated. See [simulateMovement](https://arongranberg.com/astar/docs/followerentity.html#simulateMovement) [isStopped](https://arongranberg.com/astar/docs/followerentity.html#isStopped) Deprecated This has been superseded by [autoRepath.mode](https://arongranberg.com/astar/docs/autorepathpolicy2.html#mode) . --- # ScanAsync - A* Pathfinding Project Function [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .ScanAsync =================================================================================== ScanAsync ([NavGraph](https://arongranberg.com/astar/docs/navgraph.html) graphToScan) Scans a particular graph asynchronously. Public ##### IEnumerable<[Progress](https://arongranberg.com/astar/docs/progress.html) \> ScanAsync ( | | | | | --- | --- | --- | | [NavGraph](https://arongranberg.com/astar/docs/navgraph.html) | graphToScan | | ) Scans a particular graph asynchronously. This is a IEnumerable, you can loop through it to get the progress You can scan graphs asyncronously by yielding when you iterate through the returned IEnumerable. Note that this does not guarantee a good framerate, but it will allow you to at least show a progress bar while scanning. `IEnumerator Start () { foreach (Progress progress in [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[ScanAsync](https://arongranberg.com/astar/docs/astarpath/scanasync.html#ScanAsync) ()) { Debug.Log("Scanning... " + progress.ToString()); yield return null; } } ` See [Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) A\* Pro Feature This is an A\* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A\* Pathfinding Project or the functionality might be limited. The Pro version can be bought [here](http://www.arongranberg.com/astar/buy) ScanAsync ([NavGraph](https://arongranberg.com/astar/docs/navgraph.html) \[\] graphsToScan=null) Scans all specified graphs asynchronously. Public ##### IEnumerable<[Progress](https://arongranberg.com/astar/docs/progress.html) \> ScanAsync ( | | | | | --- | --- | --- | | [NavGraph](https://arongranberg.com/astar/docs/navgraph.html)
\[\] | graphsToScan=null | The graphs to scan. If this parameter is null then all graphs will be scanned | ) Scans all specified graphs asynchronously. This is a IEnumerable, you can loop through it to get the progress You can scan graphs asyncronously by yielding when you loop through the progress. Note that this does not guarantee a good framerate, but it will allow you to at least show a progress bar during scanning. `IEnumerator Start () { foreach (Progress progress in [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[ScanAsync](https://arongranberg.com/astar/docs/astarpath/scanasync.html#ScanAsync) ()) { Debug.Log("Scanning... " + progress.ToString()); yield return null; } } ` Note If the graphs are already scanned, doing an async scan will temporarily cause increased memory usage, since two copies of the graphs will be kept in memory during the async scan. This may not be desirable on some platforms. A non-async scan will not cause this temporary increased memory usage. A\* Pro Feature This is an A\* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A\* Pathfinding Project or the functionality might be limited. The Pro version can be bought [here](http://www.arongranberg.com/astar/buy) See [Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) --- # Scan - A* Pathfinding Project Function [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .Scan ============================================================================== Scan ([NavGraph](https://arongranberg.com/astar/docs/navgraph.html) graphToScan) Scans a particular graph. Public ##### void Scan ( | | | | | --- | --- | --- | | [NavGraph](https://arongranberg.com/astar/docs/navgraph.html) | graphToScan | | ) Scans a particular graph. Calling this method will recalculate the specified graph from scratch. This method is pretty slow (depending on graph type and graph complexity of course), so it is advisable to use smaller graph updates whenever possible. `// Recalculate all graphs [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) (); // Recalculate only the first grid graph var graphToScan = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .gridGraph; [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) (graphToScan); // Recalculate only the first and third graphs var graphsToScan = new [] { [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .graphs[0], [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .graphs[2] }; [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) (graphsToScan); ` See [Graph Updates during Runtime](https://arongranberg.com/astar/docs/graphupdates.html) [ScanAsync](https://arongranberg.com/astar/docs/astarpath/scanasync.html#ScanAsync) Scan ([NavGraph](https://arongranberg.com/astar/docs/navgraph.html) \[\] graphsToScan=null) Scans all specified graphs. Public ##### void Scan ( | | | | | --- | --- | --- | | [NavGraph](https://arongranberg.com/astar/docs/navgraph.html)
\[\] | graphsToScan=null | The graphs to scan. If this parameter is null then all graphs will be scanned | ) Scans all specified graphs. Calling this method will recalculate all specified graphs (or all graphs if the **graphsToScan** parameter is null) from scratch. This method is pretty slow (depending on graph type and graph complexity of course), so it is advisable to use smaller graph updates whenever possible. `// Recalculate all graphs [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) (); // Recalculate only the first grid graph var graphToScan = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .gridGraph; [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) (graphToScan); // Recalculate only the first and third graphs var graphsToScan = new [] { [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .graphs[0], [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[data](https://arongranberg.com/astar/docs/astarpath.html#data) .graphs[2] }; [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[Scan](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) (graphsToScan); ` See [Graph Updates during Runtime](https://arongranberg.com/astar/docs/graphupdates.html) [ScanAsync](https://arongranberg.com/astar/docs/astarpath/scanasync.html#ScanAsync) --- # SlabListExtensions - A* Pathfinding Project Class SlabListExtensions ======================== Public Public Static Methods --------------------- [Remove](https://arongranberg.com/astar/docs/slablistextensions/remove.html#Remove) (list, value) --- # UpdateGraphs - A* Pathfinding Project Function [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .UpdateGraphs ====================================================================================== UpdateGraphs ([Bounds](https://docs.unity3d.com/ScriptReference/Bounds.html) bounds) Update all graphs within **bounds**. Public ##### void UpdateGraphs ( | | | | | --- | --- | --- | | [Bounds](https://docs.unity3d.com/ScriptReference/Bounds.html) | bounds | | ) Update all graphs within **bounds**. The graphs will be updated as soon as possible. This is equivalent to `UpdateGraphs(new GraphUpdateObject(bounds)); ` `// Create an obstacle var obstacle = GameObject.Instantiate(someObstacle, somePosition, Quaternion.identity); // Use the bounding box from the attached collider var bounds = obstacle.GetComponent().bounds; // Update the graph to account for the new obstacle [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[UpdateGraphs](https://arongranberg.com/astar/docs/astarpath/updategraphs.html#UpdateGraphs3) (bounds); ` See [FlushGraphUpdates](https://arongranberg.com/astar/docs/astarpath/flushgraphupdates.html#FlushGraphUpdates) [batchGraphUpdates](https://arongranberg.com/astar/docs/astarpath.html#batchGraphUpdates) [Graph Updates during Runtime](https://arongranberg.com/astar/docs/graphupdates.html) UpdateGraphs ([Bounds](https://docs.unity3d.com/ScriptReference/Bounds.html) bounds, float delay) Update all graphs within **bounds** after **delay** seconds. Public ##### void UpdateGraphs ( | | | | | --- | --- | --- | | [Bounds](https://docs.unity3d.com/ScriptReference/Bounds.html) | bounds | | | float | delay | | ) Update all graphs within **bounds** after **delay** seconds. The graphs will be updated as soon as possible. `// Create an obstacle var obstacle = GameObject.Instantiate(someObstacle, somePosition, Quaternion.identity); // Use the bounding box from the attached collider var bounds = obstacle.GetComponent().bounds; // Update the graph to account for the new obstacle [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[UpdateGraphs](https://arongranberg.com/astar/docs/astarpath/updategraphs.html#UpdateGraphs3) (bounds); ` See [FlushGraphUpdates](https://arongranberg.com/astar/docs/astarpath/flushgraphupdates.html#FlushGraphUpdates) [batchGraphUpdates](https://arongranberg.com/astar/docs/astarpath.html#batchGraphUpdates) [Graph Updates during Runtime](https://arongranberg.com/astar/docs/graphupdates.html) UpdateGraphs ([GraphUpdateObject](https://arongranberg.com/astar/docs/graphupdateobject.html) ob) Update all graphs using the GraphUpdateObject. Public ##### void UpdateGraphs ( | | | | | --- | --- | --- | | [GraphUpdateObject](https://arongranberg.com/astar/docs/graphupdateobject.html) | ob | | ) Update all graphs using the GraphUpdateObject. This can be used to, e.g make all nodes in a region unwalkable, or set them to a higher penalty. The graphs will be updated as soon as possible (with respect to [batchGraphUpdates](https://arongranberg.com/astar/docs/astarpath.html#batchGraphUpdates) ) `// using Pathfinding; //At top of script // As an example, use the bounding box from the attached collider Bounds bounds = GetComponent().bounds; var guo = new GraphUpdateObject(bounds); // Set some settings guo.updatePhysics = true; [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[UpdateGraphs](https://arongranberg.com/astar/docs/astarpath/updategraphs.html#UpdateGraphs3) (guo); ` See [FlushGraphUpdates](https://arongranberg.com/astar/docs/astarpath/flushgraphupdates.html#FlushGraphUpdates) [batchGraphUpdates](https://arongranberg.com/astar/docs/astarpath.html#batchGraphUpdates) [Graph Updates during Runtime](https://arongranberg.com/astar/docs/graphupdates.html) UpdateGraphs ([GraphUpdateObject](https://arongranberg.com/astar/docs/graphupdateobject.html) ob, float delay) Update all graphs using the GraphUpdateObject after **delay** seconds. Public ##### void UpdateGraphs ( | | | | | --- | --- | --- | | [GraphUpdateObject](https://arongranberg.com/astar/docs/graphupdateobject.html) | ob | | | float | delay | | ) Update all graphs using the GraphUpdateObject after **delay** seconds. This can be used to, e.g make all nodes in a region unwalkable, or set them to a higher penalty. `// using Pathfinding; //At top of script // As an example, use the bounding box from the attached collider Bounds bounds = GetComponent().bounds; var guo = new GraphUpdateObject(bounds); // Set some settings guo.updatePhysics = true; [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[UpdateGraphs](https://arongranberg.com/astar/docs/astarpath/updategraphs.html#UpdateGraphs3) (guo); ` See [FlushGraphUpdates](https://arongranberg.com/astar/docs/astarpath/flushgraphupdates.html#FlushGraphUpdates) [batchGraphUpdates](https://arongranberg.com/astar/docs/astarpath.html#batchGraphUpdates) [Graph Updates during Runtime](https://arongranberg.com/astar/docs/graphupdates.html) --- # SpanExtensions - A* Pathfinding Project Class SpanExtensions ==================== Public Public Static Methods --------------------- [AsUnsafeReadOnlySpan](https://arongranberg.com/astar/docs/spanextensions/asunsafereadonlyspan.html#AsUnsafeReadOnlySpan) (arr) Converts a NativeArray to a span, assuming it will only be read. [AsUnsafeSpan](https://arongranberg.com/astar/docs/spanextensions/asunsafespan.html) (...) Converts a... [AsUnsafeSpanNoChecks](https://arongranberg.com/astar/docs/spanextensions/asunsafespannochecks.html#AsUnsafeSpanNoChecks) (arr) Converts a NativeArray to a span without performing any checks. [Contains](https://arongranberg.com/astar/docs/spanextensions/contains.html#Contains) (span, value) Returns true if the value exists in the span. [CopyFrom](https://arongranberg.com/astar/docs/spanextensions/copyfrom.html) (span, ...) Copies the contents of a... [Fill](https://arongranberg.com/astar/docs/spanextensions/fill.html#Fill) (span, value) [FillZeros](https://arongranberg.com/astar/docs/spanextensions/fillzeros.html#FillZeros) (span) [GetAllocator](https://arongranberg.com/astar/docs/spanextensions/getallocator.html#GetAllocator) (arr) [IndexOf](https://arongranberg.com/astar/docs/spanextensions/indexof.html#IndexOf) (span, value) Returns the index of the first occurrence of a value in the span. [InsertRange](https://arongranberg.com/astar/docs/spanextensions/insertrange.html#InsertRange) (list, index, count) Shifts elements toward the end of this list, increasing its length. [MoveToUnsafeSpan](https://arongranberg.com/astar/docs/spanextensions/movetounsafespan.html#MoveToUnsafeSpan) (arr) Moves a NativeArray to a span. [Sort](https://arongranberg.com/astar/docs/spanextensions/sort.html) (span, \[comp\]) Sorts the span in ascending order. Private/Protected Members ------------------------- AllocatorOffset Private Static Readonly ##### int AllocatorOffset = UnsafeUtility.GetFieldOffset(typeof(NativeArray).GetField("m\_AllocatorLabel", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)) --- # UnsafeSpan - A* Pathfinding Project Struct UnsafeSpan ================= Public Replacement for System.Span which is compatible with earlier versions of C#. Warning These spans do not in any way guarantee that the memory they refer to is valid. It is up to the user to make sure the memory is not deallocated before usage. It should never be used to refer to managed heap memory without pinning it, since unpinned managed memory can be moved by some runtimes. This has several benefits over e.g. UnsafeList: * It is faster to index into a span than into an UnsafeList, especially from C#. In fact, indexing into an [UnsafeSpan](https://arongranberg.com/astar/docs/unsafespan.html) is as fast as indexing into a native C# array. * As a comparison, indexing into a NativeArray can easily be 10x slower, and indexing into an UnsafeList is at least a few times slower. * You can create a [UnsafeSpan](https://arongranberg.com/astar/docs/unsafespan.html) from a C# array by pinning it. * It can be sliced efficiently. * It supports ref returns for the indexing operations. Public Methods -------------- [Clone](https://arongranberg.com/astar/docs/unsafespan/clone.html#Clone) (allocator) Creates a new copy of the span allocated using the given allocator. [CopyTo](https://arongranberg.com/astar/docs/unsafespan/copyto.html) (...) ... [Free](https://arongranberg.com/astar/docs/unsafespan/free.html) (\[...\]) [Move](https://arongranberg.com/astar/docs/unsafespan/move.html#Move) (startIndex, toIndex, count) Copy the range \[startIndex,startIndex+count) to \[toIndex,toIndex+count)\ \ [MoveToNativeArray](https://arongranberg.com/astar/docs/unsafespan/movetonativearray.html#MoveToNativeArray) (allocator)\ \ Moves this data to a new NativeArray.\ \ [Reallocate](https://arongranberg.com/astar/docs/unsafespan/reallocate.html#Reallocate) (allocator, newSize)\ \ Returns a new span with a different size, copies the current data over to it, and frees this span.\ \ [Reinterpret](https://arongranberg.com/astar/docs/unsafespan/reinterpret.html) (\[...\])\ \ Returns a copy of this span, but with a different data-type.\ \ [Slice](https://arongranberg.com/astar/docs/unsafespan/slice.html) (start, \[length\])\ \ Creates a new span which is a slice of this span.\ \ [ToArray](https://arongranberg.com/astar/docs/unsafespan/toarray.html#ToArray) ()\ \ Converts the span to a managed array.\ \ [UnsafeSpan](https://arongranberg.com/astar/docs/unsafespan/unsafespan.html) (...)\ \ ...\ \ Public Static Methods\ ---------------------\ \ [RemoveAt](https://arongranberg.com/astar/docs/unsafespan/removeat.html#RemoveAt) (span, index)\ \ Removes an element from a span, reducing its length by one.\ \ Public Variables\ ----------------\ \ Allocator\ \ Public Readonly\ \ ##### Allocator Allocator\ \ Length\ \ Number of elements in this span.\ \ Public\ \ ##### int Length\ \ Number of elements in this span.\ \ this\[int index\]\ \ Public\ \ ##### ref T this\[int index\]\ \ this\[uint index\]\ \ Public\ \ ##### ref T this\[uint index\]\ \ Private/Protected Members\ -------------------------\ \ length\ \ Internal Readonly\ \ ##### uint length\ \ ptr\ \ Internal Readonly\ \ ##### unsafe T \* ptr --- # AstarColor - A* Pathfinding Project Class AstarColor Extends [ISerializationCallbackReceiver](https://docs.unity3d.com/ScriptReference/ISerializationCallbackReceiver.html) ======================================================================================================================================== Public Stores editor colors. Public Methods -------------- [AstarColor](https://arongranberg.com/astar/docs/astarcolor/astarcolor.html#AstarColor) () [OnAfterDeserialize](https://arongranberg.com/astar/docs/astarcolor/onafterdeserialize.html#OnAfterDeserialize) () [OnBeforeSerialize](https://arongranberg.com/astar/docs/astarcolor/onbeforeserialize.html#OnBeforeSerialize) () [PushToStatic](https://arongranberg.com/astar/docs/astarcolor/pushtostatic.html#PushToStatic) () Pushes all local variables out to static ones. Public Static Methods --------------------- [ColorHash](https://arongranberg.com/astar/docs/astarcolor/colorhash.html#ColorHash) () [GetAreaColor](https://arongranberg.com/astar/docs/astarcolor/getareacolor.html#GetAreaColor) (area) Returns an color for an area, uses both user set ones and calculated. [GetTagColor](https://arongranberg.com/astar/docs/astarcolor/gettagcolor.html#GetTagColor) (tag) Returns an color for a tag, uses both user set ones and calculated. Public Variables ---------------- \_AreaColors Holds user set area colors. Public ##### Color\[\] \_AreaColors Holds user set area colors. Use GetAreaColor to get an area color \_BoundsHandles Public ##### [Color](https://docs.unity3d.com/ScriptReference/Color.html) \_BoundsHandles \_ConnectionHighLerp Public ##### [Color](https://docs.unity3d.com/ScriptReference/Color.html) \_ConnectionHighLerp \_ConnectionLowLerp Public ##### [Color](https://docs.unity3d.com/ScriptReference/Color.html) \_ConnectionLowLerp \_MeshEdgeColor Public ##### [Color](https://docs.unity3d.com/ScriptReference/Color.html) \_MeshEdgeColor \_SolidColor Public ##### [Color](https://docs.unity3d.com/ScriptReference/Color.html) \_SolidColor \_UnwalkableNode Public ##### [Color](https://docs.unity3d.com/ScriptReference/Color.html) \_UnwalkableNode Public Static Variables ----------------------- BoundsHandles Public Static ##### [Color](https://docs.unity3d.com/ScriptReference/Color.html) BoundsHandles = new Color(0.29F, 0.454F, 0.741F, 0.9F) ConnectionHighLerp Public Static ##### [Color](https://docs.unity3d.com/ScriptReference/Color.html) ConnectionHighLerp = new Color(1, 0, 0, 0.5F) ConnectionLowLerp Public Static ##### [Color](https://docs.unity3d.com/ScriptReference/Color.html) ConnectionLowLerp = new Color(0, 1, 0, 0.5F) MeshEdgeColor Public Static ##### [Color](https://docs.unity3d.com/ScriptReference/Color.html) MeshEdgeColor = new Color(0, 0, 0, 0.5F) SolidColor Public Static ##### [Color](https://docs.unity3d.com/ScriptReference/Color.html) SolidColor = new Color(30/255f, 102/255f, 201/255f, 0.9F) UnwalkableNode Public Static ##### [Color](https://docs.unity3d.com/ScriptReference/Color.html) UnwalkableNode = new Color(1, 0, 0, 0.5F) Private/Protected Members ------------------------- AreaColors Private Static ##### Color\[\] AreaColors = new Color\[1\] --- # RVO - A* Pathfinding Project Namespace RVO ============= Classes ------- [AgentIndex](https://arongranberg.com/astar/docs/agentindex.html) Index of an [RVO](https://arongranberg.com/astar/docs/rvo.html) agent in the local avoidance simulation. [RVOAgent](https://arongranberg.com/astar/docs/rvoagent.html) Agent data for the local avoidance system. [RVOSystem](https://arongranberg.com/astar/docs/rvosystem.html) Simulates local avoidance in an [ECS](https://arongranberg.com/astar/docs/ecs2.html) context. --- # EuclideanEmbedding - A* Pathfinding Project Class EuclideanEmbedding ======================== Public Implements heuristic optimizations. See heuristic-opt Game AI Pro - [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) Architecture Optimizations by Steve Rabin and Nathan R. Sturtevant A\* Pro Feature This is an A\* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A\* Pathfinding Project or the functionality might be limited. The Pro version can be bought [here](http://www.arongranberg.com/astar/buy) Inner Types ----------- [EuclideanEmbeddingSearchPath](https://arongranberg.com/astar/docs/euclideanembeddingsearchpath.html) Public Methods -------------- [OnDisable](https://arongranberg.com/astar/docs/euclideanembedding/ondisable.html#OnDisable) () [OnDrawGizmos](https://arongranberg.com/astar/docs/euclideanembedding/ondrawgizmos.html#OnDrawGizmos) () [RecalculateCosts](https://arongranberg.com/astar/docs/euclideanembedding/recalculatecosts.html#RecalculateCosts) () [RecalculatePivots](https://arongranberg.com/astar/docs/euclideanembedding/recalculatepivots.html#RecalculatePivots) () Public Static Methods --------------------- [GetHeuristic](https://arongranberg.com/astar/docs/euclideanembedding/getheuristic.html#GetHeuristic) (costs, pivotCount, nodeIndex1, nodeIndex2) Public Variables ---------------- costs Costs laid out as n\*\[int\],n\*\[int\],n\*\[int\] where n is the number of pivot points. Public ##### NativeArray costs Costs laid out as n\*\[int\],n\*\[int\],n\*\[int\] where n is the number of pivot points. Each node has n integers which is the cost from that node to the pivot node. They are at around the same place in the array for simplicity and for cache locality. cost(nodeIndex, pivotIndex) = costs\[nodeIndex\*pivotCount+pivotIndex\] dirty Public ##### bool dirty mode If heuristic optimization should be used and how to place the pivot points. Public ##### [HeuristicOptimizationMode](https://arongranberg.com/astar/docs/util.html#HeuristicOptimizationMode) mode If heuristic optimization should be used and how to place the pivot points. See [Heuristic Optimization](https://arongranberg.com/astar/docs/heuristicopt.html) Game AI Pro - [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) Architecture Optimizations by Steve Rabin and Nathan R. Sturtevant pivotCount Public ##### int pivotCount pivotPointRoot All children of this transform will be used as pivot points. Public ##### [Transform](https://docs.unity3d.com/ScriptReference/Transform.html) pivotPointRoot All children of this transform will be used as pivot points. seed Public ##### int seed spreadOutCount Public ##### int spreadOutCount = 10 Private/Protected Members ------------------------- [ApplyGridGraphEndpointSpecialCase](https://arongranberg.com/astar/docs/euclideanembedding/applygridgraphendpoint.html#ApplyGridGraphEndpointSpecialCase) () Special case necessary for paths to unwalkable nodes right next to walkable nodes to be able to use good heuristics. [GetClosestWalkableNodesToChildrenRecursively](https://arongranberg.com/astar/docs/euclideanembedding/getclosestwalkablenode.html#GetClosestWalkableNodesToChildrenRecursiv) (tr, nodes) [GetRandom](https://arongranberg.com/astar/docs/euclideanembedding/getrandom.html#GetRandom) () Simple linear congruential generator. [PickAnyWalkableNode](https://arongranberg.com/astar/docs/euclideanembedding/pickanywalkablenode.html#PickAnyWalkableNode) () [PickNRandomNodes](https://arongranberg.com/astar/docs/euclideanembedding/picknrandomnodes.html#PickNRandomNodes) (count, buffer) Pick N random walkable nodes from all nodes in all graphs and add them to the buffer. [RecalculateCostsInner](https://arongranberg.com/astar/docs/euclideanembedding/recalculatecostsinner.html#RecalculateCostsInner) () pivots Private ##### [GraphNode](https://arongranberg.com/astar/docs/graphnode.html) \[\] pivots ra Private Static ##### const uint ra = 12820163 rc Private Static ##### const uint rc = 1140671485 rval Private ##### uint rval --- # AgentIndex - A* Pathfinding Project Struct AgentIndex Extends ICleanupComponentData =============================================== Public Index of an [RVO](https://arongranberg.com/astar/docs/rvo.html) agent in the local avoidance simulation. If this component is present, that indicates that the agent is part of a local avoidance simulation. The [RVOSystem](https://arongranberg.com/astar/docs/rvosystem.html) is responsible for adding and removing this component as necessary. Any other systems should only concern themselves with the [RVOAgent](https://arongranberg.com/astar/docs/rvoagent.html) component. Warning This component does not support cloning. You must not clone entities that use this component. There doesn't seem to be any way to make this work with the Unity.Entities API at the moment. Public Methods -------------- [Exists](https://arongranberg.com/astar/docs/agentindex/exists.html#Exists) (agentData) True if the agent exists in the simulation. [TryGetIndex](https://arongranberg.com/astar/docs/agentindex/trygetindex.html) (..., index) Returns the index of the agent in the simulation's data arrays, if the agent exists. Public Variables ---------------- Version Public ##### int Version packedAgentIndex Public Readonly ##### int packedAgentIndex Public Static Variables ----------------------- DeletedBit Public Static ##### const int DeletedBit = 1 << 31 IndexMask Public Static ##### const int IndexMask = (1 << 24) - 1 VersionMask Public Static ##### const int VersionMask = 0b1111\_111 << [VersionOffset](https://arongranberg.com/astar/docs/agentindex.html#VersionOffset) VersionOffset Public Static ##### const int VersionOffset = 24 Private/Protected Members ------------------------- [AgentIndex](https://arongranberg.com/astar/docs/agentindex/agentindex.html) (...) Index Index of the agent in the simulation's data arrays. Internal ##### int Index Index of the agent in the simulation's data arrays. See [TryGetIndex](https://arongranberg.com/astar/docs/agentindex/trygetindex.html) Valid Internal ##### bool Valid [WithDeleted](https://arongranberg.com/astar/docs/agentindex/withdeleted.html#WithDeleted) () [WithIncrementedVersion](https://arongranberg.com/astar/docs/agentindex/withincrementedversion.html#WithIncrementedVersion) () --- # Heuristic Optimization - A* Pathfinding Project Heuristic Optimization ====================== A tutorial on how to use heuristic optimization to gain significant speedups. Normally when a pathfinding search is made, a [heuristic](https://arongranberg.com/astar/docs/astarpath.html#heuristic) is used. The heuristic is something which gives a rough estimate of how far it is at least to the target. Usually the real-world [Euclidean distance](https://en.wikipedia.org/wiki/Euclidean_distance) to the target is used directly since this is fast and usually gives relatively good results. The problem is that in worlds which are not just open space with a few small obstacles scattered around, this estimate isn't very good. The result is that the search goes through a lot more nodes than it would have needed to if the heuristic had been better. A\* Inspector → Settings → Heuristic Optimization Holds settings for heuristic optimization. See [Heuristic Optimization](https://arongranberg.com/astar/docs/heuristicopt.html) A\* Pro Feature This is an A\* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A\* Pathfinding Project or the functionality might be limited. The Pro version can be bought [here](http://www.arongranberg.com/astar/buy) See This setting corresponds to the member [AstarPath.euclideanEmbedding](https://arongranberg.com/astar/docs/astarpath.html#euclideanEmbedding) A\* Pro Feature This is an A\* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A\* Pathfinding Project or the functionality might be limited. The Pro version can be bought [here](http://www.arongranberg.com/astar/buy) Results ------- This technique can drastically reduce the number of nodes that have to be searched through to find the target. This can, in turn, improve the performance significantly. Consider the two images below. In the first image, this optimization is disabled while in the second one it is enabled. In the second image, the search is more informed and can avoid many directions that will not lead it to the target. Heuristic optimization disabled ![](https://arongranberg.com/astar/docs/images/heuristic/heuristic_off.png) Heuristic optimization enabled ![](https://arongranberg.com/astar/docs/images/heuristic/heuristic_on.png) Background ---------- If your world is static, or updates very rarely, there is a technique that can be used to precalculate distances between nodes and get heuristics which are a lot better. This can improve pathfinding performance by an order of magnitude (10x) in many cases. The optimal heuristic is, of course, when we know the distance between every node to every other node in the graph; however, this is a bit impractical since it would take a very long time to calculate and would use a lot of space. So what can be done is that we select a few nodes (henceforth called "pivot points") and calculate the distances from those nodes to every other node in the graph. This can then be used to calculate pretty good heuristics. Regardless of what heuristic is used, the A\* algorithm will always search through all nodes which could lie on the shortest path(s), so this technique will, for example, not give any performance increase on large open grid graphs because a path search rarely searches much more than the nodes on the shortest paths anyway. The image below shows a completely empty grid graph and 3 different optimal paths. The algorithm will have to search through all the nodes in the green region because they are all equally good (i.e., they have the same length). All those nodes lie on an optimal path because in a grid there are many optimal paths. ![](https://arongranberg.com/astar/docs/images/heuristic/suboptimal.png) The A\* [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) Project has algorithms for automatically selecting pretty good pivot points because it can be quite hard to select them in a good way manually. When I profile, I sometimes find that my manual placements of pivot points are worse than just randomly selected points. Placing Pivot Points Manually ----------------------------- When placing these pivot points, the key thing about them is that they should be at dead ends in the world. They perform best when many paths can be extended to the pivot point and still be a shortest path. In the image below, you can see pivot points in purple. The agent in the bottom left corner has requested a path to the green circle. ![](https://arongranberg.com/astar/docs/images/heuristic/pivotPointPlacement.png) There can also be game-specific knowledge you can apply. For example, in a TD game, almost all units will move towards a single goal. So if you just place a single pivot point at the goal, all paths will be much faster to calculate because the optimal distance to that point from every other one is already known. Placing Pivot Points Automatically ---------------------------------- Two modes exist. Either all points are chosen randomly, or an algorithm is applied which selects nodes as far away from each other as possible. The second one gives much higher quality heuristics, but it is much slower to calculate as it requires that the initial distance calculation is done in serial and multithreading is therefore of no use. In the image below, a comparison is shown between 5 randomly selected points and 5 points far away from each other. The ones which are far away from each other tend to be placed in dead ends or in the corners of the map, which will give very good results. ![](https://arongranberg.com/astar/docs/images/heuristic/random.png) The number of pivot points that you should use varies. The best solution is just to try different values and see what is best for your game. When reaching over a hundred pivot points, the overhead from them is often greater than the gain from a reduced number of nodes to search. I would recommend between 1 and 100; try different values and see what works best. You might notice that there is a delay at the start of the game until the pathfinding starts working. This is because it is busy preprocessing the heuristic lookups. If you find this delay so large that it becomes a problem, switch to using the "Random" mode instead of the "Random Spread Out" (if you were using that) or decrease the number of pivot points. --- # RVOAgent - A* Pathfinding Project Struct RVOAgent Extends IComponentData ====================================== Public Agent data for the local avoidance system. See [Local Avoidance](https://arongranberg.com/astar/docs/localavoidance.html) Public Variables ---------------- agentTimeHorizon How far into the future to look for collisions with other agents (in seconds) Public ##### float agentTimeHorizon How far into the future to look for collisions with other agents (in seconds) collidesWith Layer mask specifying which layers this agent will avoid. Public ##### [RVOLayer](https://arongranberg.com/astar/docs/rvo2.html#RVOLayer) collidesWith Layer mask specifying which layers this agent will avoid. You can set it as CollidesWith = RVOLayer.DefaultAgent | RVOLayer.Layer3 | RVOLayer.Layer6 ... This can be very useful in games which have multiple teams of some sort. For example you usually want the agents in one team to avoid each other, but you do not want them to avoid the enemies. This field only affects which other agents that this agent will avoid, it does not affect how other agents react to this agent. See [Bitmask Tutorial](https://arongranberg.com/astar/docs/bitmasks.html) [http://en.wikipedia.org/wiki/Mask\_(computing)](http://en.wikipedia.org/wiki/Mask_(computing)) debug Enables drawing debug information in the scene view. Public ##### [AgentDebugFlags](https://arongranberg.com/astar/docs/rvo2.html#AgentDebugFlags) debug Enables drawing debug information in the scene view. flowFollowingStrength Public ##### float flowFollowingStrength layer Specifies the avoidance layer for this agent. Public ##### [RVOLayer](https://arongranberg.com/astar/docs/rvo2.html#RVOLayer) layer Specifies the avoidance layer for this agent. The [collidesWith](https://arongranberg.com/astar/docs/rvoagent.html#collidesWith) mask on other agents will determine if they will avoid this agent. locked A locked unit cannot move. Public ##### bool locked A locked unit cannot move. Other units will still avoid it but avoidance quality is not the best. maxNeighbours Max number of other agents to take into account. Public ##### int maxNeighbours Max number of other agents to take into account. A smaller value can reduce CPU load, a higher value can lead to better local avoidance quality. obstacleTimeHorizon How far into the future to look for collisions with obstacles (in seconds) Public ##### float obstacleTimeHorizon How far into the future to look for collisions with obstacles (in seconds) priority How strongly other agents will avoid this agent. Public ##### float priority How strongly other agents will avoid this agent. Usually a value between 0 and 1. Agents with similar priorities will avoid each other with an equal strength. If an agent sees another agent with a higher priority than itself it will avoid that agent more strongly. In the extreme case (e.g this agent has a priority of 0 and the other agent has a priority of 1) it will treat the other agent as being a moving obstacle. Similarly if an agent sees another agent with a lower priority than itself it will avoid that agent less. In general the avoidance strength for this agent is: `if this.priority > 0 or other.priority > 0: avoidanceStrength = other.priority / (this.priority + other.priority); else: avoidanceStrength = 0.5 ` priorityMultiplier Priority multiplier. Public ##### float priorityMultiplier Priority multiplier. This functions identically to the [priority](https://arongranberg.com/astar/docs/rvoagent.html#priority) , however it is not exposed in the Unity inspector. It is primarily used by the [Pathfinding.RVO.RVODestinationCrowdedBehavior](https://arongranberg.com/astar/docs/rvodestinationcrowdedbehavior.html) . Public Static Variables ----------------------- Default Good default settings for an [RVO](https://arongranberg.com/astar/docs/rvo.html) agent. Public Static Readonly ##### [RVOAgent](https://arongranberg.com/astar/docs/rvoagent.html) Default = new [RVOAgent](https://arongranberg.com/astar/docs/rvoagent.html) { [locked](https://arongranberg.com/astar/docs/rvoagent.html#locked) = false, [agentTimeHorizon](https://arongranberg.com/astar/docs/rvoagent.html#agentTimeHorizon) = 1.0f, [obstacleTimeHorizon](https://arongranberg.com/astar/docs/rvoagent.html#obstacleTimeHorizon) = 0.5f, [maxNeighbours](https://arongranberg.com/astar/docs/rvoagent.html#maxNeighbours) = 10, [layer](https://arongranberg.com/astar/docs/rvoagent.html#layer) = RVOLayer.DefaultAgent, [collidesWith](https://arongranberg.com/astar/docs/rvoagent.html#collidesWith) = ([RVOLayer](https://arongranberg.com/astar/docs/rvo2.html#RVOLayer) )(-1), [priority](https://arongranberg.com/astar/docs/rvoagent.html#priority) = 0.5f, [priorityMultiplier](https://arongranberg.com/astar/docs/rvoagent.html#priorityMultiplier) = 1.0f, [flowFollowingStrength](https://arongranberg.com/astar/docs/rvoagent.html#flowFollowingStrength) = 0.0f, [debug](https://arongranberg.com/astar/docs/rvoagent.html#debug) = AgentDebugFlags.Nothing, } Good default settings for an [RVO](https://arongranberg.com/astar/docs/rvo.html) agent. --- # AstarData - A* Pathfinding Project Class AstarData =============== Public Stores the navigation graphs for the A\* [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) System. An instance of this class is assigned to [AstarPath.data](https://arongranberg.com/astar/docs/astarpath.html#data) . From it you can access all graphs loaded through the [graphs](https://arongranberg.com/astar/docs/astardata.html#graphs) variable. This class also handles a lot of the high level serialization. Public Methods -------------- [AddGraph](https://arongranberg.com/astar/docs/astardata/addgraph.html) (\[...\]) Adds... [ClearGraphs](https://arongranberg.com/astar/docs/astardata/cleargraphs.html#ClearGraphs) () Destroys all graphs and sets [graphs](https://arongranberg.com/astar/docs/astardata.html#graphs) to null. [DeserializeGraphs](https://arongranberg.com/astar/docs/astardata/deserializegraphs.html) (\[...\]) Deserializes... [DeserializeGraphsAdditive](https://arongranberg.com/astar/docs/astardata/deserializegraphsadditive.html) (bytes, \[warnIfDuplicateGuids\]) [DisposeUnmanagedData](https://arongranberg.com/astar/docs/astardata/disposeunmanageddata.html#DisposeUnmanagedData) () [DuplicateGraph](https://arongranberg.com/astar/docs/astardata/duplicategraph.html#DuplicateGraph) (graph) Duplicates the given graph and adds the duplicate to the [graphs](https://arongranberg.com/astar/docs/astardata.html#graphs) array. [FindGraph](https://arongranberg.com/astar/docs/astardata/findgraph.html#FindGraph) (predicate) Returns the first graph which satisfies the predicate. [FindGraphOfType](https://arongranberg.com/astar/docs/astardata/findgraphoftype.html#FindGraphOfType) (type) Returns the first graph of type **type** found in the [graphs](https://arongranberg.com/astar/docs/astardata.html#graphs) array. [FindGraphTypes](https://arongranberg.com/astar/docs/astardata/findgraphtypes.html#FindGraphTypes) () Find all graph types supported in this build. [FindGraphWhichInheritsFrom](https://arongranberg.com/astar/docs/astardata/findgraphwhichinheritsfrom.html#FindGraphWhichInheritsFrom) (type) Returns the first graph which inherits from the type **type**. [FindGraphsOfType](https://arongranberg.com/astar/docs/astardata/findgraphsoftype.html#FindGraphsOfType) (type) Loop through this function to get all graphs of type 'type'. [GetData](https://arongranberg.com/astar/docs/astardata/getdata.html#GetData) () Get the serialized data for all graphs and their settings. [GetGraphIndex](https://arongranberg.com/astar/docs/astardata/getgraphindex.html#GetGraphIndex) (graph) Gets the index of the graph in the [graphs](https://arongranberg.com/astar/docs/astardata.html#graphs) array. [GetNodes](https://arongranberg.com/astar/docs/astardata/getnodes.html#GetNodes) (callback) Calls the **callback** with every node in all graphs. [GetUpdateableGraphs](https://arongranberg.com/astar/docs/astardata/getupdateablegraphs.html#GetUpdateableGraphs) () All graphs which implements the UpdateableGraph interface. [LoadFromCache](https://arongranberg.com/astar/docs/astardata/loadfromcache.html#LoadFromCache) () Load from data from [file\_cachedStartup](https://arongranberg.com/astar/docs/astardata.html#file_cachedStartup) . [OnDestroy](https://arongranberg.com/astar/docs/astardata/ondestroy.html#OnDestroy) () [OnEnable](https://arongranberg.com/astar/docs/astardata/onenable.html#OnEnable) () Loads the graphs from memory, will load cached graphs if any exists. [RemoveGraph](https://arongranberg.com/astar/docs/astardata/removegraph.html#RemoveGraph) (graph) Removes the specified graph from the [graphs](https://arongranberg.com/astar/docs/astardata.html#graphs) array and Destroys it in a safe manner. [SerializeGraph](https://arongranberg.com/astar/docs/astardata/serializegraph.html) (settings, graph, \[checksum\]) Serializes a single graph to a byte array. [SerializeGraphs](https://arongranberg.com/astar/docs/astardata/serializegraphs.html) (\[...\]) Serializes a... [SetData](https://arongranberg.com/astar/docs/astardata/setdata.html#SetData) (data) Set the serialized data for all graphs and their settings. [UpdateShortcuts](https://arongranberg.com/astar/docs/astardata/updateshortcuts.html#UpdateShortcuts) () Updates shortcuts to the first graph of different types. Public Static Methods --------------------- [GetGraph](https://arongranberg.com/astar/docs/astardata/getgraph.html#GetGraph) (node) Graph which contains the specified node. Public Variables ---------------- cacheStartup Should graph-data be cached. Public ##### bool cacheStartup Should graph-data be cached. Caching the startup means saving the whole graphs - not only the settings - to a file ([file\_cachedStartup](https://arongranberg.com/astar/docs/astardata.html#file_cachedStartup) ) which can be loaded when the game starts. This is usually much faster than scanning the graphs when the game starts. This is configured from the editor under the "Save & Load" tab. ![](https://arongranberg.com/astar/docs/images/inspector/saveloadtab@2x.png) See [Saving and Loading Graphs](https://arongranberg.com/astar/docs/saveloadgraphs.html) file\_cachedStartup Serialized data for cached startup. Public ##### [TextAsset](https://docs.unity3d.com/ScriptReference/TextAsset.html) file\_cachedStartup Serialized data for cached startup. If set, and [cacheStartup](https://arongranberg.com/astar/docs/astardata.html#cacheStartup) is enabled, graphs will be deserialized from this file when the game starts. ![](https://arongranberg.com/astar/docs/images/inspector/saveloadtab@2x.png) graphs All graphs. Public ##### [NavGraph](https://arongranberg.com/astar/docs/navgraph.html) \[\] graphs = new [NavGraph](https://arongranberg.com/astar/docs/navgraph.html) \[0\] All graphs. This will be filled only after deserialization has completed. May contain null entries if graph have been removed. gridGraph Shortcut to the first [GridGraph](https://arongranberg.com/astar/docs/gridgraph.html) . Public ##### [GridGraph](https://arongranberg.com/astar/docs/gridgraph.html) gridGraph Shortcut to the first [GridGraph](https://arongranberg.com/astar/docs/gridgraph.html) . layerGridGraph Shortcut to the first [LayerGridGraph](https://arongranberg.com/astar/docs/layergridgraph.html) . Public ##### [LayerGridGraph](https://arongranberg.com/astar/docs/layergridgraph.html) layerGridGraph Shortcut to the first [LayerGridGraph](https://arongranberg.com/astar/docs/layergridgraph.html) . A\* Pro Feature This is an A\* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A\* Pathfinding Project or the functionality might be limited. The Pro version can be bought [here](http://www.arongranberg.com/astar/buy) linkGraph Shortcut to the first [LinkGraph](https://arongranberg.com/astar/docs/linkgraph.html) . Public ##### [LinkGraph](https://arongranberg.com/astar/docs/linkgraph.html) linkGraph Shortcut to the first [LinkGraph](https://arongranberg.com/astar/docs/linkgraph.html) . navmeshGraph Shortcut to the first [NavMeshGraph](https://arongranberg.com/astar/docs/navmeshgraph.html) . Public ##### [NavMeshGraph](https://arongranberg.com/astar/docs/navmeshgraph.html) navmeshGraph Shortcut to the first [NavMeshGraph](https://arongranberg.com/astar/docs/navmeshgraph.html) . pointGraph Shortcut to the first [PointGraph](https://arongranberg.com/astar/docs/pointgraph.html) . Public ##### [PointGraph](https://arongranberg.com/astar/docs/pointgraph.html) pointGraph Shortcut to the first [PointGraph](https://arongranberg.com/astar/docs/pointgraph.html) . recastGraph Shortcut to the first [RecastGraph](https://arongranberg.com/astar/docs/recastgraph.html) . Public ##### [RecastGraph](https://arongranberg.com/astar/docs/recastgraph.html) recastGraph Shortcut to the first [RecastGraph](https://arongranberg.com/astar/docs/recastgraph.html) . A\* Pro Feature This is an A\* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A\* Pathfinding Project or the functionality might be limited. The Pro version can be bought [here](http://www.arongranberg.com/astar/buy) Public Static Variables ----------------------- graphTypes All supported graph types. Public Static ##### System.Type\[\] graphTypes All supported graph types. Populated through reflection search Private/Protected Members ------------------------- [AssertSafe](https://arongranberg.com/astar/docs/astardata/assertsafe.html#AssertSafe) (onlyAddingGraph=…) [AstarData](https://arongranberg.com/astar/docs/astardata/astardata.html#AstarData) (active) [ClearGraphsInternal](https://arongranberg.com/astar/docs/astardata/cleargraphsinternal.html#ClearGraphsInternal) () [CreateGraph](https://arongranberg.com/astar/docs/astardata/creategraph.html#CreateGraph) (type) Creates a new graph instance of type **type**. [DeserializeGraphsPartAdditive](https://arongranberg.com/astar/docs/astardata/deserializegraphspartadditive.html#DeserializeGraphsPartAdditive) (sr, warnIfDuplicateGuids) Helper function for deserializing graphs. [DestroyAllNodes](https://arongranberg.com/astar/docs/astardata/destroyallnodes.html#DestroyAllNodes) () Makes all graphs become unscanned. [LockGraphStructure](https://arongranberg.com/astar/docs/astardata/lockgraphstructure.html#LockGraphStructure) (allowAddingGraphs=…) Prevent the graph structure from changing during the time this lock is held. MarkerDeserializeGraphs Private Static Readonly ##### Unity.Profiling.ProfilerMarker MarkerDeserializeGraphs = new Unity.Profiling.ProfilerMarker("DeserializeGraphs") MarkerFindGraphTypes Private Static Readonly ##### Unity.Profiling.ProfilerMarker MarkerFindGraphTypes = new Unity.Profiling.ProfilerMarker("FindGraphTypes") MarkerLoadFromCache Private Static Readonly ##### Unity.Profiling.ProfilerMarker MarkerLoadFromCache = new Unity.Profiling.ProfilerMarker("LoadFromCache") MarkerSerializeGraphs Private Static Readonly ##### Unity.Profiling.ProfilerMarker MarkerSerializeGraphs = new Unity.Profiling.ProfilerMarker("SerializeGraphs") [UnlockGraphStructure](https://arongranberg.com/astar/docs/astardata/unlockgraphstructure.html#UnlockGraphStructure) () Allows the graph structure to change again. active The [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component which owns this [AstarData](https://arongranberg.com/astar/docs/astardata.html) . Private ##### [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) active The [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component which owns this [AstarData](https://arongranberg.com/astar/docs/astardata.html) . data Serialized data for all graphs and settings. Private ##### byte\[\]?? data Serialized data for all graphs and settings. dataString Serialized data for all graphs and settings. Private ##### string dataString Serialized data for all graphs and settings. Stored as a base64 encoded string because otherwise Unity's Undo system would sometimes corrupt the byte data (because it only stores deltas). This can be accessed as a byte array from the [data](https://arongranberg.com/astar/docs/astardata.html#data) property. graphStructureLocked Private ##### List graphStructureLocked = new List() Deprecated Members ------------------ navmesh Shortcut to the first [NavMeshGraph](https://arongranberg.com/astar/docs/navmeshgraph.html) . Public ##### [NavMeshGraph](https://arongranberg.com/astar/docs/navmeshgraph.html) navmesh Shortcut to the first [NavMeshGraph](https://arongranberg.com/astar/docs/navmeshgraph.html) . Deprecated Use [navmeshGraph](https://arongranberg.com/astar/docs/astardata.html#navmeshGraph) instead --- # JobCopyFromEntitiesToRVOSimulator - A* Pathfinding Project Struct JobCopyFromEntitiesToRVOSimulator Extends IJobEntity =========================================================== Public Public Methods -------------- [Execute](https://arongranberg.com/astar/docs/jobcopyfromentitiestorvosimulator/execute.html#Execute) (entity, transform, shape, movementPlane, agentIndex, controller, target) Public Variables ---------------- agentData Public ##### [SimulatorBurst.AgentData](https://arongranberg.com/astar/docs/agentdata.html) agentData agentOffMeshLinkTraversalLookup Public ##### ComponentLookup<[AgentOffMeshLinkTraversal](https://arongranberg.com/astar/docs/agentoffmeshlinktraversal.html) \> agentOffMeshLinkTraversalLookup agentOutputData Public ##### [SimulatorBurst.AgentOutputData](https://arongranberg.com/astar/docs/agentoutputdata.html) agentOutputData dt Public ##### float dt movementPlaneMode Public ##### [MovementPlane](https://arongranberg.com/astar/docs/rvo2.html#MovementPlane) movementPlaneMode --- # NavmeshUpdates - A* Pathfinding Project Class NavmeshUpdates ==================== Public Helper for navmesh cut objects. Responsible for keeping track of which navmesh cuts have moved and coordinating graph updates to account for those changes. See [Navmesh Cutting](https://arongranberg.com/astar/docs/navmeshcutting.html) [AstarPath.navmeshUpdates](https://arongranberg.com/astar/docs/astarpath.html#navmeshUpdates) [NavmeshBase.enableNavmeshCutting](https://arongranberg.com/astar/docs/navmeshbase.html#enableNavmeshCutting) A\* Pro Feature This is an A\* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A\* Pathfinding Project or the functionality might be limited. The Pro version can be bought [here](http://www.arongranberg.com/astar/buy) Inner Types ----------- [NavmeshUpdateSettings](https://arongranberg.com/astar/docs/navmeshupdatesettings.html) Stores navmesh cutting related data for a single graph. Public Methods -------------- [DiscardPending](https://arongranberg.com/astar/docs/navmeshupdates/discardpending.html#DiscardPending) () Discards all pending updates caused by moved or modified navmesh cuts. [ForceUpdate](https://arongranberg.com/astar/docs/navmeshupdates/forceupdate.html#ForceUpdate) () Checks all [NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) instances and updates graphs if needed. [ForceUpdateAround](https://arongranberg.com/astar/docs/navmeshupdates/forceupdatearound.html#ForceUpdateAround) (clipper) Public Variables ---------------- updateInterval How often to check if an update needs to be done (real seconds between checks). Public ##### float updateInterval How often to check if an update needs to be done (real seconds between checks). For worlds with a very large number of [NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) objects, it might be bad for performance to do this check every frame. If you think this is a performance penalty, increase this number to check less often. If negative, no updates will be done. They must be manually triggered using [ForceUpdate](https://arongranberg.com/astar/docs/navmeshupdates/forceupdate.html#ForceUpdate) . For almost all games, this can be kept at 0. If you are smoothly moving navmesh cuts around, however, you may want to increase this a bit, to avoid triggering a navmesh update every frame. An update not only has the cost associated with the update directly, but also the cost of recalculating the path for any agents that are using the affected part of the navmesh. `// Check every frame (the default) [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[navmeshUpdates](https://arongranberg.com/astar/docs/astarpath.html#navmeshUpdates) .updateInterval = 0; // Check every 0.1 seconds [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[navmeshUpdates](https://arongranberg.com/astar/docs/astarpath.html#navmeshUpdates) .updateInterval = 0.1f; // Never check for changes [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[navmeshUpdates](https://arongranberg.com/astar/docs/astarpath.html#navmeshUpdates) .updateInterval = -1; // You will have to schedule updates manually using [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[navmeshUpdates](https://arongranberg.com/astar/docs/astarpath.html#navmeshUpdates) .ForceUpdate(); `You can also find this in the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) inspector under Settings. ![](https://arongranberg.com/astar/docs/images/navmeshcut_update_interval@2x.png) Private/Protected Members ------------------------- [AddListener](https://arongranberg.com/astar/docs/navmeshupdates/addlistener.html#AddListener) (listener) [ExpandedXZBounds](https://arongranberg.com/astar/docs/navmeshupdates/expandedxzbounds.html#ExpandedXZBounds) (bounds) [HandleOnDisableCallback](https://arongranberg.com/astar/docs/navmeshupdates/handleondisablecallback.html#HandleOnDisableCallback) (obj) Called when a [NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) or [NavmeshAdd](https://arongranberg.com/astar/docs/navmeshadd.html) is disabled. [HandleOnEnableCallback](https://arongranberg.com/astar/docs/navmeshupdates/handleonenablecallback.html#HandleOnEnableCallback) (obj) Called when a [NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) or [NavmeshAdd](https://arongranberg.com/astar/docs/navmeshadd.html) is enabled. [OnDisable](https://arongranberg.com/astar/docs/navmeshupdates/ondisable.html#OnDisable) () [OnEnable](https://arongranberg.com/astar/docs/navmeshupdates/onenable.html#OnEnable) () [RefreshEnabledState](https://arongranberg.com/astar/docs/navmeshupdates/refreshenabledstate.html#RefreshEnabledState) () [RemoveListener](https://arongranberg.com/astar/docs/navmeshupdates/removelistener.html#RemoveListener) (listener) [ScheduleTileUpdates](https://arongranberg.com/astar/docs/navmeshupdates/scheduletileupdates.html#ScheduleTileUpdates) () [Update](https://arongranberg.com/astar/docs/navmeshupdates/update.html#Update) () Update is called once per frame. astar Internal ##### [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) astar lastUpdateTime Last time navmesh cuts were applied. Private ##### float lastUpdateTime = float.NegativeInfinity Last time navmesh cuts were applied. listeners Private ##### List<[NavmeshUpdateSettings](https://arongranberg.com/astar/docs/navmeshupdatesettings.html) \> listeners = new List<[NavmeshUpdateSettings](https://arongranberg.com/astar/docs/navmeshupdatesettings.html) \>() --- # RVOSystem - A* Pathfinding Project Struct RVOSystem Extends ISystem ================================ Public Simulates local avoidance in an [ECS](https://arongranberg.com/astar/docs/ecs2.html) context. All agent entities must have the following [ECS](https://arongranberg.com/astar/docs/ecs2.html) components: * LocalTransform * [AgentCylinderShape](https://arongranberg.com/astar/docs/agentcylindershape.html) * [AgentMovementPlane](https://arongranberg.com/astar/docs/agentmovementplane.html) * [RVOAgent](https://arongranberg.com/astar/docs/rvoagent.html) * [MovementControl](https://arongranberg.com/astar/docs/movementcontrol.html) : where you store how you want the agent to move * [ResolvedMovement](https://arongranberg.com/astar/docs/resolvedmovement.html) : where this system will output how the agent should move, when using [RVO](https://arongranberg.com/astar/docs/rvo.html) The system will use the data from [MovementControl](https://arongranberg.com/astar/docs/movementcontrol.html) , and output the following fields to [ResolvedMovement](https://arongranberg.com/astar/docs/resolvedmovement.html) : [ResolvedMovement.targetPoint](https://arongranberg.com/astar/docs/resolvedmovement.html#targetPoint) : Where the agent should move to. [ResolvedMovement.speed](https://arongranberg.com/astar/docs/resolvedmovement.html#speed) : At what speed the agent should move, in world units. [ResolvedMovement.turningRadiusMultiplier](https://arongranberg.com/astar/docs/resolvedmovement.html#turningRadiusMultiplier) : This will go up if its more crowded, to indicate that the agent should try to take wider turns to improve crowd flow. The [AgentIndex](https://arongranberg.com/astar/docs/agentindex.html) component will be added to the agent automatically by this system. You do not need to care about it. Inner Types ----------- [JobCopyFromEntitiesToRVOSimulator](https://arongranberg.com/astar/docs/jobcopyfromentitiestorvosimulator.html) [JobCopyFromRVOSimulatorToEntities](https://arongranberg.com/astar/docs/jobcopyfromrvosimulatortoentities.html) Public Methods -------------- [AddAndRemoveAgentsFromSimulation](https://arongranberg.com/astar/docs/rvosystem/addandremoveagentsfromsimulatio.html#AddAndRemoveAgentsFromSimulation) (systemState, simulator) [CopyFromEntitiesToRVOSimulator](https://arongranberg.com/astar/docs/rvosystem/copyfromentitiestorvosimulator.html#CopyFromEntitiesToRVOSimulator) (systemState, simulator, dt) [CopyFromRVOSimulatorToEntities](https://arongranberg.com/astar/docs/rvosystem/copyfromrvosimulatortoentities.html#CopyFromRVOSimulatorToEntities) (systemState, simulator) [OnCreate](https://arongranberg.com/astar/docs/rvosystem/oncreate.html#OnCreate) (state) [OnDestroy](https://arongranberg.com/astar/docs/rvosystem/ondestroy.html#OnDestroy) (state) [OnUpdate](https://arongranberg.com/astar/docs/rvosystem/onupdate.html#OnUpdate) (systemState) [RemoveAllAgentsFromSimulation](https://arongranberg.com/astar/docs/rvosystem/removeallagentsfromsimulation.html#RemoveAllAgentsFromSimulation) (systemState) Public Variables ---------------- agentOffMeshLinkTraversalLookup Public ##### ComponentLookup<[AgentOffMeshLinkTraversal](https://arongranberg.com/astar/docs/agentoffmeshlinktraversal.html) \> agentOffMeshLinkTraversalLookup lastSimulator Keeps track of the last simulator that this [RVOSystem](https://arongranberg.com/astar/docs/rvosystem.html) saw. Public ##### [GCHandle](https://arongranberg.com/astar/docs/%3Cundefined%3E) lastSimulator Keeps track of the last simulator that this [RVOSystem](https://arongranberg.com/astar/docs/rvosystem.html) saw. This is a weak GCHandle to allow it to be stored in an ISystem. --- # NavGraph - A* Pathfinding Project Class NavGraph Extends [IGraphInternals](https://arongranberg.com/astar/docs/igraphinternals.html) =================================================================================================== Public Abstract Base class for all graphs. Public Methods -------------- [CountNodes](https://arongranberg.com/astar/docs/navgraph/countnodes.html#CountNodes) () Number of nodes in the graph. [GetNearest](https://arongranberg.com/astar/docs/navgraph/getnearest.html) (position, \[constraint\]) [GetNodes](https://arongranberg.com/astar/docs/navgraph/getnodes.html) (action, \[data\]) Calls a delegate with... [IsInsideBounds](https://arongranberg.com/astar/docs/navgraph/isinsidebounds.html#IsInsideBounds) (point) True if the point is inside the bounding box of this graph. [IsPointOnNavmesh](https://arongranberg.com/astar/docs/navgraph/ispointonnavmesh.html#IsPointOnNavmesh) (position) True if the point is on a walkable part of the navmesh, as seen from above. [NearestNodeDistanceSqrLowerBound](https://arongranberg.com/astar/docs/navgraph/nearestnodedistancesqrlowerbound.html#NearestNodeDistanceSqrLowerBound) (position, constraint) Lower bound on the squared distance from the given point to the closest node in this graph. [OnDrawGizmos](https://arongranberg.com/astar/docs/navgraph/ondrawgizmos.html#OnDrawGizmos) (gizmos, drawNodes, redrawScope, renderInGame) Draw gizmos for the graph. [RandomPointOnSurface](https://arongranberg.com/astar/docs/navgraph/randompointonsurface.html) (..., \[highQuality\]) [RelocateNodes](https://arongranberg.com/astar/docs/navgraph/relocatenodes.html#RelocateNodes) (deltaMatrix) Moves the nodes in this graph. [Scan](https://arongranberg.com/astar/docs/navgraph/scan.html#Scan) () Scan the graph. [Snapshot](https://arongranberg.com/astar/docs/navgraph/snapshot.html#Snapshot) (bounds) Captures a snapshot of a part of the graph, to allow restoring it later. Public Variables ---------------- active Reference to the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) object in the scene. Public ##### [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) active Reference to the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) object in the scene. bounds World bounding box for the graph. Public ##### [Bounds](https://docs.unity3d.com/ScriptReference/Bounds.html) bounds World bounding box for the graph. This always contains the whole graph. Note Since this an axis aligned bounding box, it may not be particularly tight if the graph is rotated. It is ok for a graph type to return an infinitely large bounding box, but this may make some operations less efficient. The point graph will always return an infinitely large bounding box. drawGizmos Enable to draw gizmos in the Unity scene view. Public ##### bool drawGizmos = true Enable to draw gizmos in the Unity scene view. In the inspector this value corresponds to the state of the 'eye' icon in the top left corner of every graph inspector. graphIndex Index of the graph, used for identification purposes. Public ##### uint graphIndex Index of the graph, used for identification purposes. guid Used as an ID of the graph, considered to be unique. Public ##### [Guid](https://arongranberg.com/astar/docs/guid.html) guid Used as an ID of the graph, considered to be unique. Note This is [Pathfinding.Util.Guid](https://arongranberg.com/astar/docs/guid.html) not System.Guid. A replacement for System.Guid was coded for better compatibility with iOS You should never have to change this value yourself. infoScreenOpen Used in the editor to check if the info screen is open. Public ##### bool infoScreenOpen Used in the editor to check if the info screen is open. Should be inside UNITY\_EDITOR only #ifs but just in case anyone tries to serialize a [NavGraph](https://arongranberg.com/astar/docs/navgraph.html) instance using Unity, I have left it like this as it would otherwise cause a crash when building. Version 3.0.8.1 was released because of this bug only initialPenalty Default penalty to apply to all nodes. Public ##### uint initialPenalty Default penalty to apply to all nodes. See [Graph Updates during Runtime](https://arongranberg.com/astar/docs/graphupdates.html) [GraphNode.Penalty](https://arongranberg.com/astar/docs/graphnode.html#Penalty) [Working with tags](https://arongranberg.com/astar/docs/tags.html) isScanned True if the graph has been scanned and contains nodes. Public Abstract ##### bool isScanned True if the graph has been scanned and contains nodes. [Graphs](https://arongranberg.com/astar/docs/graphs2.html) are typically scanned when the game starts, but they can also be scanned manually. If a graph has not been scanned, it does not contain any nodes and it not possible to use it for pathfinding. See [AstarPath.Scan(NavGraph)](https://arongranberg.com/astar/docs/astarpath/scan.html#Scan2) name Name of the graph. Public ##### string name Name of the graph. Can be set in the unity editor open Is the graph open in the editor. Public ##### bool open Is the graph open in the editor. persistent True if the graph will be included when serializing graph data. Public ##### bool persistent True if the graph will be included when serializing graph data. If false, the graph will be ignored when saving graph data. Most graphs are persistent, but the [LinkGraph](https://arongranberg.com/astar/docs/linkgraph.html) is not persistent because links are always re-created from components at runtime. showInInspector True if the graph should be visible in the editor. Public ##### bool showInInspector True if the graph should be visible in the editor. False is used for some internal graph types that users don't have to worry about. Private/Protected Members ------------------------- [AssertSafeToUpdateGraph](https://arongranberg.com/astar/docs/navgraph/assertsafetoupdategraph.html#AssertSafeToUpdateGraph) () Throws an exception if it is not safe to update internal graph data right now. [DeserializeExtraInfo](https://arongranberg.com/astar/docs/navgraph/deserializeextrainfo.html) (ctx) [DestroyAllNodes](https://arongranberg.com/astar/docs/navgraph/destroyallnodes.html) () [DirtyBounds](https://arongranberg.com/astar/docs/navgraph/dirtybounds.html#DirtyBounds) (bounds) Notifies the system that changes have been made inside these bounds. [DisposeUnmanagedData](https://arongranberg.com/astar/docs/navgraph/disposeunmanageddata.html) () [DrawUnwalkableNodes](https://arongranberg.com/astar/docs/navgraph/drawunwalkablenodes.html#DrawUnwalkableNodes) (gizmos, size, redrawScope, renderInGame) [OnDestroy](https://arongranberg.com/astar/docs/navgraph/ondestroy.html) () [PostDeserialization](https://arongranberg.com/astar/docs/navgraph/postdeserialization.html) (ctx) ... [ScanInternal](https://arongranberg.com/astar/docs/navgraph/scaninternal.html) (\[...\]) [SerializeExtraInfo](https://arongranberg.com/astar/docs/navgraph/serializeextrainfo.html) (ctx) SerializedEditorSettings Private ##### string SerializedEditorSettings exists True if the graph exists, false if it has been destroyed. Internal ##### bool exists True if the graph exists, false if it has been destroyed. serializedEditorSettings Used in the Unity editor to store serialized settings for graph inspectors. Private ##### string serializedEditorSettings Used in the Unity editor to store serialized settings for graph inspectors. Deprecated Members ------------------ [GetNearestForce](https://arongranberg.com/astar/docs/navgraph/getnearestforce.html#GetNearestForce) (position, constraint) Returns the nearest node to a position using the specified [NNConstraint](https://arongranberg.com/astar/docs/nnconstraint.html) . --- # JobCopyFromRVOSimulatorToEntities - A* Pathfinding Project Struct JobCopyFromRVOSimulatorToEntities Extends IJobEntity =========================================================== Public Public Methods -------------- [Execute](https://arongranberg.com/astar/docs/jobcopyfromrvosimulatortoentities/execute.html#Execute) (transform, shape, agentIndex, controller, control, resolved) Public Variables ---------------- agentDataVersions Public ##### NativeArray<[AgentIndex](https://arongranberg.com/astar/docs/agentindex.html) \> agentDataVersions agentOutputData Public ##### [SimulatorBurst.AgentOutputData](https://arongranberg.com/astar/docs/agentoutputdata.html) agentOutputData quadtree Public ##### [RVOQuadtreeBurst](https://arongranberg.com/astar/docs/rvoquadtreeburst.html) quadtree Public Static Variables ----------------------- MaximumCirclePackingDensity See [https://en.wikipedia.org/wiki/Circle\_packing](https://en.wikipedia.org/wiki/Circle_packing) . Public Static ##### const float MaximumCirclePackingDensity = 0.9069f See [https://en.wikipedia.org/wiki/Circle\_packing](https://en.wikipedia.org/wiki/Circle_packing) . --- # AgentCylinderShape - A* Pathfinding Project Struct AgentCylinderShape Extends IComponentData ================================================ Public An agent's shape represented as a cylinder. Public Variables ---------------- height Height of the agent in world units. Public ##### float height Height of the agent in world units. radius Radius of the agent in world units. Public ##### float radius Radius of the agent in world units. --- # NavmeshCut - A* Pathfinding Project Class NavmeshCut Extends [NavmeshClipper](https://arongranberg.com/astar/docs/navmeshclipper.html) =================================================================================================== Public Navmesh cutting is used for fast recast/navmesh graph updates. ![](https://arongranberg.com/astar/docs/images/generated/inspectors/NavmeshCut@2x.png) Navmesh cutting is used to cut holes in an existing navmesh generated by a recast or navmesh graph. With navmesh cutting you can remove (cut) parts of the navmesh that is blocked by obstacles such as a new building in an RTS game however you cannot add anything new to the navmesh or change the positions of the nodes. Normal graph updates on recast/navmesh graphs, in contrast, only allow either just changing parameters on existing nodes (e.g make a whole triangle unwalkable), which is not very flexible, or recalculate whole tiles, which can be slow. Navmesh cutting is typically significantly faster than recalculating whole tiles from scratch in a recast graph. Your browser does not support the video tag. The [NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) component uses a 2D shape to cut the navmesh with. This shape can be produced by either one of the built-in 2D shapes (rectangle/circle) or one of the 3D shapes (cube/sphere/capsule) which will be projected down to a 2D shape when cutting happens. You can also specify a custom 2D mesh to use as a cut. ![](https://arongranberg.com/astar/docs/images/navmeshcut.png) Note that the rectangle/circle shapes are not 3D. If you rotate them, you will see that the 2D shape will be rotated and then just projected down on the XZ plane. Therefore it is recommended to use the 3D shapes (cube/sphere/capsule) in most cases since those are easier to use. In the scene view the [NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) looks like an extruded 2D shape because a navmesh cut also has a height. It will only cut the part of the navmesh which it touches. For performance reasons it only checks the bounding boxes of the triangles in the navmesh, so it may cut triangles whoose bounding boxes it intersects even if the triangle does not intersect the extruded shape. However in most cases this does not make a large difference. It is also possible to set the navmesh cut to dual mode by setting the [isDual](https://arongranberg.com/astar/docs/navmeshcut.html#isDual) field to true. This will prevent it from cutting a hole in the navmesh and it will instead just split the navmesh along the border but keep both the interior and the exterior. This can be useful if you for example want to change the penalty of some region which does not neatly line up with the navmesh triangles. It is often combined with the [GraphUpdateScene](https://arongranberg.com/astar/docs/graphupdatescene.html) component (however note that the [GraphUpdateScene](https://arongranberg.com/astar/docs/graphupdatescene.html) component will not automatically reapply the penalty if the graph is updated again). By default the navmesh cut does not take rotation or scaling into account. If you want to do that, you can set the [useRotationAndScale](https://arongranberg.com/astar/docs/navmeshcut.html#useRotationAndScale) field to true. **Custom meshes** For most purposes you can use the built-in shapes, however in some cases a custom cutting mesh may be useful. The custom mesh should be a flat 2D shape like in the image below. The script will then find the contour of that mesh and use that shape as the cut. Make sure that all normals are smooth and that the mesh contains no UV information. Otherwise Unity might split a vertex and then the script will not find the correct contour. You should not use a very high polygon mesh since that will create a lot of nodes in the navmesh graph and slow down pathfinding because of that. For very high polygon meshes it might even cause more suboptimal paths to be generated if it causes many thin triangles to be added to the navmesh. ![](https://arongranberg.com/astar/docs/images/navmeshcut_mesh.png) **Update frequency** Navmesh cuts are typically pretty fast, so you may be tempted to make them update the navmesh very often (once every few frames perhaps), just because you can spare the CPU power. However, updating the navmesh too often can also have consequences for agents that are following paths on the graph. If a navmesh cut updates the graph near an agent, it will usually have to recalculate its path. If this happens too often, this can lead to the pathfinding worker threads being overwhelmed by pathfinding requests, causing higher latency for individual pathfinding requests. This can, in turn, make agents less responsive. So it's recommended to keep the update frequency reasonable. After all, a player is unlikely to notice if the navmesh was updated 20 times per second or 2 times per second (or even less often). You can primarily control this using the [updateDistance](https://arongranberg.com/astar/docs/navmeshcut.html#updateDistance) and [updateRotationDistance](https://arongranberg.com/astar/docs/navmeshcut.html#updateRotationDistance) fields. But you can also control the global frequency of updates. This is explained in the next section. **Control updates through code** Navmesh cuts are applied periodically, but sometimes you may want to ensure the graph is up to date right now. Then you can use the following code. `// Schedule pending updates to be done as soon as the pathfinding threads // are done with what they are currently doing. [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[navmeshUpdates](https://arongranberg.com/astar/docs/astarpath.html#navmeshUpdates) .ForceUpdate(); // Block until the updates have finished [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[FlushGraphUpdates](https://arongranberg.com/astar/docs/astarpath/flushgraphupdates.html#FlushGraphUpdates) (); `You can also control how often the scripts check for if any navmesh cut has changed. If you have a very large number of cuts it may be good for performance to not check it as often. `// Check every frame (the default) [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[navmeshUpdates](https://arongranberg.com/astar/docs/astarpath.html#navmeshUpdates) .updateInterval = 0; // Check every 0.1 seconds [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[navmeshUpdates](https://arongranberg.com/astar/docs/astarpath.html#navmeshUpdates) .updateInterval = 0.1f; // Never check for changes [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[navmeshUpdates](https://arongranberg.com/astar/docs/astarpath.html#navmeshUpdates) .updateInterval = -1; // You will have to schedule updates manually using [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[navmeshUpdates](https://arongranberg.com/astar/docs/astarpath.html#navmeshUpdates) .ForceUpdate(); `You can also find this setting in the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) inspector under Settings. ![](https://arongranberg.com/astar/docs/images/navmeshcut_update_interval@2x.png) **Navmesh cutting and tags/penalties** Navmesh cuts can only preserve tags for updates which happen when the graph is first scanned, or when a recast graph tile is recalculated from scratch. This means that any tags that you apply dynamically using e.g. a [GraphUpdateScene](https://arongranberg.com/astar/docs/graphupdatescene.html) component may be lost when a navmesh cut is applied. If you need to combine tags and navmesh cutting, it is therefore strongly recommended to use the [RecastNavmeshModifier](https://arongranberg.com/astar/docs/recastnavmeshmodifier.html) component to apply the tags, as that will work smoothly with navmesh cutting. Internally, what happens is that when a graph is scanned, the navmesh cutting subsystem takes a snapshot of all triangles in the graph, including tags. This data will then be referenced every time cutting happens and the tags from the snapshot will be copied to the new triangles after cutting has taken place. You can also apply tags and penalties using a graph update after cutting has taken place. For example by subclassing a navmesh cut and overriding the [UsedForCut](https://arongranberg.com/astar/docs/navmeshcut/usedforcut.html#UsedForCut) method. However, it is recommended to use the [RecastNavmeshModifier](https://arongranberg.com/astar/docs/recastnavmeshmodifier.html) as mentioned before, as this is a more robust solution. A\* Pro Feature This is an A\* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A\* Pathfinding Project or the functionality might be limited. The Pro version can be bought [here](http://www.arongranberg.com/astar/buy) See [http://www.arongranberg.com/2013/08/navmesh-cutting/](http://www.arongranberg.com/2013/08/navmesh-cutting/) Version This component is only available in 2022.3 and later, due to Unity bugs in earlier versions. Inner Types ----------- [Contour](https://arongranberg.com/astar/docs/contour.html) [ContourBurst](https://arongranberg.com/astar/docs/contourburst.html) Public Methods -------------- [DrawGizmos](https://arongranberg.com/astar/docs/navmeshcut/drawgizmos.html#DrawGizmos) () [ForceUpdate](https://arongranberg.com/astar/docs/navmeshcut/forceupdate.html#ForceUpdate) () Forces this navmesh cut to update the navmesh. [GetBounds](https://arongranberg.com/astar/docs/navmeshcut/getbounds.html#GetBounds) (inverseTransform, radiusMargin) Bounds of the cut after transforming using the \*inverse\* transform of the **inverseTransform** parameter. [GetContour](https://arongranberg.com/astar/docs/navmeshcut/getcontour.html#GetContour) (buffer, matrix, radiusMargin) [Contour](https://arongranberg.com/astar/docs/contour.html) of the navmesh cut. [GetContourBurst](https://arongranberg.com/astar/docs/navmeshcut/getcontourburst.html#GetContourBurst) (outputVertices, outputContours, matrix, radiusMargin) [Contour](https://arongranberg.com/astar/docs/contour.html) of the navmesh cut. [NotifyUpdated](https://arongranberg.com/astar/docs/navmeshcut/notifyupdated.html#NotifyUpdated) (previousState) Internal method to notify the [NavmeshCut](https://arongranberg.com/astar/docs/navmeshcut.html) that it has just been used to update the navmesh. [RequiresUpdate](https://arongranberg.com/astar/docs/navmeshcut/requiresupdate.html#RequiresUpdate) (previousState) Returns true if this object has moved so much that it requires an update. [UsedForCut](https://arongranberg.com/astar/docs/navmeshcut/usedforcut.html#UsedForCut) () Called whenever this navmesh cut is used to update the navmesh. Public Variables ---------------- center Public ##### [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) center circleRadius Radius of the circle. Public ##### float circleRadius = 1 Radius of the circle. circleResolution Number of vertices on the circle. Public ##### int circleResolution = 6 Number of vertices on the circle. cutsAddedGeom Cuts geometry added by a [NavmeshAdd](https://arongranberg.com/astar/docs/navmeshadd.html) component. Public ##### bool cutsAddedGeom = true Cuts geometry added by a [NavmeshAdd](https://arongranberg.com/astar/docs/navmeshadd.html) component. You rarely need to change this height The cut will be extruded to this height. Public ##### float height = 1 The cut will be extruded to this height. isDual Only makes a split in the navmesh, but does not remove the geometry to make a hole. Public ##### bool isDual Only makes a split in the navmesh, but does not remove the geometry to make a hole. This is slower than a normal cut mesh Custom mesh to use. Public ##### [Mesh](https://docs.unity3d.com/ScriptReference/Mesh.html) mesh Custom mesh to use. The contour(s) of the mesh will be extracted. If you get the "max perturbations" error when cutting with this, check the normals on the mesh. They should all point in the same direction. Try flipping them if that does not help. This mesh should only be a 2D surface, not a volume. meshScale Scale of the custom mesh, if used. Public ##### float meshScale = 1 Scale of the custom mesh, if used. radiusExpansionMode If the cut should be expanded by the agent radius or not. Public ##### [RadiusExpansionMode](https://arongranberg.com/astar/docs/navmeshcut.html#RadiusExpansionMode) radiusExpansionMode = RadiusExpansionMode.ExpandByAgentRadius If the cut should be expanded by the agent radius or not. See [RadiusExpansionMode](https://arongranberg.com/astar/docs/navmeshcut.html#RadiusExpansionMode) for more details. rectangleSize Size of the rectangle. Public ##### [Vector2](https://docs.unity3d.com/ScriptReference/Vector2.html) rectangleSize = new Vector2(1, 1) Size of the rectangle. type Shape of the cut. Public ##### [MeshType](https://arongranberg.com/astar/docs/navmeshcut.html#MeshType) type = MeshType.Box Shape of the cut. updateDistance How much the cut must move before the navmesh is updated. Public ##### float updateDistance = 0.4f How much the cut must move before the navmesh is updated. A smaller distance gives better accuracy, but requires more updates when moving the object over time, so it is often slower. Even if the graph update itself is fast, having a low value can make agents have to recalculate their paths a lot more often, leading to lower performance. updateRotationDistance How many degrees the object must rotate before the navmesh is updated. Public ##### float updateRotationDistance = 10 How many degrees the object must rotate before the navmesh is updated. Should be between 0 and 180. useRotationAndScale Includes rotation and scale in calculations. Public ##### bool useRotationAndScale Includes rotation and scale in calculations. If this is disabled, the object's rotation and scale is not taken into account when determining the shape of the cut. Enabling this is a bit slower, since a lot more matrix multiplications are needed. Public Static Variables ----------------------- GizmoColor Public Static Readonly ##### [Color](https://docs.unity3d.com/ScriptReference/Color.html) GizmoColor = new Color(37.0f/255, 184.0f/255, 239.0f/255) GizmoColor2 Public Static Readonly ##### [Color](https://docs.unity3d.com/ScriptReference/Color.html) GizmoColor2 = new Color(169.0f/255, 92.0f/255, 242.0f/255) Public Enums ------------ MeshType Public ##### MeshType | | | | --- | --- | | Rectangle | A 2D rectangle. | | Circle | A 2D circle. | | CustomMesh | | | Box | A 3D box which will be projected down to a 2D outline. | | Sphere | A 3D sphere which will be projected down to a 2D outline. | | Capsule | A 3D capsule which will be projected down to a 2D outline. | RadiusExpansionMode Public ##### RadiusExpansionMode | | | | --- | --- | | DontExpand | If **DontExpand** is used then the cut will be exactly as specified with no modifications.

It will be the same for all graphs. | | ExpandByAgentRadius | If **ExpandByAgentRadius** is used then the cut will be expanded by the agent's radius (set in the recast graph settings) in every direction.

For navmesh graphs (which do not have a character radius) this is equivalent to **DontExpand**.

This is especially useful if you have multiple graphs for different unit sizes and want the cuts to be sized according to the different units. | Inherited Public Members ------------------------ [AddEnableCallback](https://arongranberg.com/astar/docs/navmeshclipper/addenablecallback.html#AddEnableCallback) (onEnable, onDisable) [RemoveEnableCallback](https://arongranberg.com/astar/docs/navmeshclipper/removeenablecallback.html#RemoveEnableCallback) (onEnable, onDisable) allEnabled All navmesh clipper components in the scene. Public Static ##### List<[NavmeshClipper](https://arongranberg.com/astar/docs/navmeshclipper.html) \> allEnabled All navmesh clipper components in the scene. Not ordered in any particular way. Warning Do not modify this list graphMask Which graphs that are affected by this component. Public ##### [GraphMask](https://arongranberg.com/astar/docs/graphmask.html) graphMask = [GraphMask.everything](https://arongranberg.com/astar/docs/graphmask.html#everything) Which graphs that are affected by this component. You can use this to make a graph ignore a particular navmesh cut altogether. Note that navmesh cuts can only affect navmesh/recast graphs. If you change this field during runtime you must disable the component and enable it again for the changes to be detected. See [NavmeshBase.enableNavmeshCutting](https://arongranberg.com/astar/docs/navmeshbase.html#enableNavmeshCutting) Private/Protected Members ------------------------- [Awake](https://arongranberg.com/astar/docs/navmeshcut/awake.html#Awake) () [CalculateMeshContour](https://arongranberg.com/astar/docs/navmeshcut/calculatemeshcontour.html#CalculateMeshContour) () [ClosestGraph](https://arongranberg.com/astar/docs/navmeshcut/closestgraph.html#ClosestGraph) (position) [OnDisable](https://arongranberg.com/astar/docs/navmeshcut/ondisable.html#OnDisable) () [OnEnable](https://arongranberg.com/astar/docs/navmeshclipper/onenable.html#OnEnable) () [OnUpgradeSerializedData](https://arongranberg.com/astar/docs/navmeshcut/onupgradeserializeddata.html) (migrations, unityThread) [RefreshEnabledList](https://arongranberg.com/astar/docs/navmeshclipper/refreshenabledlist.html#RefreshEnabledList) () Ensures that the list of enabled clippers is up to date. [Reset](https://arongranberg.com/astar/docs/versionedmonobehaviour/reset.html#Reset) () Handle serialization backwards compatibility. [UpgradeSerializedData](https://arongranberg.com/astar/docs/versionedmonobehaviour/upgradeserializedd.html#UpgradeSerializedData) (isUnityThread) contourTransformationMatrix Private ##### [Matrix4x4](https://docs.unity3d.com/ScriptReference/Matrix4x4.html) contourTransformationMatrix edges Cached variable, to avoid allocations. Private Static Readonly ##### Dictionary edges = new Dictionary() Cached variable, to avoid allocations. lastMesh Private ##### [Mesh](https://docs.unity3d.com/ScriptReference/Mesh.html) lastMesh meshContourVertices Private ##### NativeList meshContourVertices meshContours Private ##### NativeList<[ContourBurst](https://arongranberg.com/astar/docs/contourburst.html) \> meshContours pointers Cached variable, to avoid allocations. Private Static Readonly ##### Dictionary pointers = new Dictionary() Cached variable, to avoid allocations. tr cached transform component Protected ##### [Transform](https://docs.unity3d.com/ScriptReference/Transform.html) tr cached transform component --- # AgentMovementPlane - A* Pathfinding Project Struct AgentMovementPlane Extends IComponentData ================================================ Public Holds an agent's movement plane. Public Methods -------------- [AgentMovementPlane](https://arongranberg.com/astar/docs/agentmovementplane/agentmovementplane.html) (...) Public Variables ---------------- value The movement plane for the agent. Public ##### [NativeMovementPlane](https://arongranberg.com/astar/docs/nativemovementplane.html) value The movement plane for the agent. The movement plane determines what the "up" direction of the agent is. For most typical 3D games, this will be aligned with the Y axis, but there are games in which the agent needs to navigate on walls, or on spherical worlds. For those games this movement plane will track the plane in which the agent is currently moving. See [Spherical Worlds](https://arongranberg.com/astar/docs/spherical.html) --- # GraphModifier - A* Pathfinding Project Class GraphModifier Extends [VersionedMonoBehaviour](https://arongranberg.com/astar/docs/versionedmonobehaviour.html) ====================================================================================================================== Public [GraphModifier](https://arongranberg.com/astar/docs/graphmodifier.html) is used for modifying graphs or processing graph data based on events. This class is a simple container for a number of events. ![](https://arongranberg.com/astar/docs/images/graph_events@2x.png) Warning Some events will be called both in play mode **and in editor mode** (at least the scan events). So make sure your code handles both cases well. You may choose to ignore editor events. See Application.IsPlaying Warning Events may be received before Awake and OnEnable has been called on the component. This is because graphs are typically scanned during Awake on the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) component, which may happen before Awake on the graph modifier itself. Public Methods -------------- [OnGraphsPostUpdate](https://arongranberg.com/astar/docs/graphmodifier/ongraphspostupdate.html#OnGraphsPostUpdate) () Called after graphs have been updated using GraphUpdateObjects or navmesh cutting. [OnGraphsPostUpdateBeforeAreaRecalculation](https://arongranberg.com/astar/docs/graphmodifier/ongraphspostupdatebeforeare.html#OnGraphsPostUpdateBeforeAreaRecalculation) () Called after graphs have been updated. [OnGraphsPreUpdate](https://arongranberg.com/astar/docs/graphmodifier/ongraphspreupdate.html#OnGraphsPreUpdate) () Called before graphs are updated using GraphUpdateObjects. [OnLatePostScan](https://arongranberg.com/astar/docs/graphmodifier/onlatepostscan.html#OnLatePostScan) () Called at the end of the scanning procedure. [OnPostCacheLoad](https://arongranberg.com/astar/docs/graphmodifier/onpostcacheload.html#OnPostCacheLoad) () Called after cached graphs have been loaded. [OnPostGraphLoad](https://arongranberg.com/astar/docs/graphmodifier/onpostgraphload.html#OnPostGraphLoad) () Called after a graph has been deserialized and loaded. [OnPostScan](https://arongranberg.com/astar/docs/graphmodifier/onpostscan.html#OnPostScan) () Called right after all graphs have been scanned. [OnPreScan](https://arongranberg.com/astar/docs/graphmodifier/onprescan.html#OnPreScan) () Called right before graphs are going to be scanned. Public Static Methods --------------------- [FindAllModifiers](https://arongranberg.com/astar/docs/graphmodifier/findallmodifiers.html#FindAllModifiers) () [TriggerEvent](https://arongranberg.com/astar/docs/graphmodifier/triggerevent.html#TriggerEvent) (type) Triggers an event for all active graph modifiers. Public Enums ------------ EventType [GraphModifier](https://arongranberg.com/astar/docs/graphmodifier.html) event type. Public ##### EventType | | | | --- | --- | | PostScan= 1 << 0 | | | PreScan= 1 << 1 | | | LatePostScan= 1 << 2 | | | PreUpdate= 1 << 3 | | | PostUpdate= 1 << 4 | | | PostCacheLoad= 1 << 5 | | | PostUpdateBeforeAreaRecalculation= 1 << 6 | | | PostGraphLoad= 1 << 7 | | [GraphModifier](https://arongranberg.com/astar/docs/graphmodifier.html) event type. Private/Protected Members ------------------------- [AddToLinkedList](https://arongranberg.com/astar/docs/graphmodifier/addtolinkedlist.html#AddToLinkedList) () [Awake](https://arongranberg.com/astar/docs/graphmodifier/awake.html#Awake) () [ConfigureUniqueID](https://arongranberg.com/astar/docs/graphmodifier/configureuniqueid.html#ConfigureUniqueID) () [GetModifiersOfType](https://arongranberg.com/astar/docs/graphmodifier/getmodifiersoftype.html#GetModifiersOfType) () [OnDestroy](https://arongranberg.com/astar/docs/graphmodifier/ondestroy.html#OnDestroy) () [OnDisable](https://arongranberg.com/astar/docs/graphmodifier/ondisable.html#OnDisable) () Removes this modifier from list of active modifiers. [OnEnable](https://arongranberg.com/astar/docs/graphmodifier/onenable.html#OnEnable) () Adds this modifier to list of active modifiers. [OnUpgradeSerializedData](https://arongranberg.com/astar/docs/versionedmonobehaviour/onupgradeserialize.html#OnUpgradeSerializedData) (migrations, unityThread) Handle serialization backwards compatibility. [RemoveFromLinkedList](https://arongranberg.com/astar/docs/graphmodifier/removefromlinkedlist.html#RemoveFromLinkedList) () [Reset](https://arongranberg.com/astar/docs/graphmodifier/reset.html#Reset) () Handle serialization backwards compatibility. [UpgradeSerializedData](https://arongranberg.com/astar/docs/versionedmonobehaviour/upgradeserializedd.html#UpgradeSerializedData) (isUnityThread) next Private ##### [GraphModifier](https://arongranberg.com/astar/docs/graphmodifier.html) next prev Private ##### [GraphModifier](https://arongranberg.com/astar/docs/graphmodifier.html) prev root All active graph modifiers. Private Static ##### [GraphModifier](https://arongranberg.com/astar/docs/graphmodifier.html) root All active graph modifiers. uniqueID Unique persistent ID for this component, used for serialization. Protected ##### ulong uniqueID Unique persistent ID for this component, used for serialization. usedIDs Maps persistent IDs to the component that uses it. Protected Static ##### Dictionary usedIDs = new Dictionary() Maps persistent IDs to the component that uses it. --- # OffMeshLinks - A* Pathfinding Project Class OffMeshLinks ================== Public Manager for off-mesh links. This manager tracks all active off-mesh links in the scene and recalculates them when needed. If an off-mesh link is activated, a [LinkGraph](https://arongranberg.com/astar/docs/linkgraph.html) will also be added to the graph list to store the special nodes necessary for the links to work. Whenever a graph update happens, the [DirtyBounds](https://arongranberg.com/astar/docs/offmeshlinks/dirtybounds.html#DirtyBounds) method should be called with the bounds of the updated area. This will cause the links touching that bounding box to be recalculated at the end of the graph update step. Typically you will not need to interact with this class yourself, instead you can use the pre-built components like [NodeLink2](https://arongranberg.com/astar/docs/nodelink2.html) . Inner Types ----------- [Anchor](https://arongranberg.com/astar/docs/anchor.html) The start or end point of an off-mesh link. [OffMeshLinkCombined](https://arongranberg.com/astar/docs/offmeshlinkcombined.html) [OffMeshLinkConcrete](https://arongranberg.com/astar/docs/offmeshlinkconcrete.html) [OffMeshLinkSource](https://arongranberg.com/astar/docs/offmeshlinksource.html) [OffMeshLinkTracer](https://arongranberg.com/astar/docs/offmeshlinktracer.html) Information about an off-mesh link. Public Methods -------------- [Add](https://arongranberg.com/astar/docs/offmeshlinks/add.html#Add) (link) Adds a new off-mesh link. [ConnectedGraphs](https://arongranberg.com/astar/docs/offmeshlinks/connectedgraphs.html#ConnectedGraphs) (link) Get all graphs that this link is connected to. [Dirty](https://arongranberg.com/astar/docs/offmeshlinks/dirty.html#Dirty) (link) Mark a link as dirty. [DirtyBounds](https://arongranberg.com/astar/docs/offmeshlinks/dirtybounds.html#DirtyBounds) (bounds) Mark links touching the given bounds as dirty. [GetNearest](https://arongranberg.com/astar/docs/offmeshlinks/getnearest.html#GetNearest) (point, maxDistance) Get the nearest link to a point. [OffMeshLinks](https://arongranberg.com/astar/docs/offmeshlinks/offmeshlinks.html#OffMeshLinks) (astar) [Remove](https://arongranberg.com/astar/docs/offmeshlinks/remove.html#Remove) (link) Removes an existing off-mesh link. Public Enums ------------ Directionality Determines how a link is connected in the graph. Public ##### Directionality | | | | --- | --- | | OneWay | Movement is only allowed from the start point to the end point. | | TwoWay | Movement is allowed in both directions. | Determines how a link is connected in the graph. OffMeshLinkStatus Public ##### OffMeshLinkStatus | | | | --- | --- | | Inactive= 1 << 0 | | | Pending= 1 << 1 | | | Active= 1 << 2 | | | FailedToConnectStart= Inactive \| 1 << 3 | | | FailedToConnectEnd= Inactive \| 1 << 4 | | | PendingRemoval= 1 << 5 | | Private/Protected Members ------------------------- [ClampSegment](https://arongranberg.com/astar/docs/offmeshlinks/clampsegment.html#ClampSegment) (anchor, graphMask, maxSnappingDistance, result, nodes) [DirtyNoSchedule](https://arongranberg.com/astar/docs/offmeshlinks/dirtynoschedule.html#DirtyNoSchedule) (link) [OnDisable](https://arongranberg.com/astar/docs/offmeshlinks/ondisable.html#OnDisable) () [Refresh](https://arongranberg.com/astar/docs/offmeshlinks/refresh.html#Refresh) () [ScheduleUpdate](https://arongranberg.com/astar/docs/offmeshlinks/scheduleupdate.html#ScheduleUpdate) () astar Private ##### [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) astar pendingAdd Private ##### List<[OffMeshLinkSource](https://arongranberg.com/astar/docs/offmeshlinksource.html) \> pendingAdd = new List<[OffMeshLinkSource](https://arongranberg.com/astar/docs/offmeshlinksource.html) \>() tree Private ##### [AABBTree](https://arongranberg.com/astar/docs/aabbtree.html) <[OffMeshLinkCombined](https://arongranberg.com/astar/docs/offmeshlinkcombined.html) \> tree = new [AABBTree](https://arongranberg.com/astar/docs/aabbtree.html) <[OffMeshLinkCombined](https://arongranberg.com/astar/docs/offmeshlinkcombined.html) \>() updateScheduled Private ##### bool updateScheduled --- # Progress - A* Pathfinding Project Struct Progress =============== Public [Progress](https://arongranberg.com/astar/docs/progress.html) info for e.g a progressbar. Used by the scan functions in the project See [AstarPath.ScanAsync](https://arongranberg.com/astar/docs/astarpath/scanasync.html#ScanAsync) Public Methods -------------- [MapTo](https://arongranberg.com/astar/docs/progress/mapto.html#MapTo) (min, max) [Progress](https://arongranberg.com/astar/docs/progress/progress.html#Progress) (progress, stage, graphIndex=0, graphCount=0) [ToString](https://arongranberg.com/astar/docs/progress/tostring.html#ToString) () Public Variables ---------------- progress Current progress as a value between 0 and 1. Public Readonly ##### float progress Current progress as a value between 0 and 1. Private/Protected Members ------------------------- graphCount Internal Readonly ##### int graphCount graphIndex Internal Readonly ##### int graphIndex stage Internal Readonly ##### [ScanningStage](https://arongranberg.com/astar/docs/pathfinding.html#ScanningStage) stage --- # AgentMovementPlaneSource - A* Pathfinding Project Struct AgentMovementPlaneSource Extends ISharedComponentData ============================================================ Public The movement plane source for an agent. See [MovementPlaneSource](https://arongranberg.com/astar/docs/ecs2.html#MovementPlaneSource) Public Variables ---------------- value Public ##### [MovementPlaneSource](https://arongranberg.com/astar/docs/ecs2.html#MovementPlaneSource) value --- # AgentOffMeshLinkLocalAvoidanceDisabled - A* Pathfinding Project Struct AgentOffMeshLinkLocalAvoidanceDisabled Extends IComponentData, IEnableableComponent ========================================================================================== Public Component which is enabled when the agent is traversing an off-mesh link, and the local avoidance logic should be disabled. You can toggle this using [AgentOffMeshLinkTraversalContext.DisableLocalAvoidance](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext/disablel.html#DisableLocalAvoidance) . This component is added to the agent when it starts traversing an off-mesh link. The enabled/disabled state is managed by [JobManagedOffMeshLinkTransition](https://arongranberg.com/astar/docs/jobmanagedoffmeshlinktransition.html) . --- # PathHandler - A* Pathfinding Project Class PathHandler ================= Public Handles thread specific path data. Public Methods -------------- [AddTemporaryNode](https://arongranberg.com/astar/docs/pathhandler/addtemporarynode.html#AddTemporaryNode) (node) Add a new temporary node for this path request. [ClearPathIDs](https://arongranberg.com/astar/docs/pathhandler/clearpathids.html#ClearPathIDs) () Set all nodes' pathIDs to 0. [Dispose](https://arongranberg.com/astar/docs/pathhandler/dispose.html#Dispose) () [GetNode](https://arongranberg.com/astar/docs/pathhandler/getnode.html#GetNode) (nodeIndex) [GetPathNode](https://arongranberg.com/astar/docs/pathhandler/getpathnode.html#GetPathNode) (node, variant=0) Returns the [PathNode](https://arongranberg.com/astar/docs/pathnode.html) corresponding to the specified node. [GetTemporaryNode](https://arongranberg.com/astar/docs/pathhandler/gettemporarynode.html#GetTemporaryNode) (nodeIndex) [InitializeForPath](https://arongranberg.com/astar/docs/pathhandler/initializeforpath.html#InitializeForPath) (p) [IsTemporaryNode](https://arongranberg.com/astar/docs/pathhandler/istemporarynode.html#IsTemporaryNode) (pathNodeIndex) [LogVisitedNode](https://arongranberg.com/astar/docs/pathhandler/logvisitednode.html#LogVisitedNode) (pathNodeIndex, h, g) Public Variables ---------------- DebugStringBuilder StringBuilder that paths can use to build debug strings. Public Readonly ##### System.Text.StringBuilder DebugStringBuilder = new System.Text.StringBuilder() StringBuilder that paths can use to build debug strings. Better for performance and memory usage to use a single StringBuilder instead of each path creating its own PathID ID for the path currently being calculated or last path that was calculated. Public ##### ushort PathID ID for the path currently being calculated or last path that was calculated. heap Binary heap to keep track of nodes on the "Open list". Public ##### [BinaryHeap](https://arongranberg.com/astar/docs/binaryheap.html) heap = new [BinaryHeap](https://arongranberg.com/astar/docs/binaryheap.html) (128) Binary heap to keep track of nodes on the "Open list". See [https://en.wikipedia.org/wiki/A](https://en.wikipedia.org/wiki/A) \*\_search\_algorithm numTemporaryNodes Public ##### int numTemporaryNodes pathNodes Reference to the per-node data for this thread. Public ##### [UnsafeSpan](https://arongranberg.com/astar/docs/unsafespan.html) <[PathNode](https://arongranberg.com/astar/docs/pathnode.html) \> pathNodes Reference to the per-node data for this thread. Note Only guaranteed to point to a valid allocation while the path is being calculated. Be careful when storing copies of this array, as it may be re-allocated by the AddTemporaryNode method. temporaryNodeStartIndex All path nodes with an index greater or equal to this are temporary nodes that only exist for the duration of a single path. Public ##### uint temporaryNodeStartIndex All path nodes with an index greater or equal to this are temporary nodes that only exist for the duration of a single path. This is a copy of NodeStorage.nextNodeIndex. This is used to avoid having to access the NodeStorage while pathfinding as it's an extra indirection. threadID Public Readonly ##### int threadID totalThreadCount Public Readonly ##### int totalThreadCount Private/Protected Members ------------------------- [PathHandler](https://arongranberg.com/astar/docs/pathhandler/pathhandler.html#PathHandler) (nodeStorage, threadID, totalThreadCount) debugPathNodes Private ##### [UnsafeSpan](https://arongranberg.com/astar/docs/unsafespan.html) <[GlobalNodeStorage.DebugPathNode](https://arongranberg.com/astar/docs/debugpathnode.html) \> debugPathNodes nodeStorage Internal Readonly ##### [GlobalNodeStorage](https://arongranberg.com/astar/docs/globalnodestorage.html) nodeStorage pathID Current PathID. Private ##### ushort pathID Current PathID. See [PathID](https://arongranberg.com/astar/docs/pathhandler.html#PathID) temporaryNodes Private ##### [UnsafeSpan](https://arongranberg.com/astar/docs/unsafespan.html) <[TemporaryNode](https://arongranberg.com/astar/docs/temporarynode.html) \> temporaryNodes --- # AgentOffMeshLinkMovementDisabled - A* Pathfinding Project Struct AgentOffMeshLinkMovementDisabled Extends IComponentData, IEnableableComponent ==================================================================================== Public Component which is enabled when the agent is traversing an off-mesh link, and the built-in movement logic should be disabled. You can toggle this using [AgentOffMeshLinkTraversalContext.enableBuiltInMovement](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext.html#enableBuiltInMovement) . This component is added to the agent when it starts traversing an off-mesh link. The enabled/disabled state is managed by [JobManagedOffMeshLinkTransition](https://arongranberg.com/astar/docs/jobmanagedoffmeshlinktransition.html) . --- # ECS - A* Pathfinding Project Namespace ECS ============= Namespaces ---------- [RVO](https://arongranberg.com/astar/docs/rvo.html) Classes ------- [AgentCylinderShape](https://arongranberg.com/astar/docs/agentcylindershape.html) An agent's shape represented as a cylinder. [AgentMovementPlane](https://arongranberg.com/astar/docs/agentmovementplane.html) Holds an agent's movement plane. [AgentMovementPlaneSource](https://arongranberg.com/astar/docs/agentmovementplanesource.html) The movement plane source for an agent. [AgentOffMeshLinkLocalAvoidanceDisabled](https://arongranberg.com/astar/docs/agentoffmeshlinklocalavoidancedisabled.html) Component which is enabled when the agent is traversing an off-mesh link, and the local avoidance logic should be disabled. [AgentOffMeshLinkMovementDisabled](https://arongranberg.com/astar/docs/agentoffmeshlinkmovementdisabled.html) Component which is enabled when the agent is traversing an off-mesh link, and the built-in movement logic should be disabled. [AgentOffMeshLinkTraversal](https://arongranberg.com/astar/docs/agentoffmeshlinktraversal.html) Holds unmanaged information about an off-mesh link that the agent is currently traversing. [AgentOffMeshLinkTraversalContext](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext.html) Context with helpers for traversing an off-mesh link. [AgentShouldRecalculatePath](https://arongranberg.com/astar/docs/agentshouldrecalculatepath.html) Tag component which, when enabled, indicates that the agent should recalculate its path immediately. [AIGizmosSystem](https://arongranberg.com/astar/docs/aigizmossystem.html) Draws gizmos and debug information for [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) agents. [AIMovementSystemGroup](https://arongranberg.com/astar/docs/aimovementsystemgroup.html) [AIMoveSystem](https://arongranberg.com/astar/docs/aimovesystem.html) [AutoRepathPolicy](https://arongranberg.com/astar/docs/autorepathpolicy2.html) Policy for how often to recalculate an agent's path. [ComponentRef](https://arongranberg.com/astar/docs/componentref.html) Wrapper for a pointer. [DestinationEntity](https://arongranberg.com/astar/docs/destinationentity.html) Holds an agent's destination as an entity. [DestinationEntitySystem](https://arongranberg.com/astar/docs/destinationentitysystem.html) System that updates the destination of agents with a [DestinationEntity](https://arongranberg.com/astar/docs/destinationentity.html) component. [DestinationMoveInCircleSystem](https://arongranberg.com/astar/docs/destinationmoveincirclesystem.html) System that updates the destination of agents with a [DestinationMoveInCircle](https://arongranberg.com/astar/docs/destinationmoveincircle.html) component. [DestinationPoint](https://arongranberg.com/astar/docs/destinationpoint.html) Holds an agent's destination point. [DrawGizmosJobUtils](https://arongranberg.com/astar/docs/drawgizmosjobutils.html) [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) Utility for efficient random access to entity component data from the main thread. [EntityAccessHelper](https://arongranberg.com/astar/docs/entityaccesshelper.html) Helper for [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) . [EntityStorageCache](https://arongranberg.com/astar/docs/entitystoragecache.html) Utility for efficient random access to entity storage data from the main thread. [FallbackResolveMovementSystem](https://arongranberg.com/astar/docs/fallbackresolvemovementsystem.html) Copies [MovementControl](https://arongranberg.com/astar/docs/movementcontrol.html) to [ResolvedMovement](https://arongranberg.com/astar/docs/resolvedmovement.html) when no local avoidance is used. [FollowerControlSystem](https://arongranberg.com/astar/docs/followercontrolsystem.html) [FollowerEntityProxy](https://arongranberg.com/astar/docs/followerentityproxy.html) Proxy for a [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) using pure [ECS](https://arongranberg.com/astar/docs/ecs2.html) components. [GravityState](https://arongranberg.com/astar/docs/gravitystate.html) Agent state related to gravity. [InitManagedStateSystem](https://arongranberg.com/astar/docs/initmanagedstatesystem.html) Creates a [ManagedState](https://arongranberg.com/astar/docs/managedstate.html) component for every entity with a [ManagedSettings](https://arongranberg.com/astar/docs/managedsettings.html) component. [JobAlignAgentWithMovementDirection](https://arongranberg.com/astar/docs/jobalignagentwithmovementdirection.html) Aligns the agent's rotation with its movement direction, if the local avoidance system is causing it to move differently than expected. [JobApplyGravity](https://arongranberg.com/astar/docs/jobapplygravity.html) [JobClearTemporaryData](https://arongranberg.com/astar/docs/jobcleartemporarydata.html) [JobControl](https://arongranberg.com/astar/docs/jobcontrol.html) [JobDrawFollowerGizmos](https://arongranberg.com/astar/docs/jobdrawfollowergizmos.html) [JobDrawFollowerGizmosBase](https://arongranberg.com/astar/docs/jobdrawfollowergizmosbase.html) [JobManagedMovementOverrideAfterControl](https://arongranberg.com/astar/docs/jobmanagedmovementoverrideaftercontrol.html) [JobManagedMovementOverrideBeforeControl](https://arongranberg.com/astar/docs/jobmanagedmovementoverridebeforecontrol.html) [JobManagedMovementOverrideBeforeMovement](https://arongranberg.com/astar/docs/jobmanagedmovementoverridebeforemovement.html) [JobManagedOffMeshLinkTransition](https://arongranberg.com/astar/docs/jobmanagedoffmeshlinktransition.html) [JobManagedOffMeshLinkTransitionCleanup](https://arongranberg.com/astar/docs/jobmanagedoffmeshlinktransitioncleanup.html) [JobMoveAgent](https://arongranberg.com/astar/docs/jobmoveagent.html) [JobPrepareAgentRaycasts](https://arongranberg.com/astar/docs/jobprepareagentraycasts.html) [JobRepairPath](https://arongranberg.com/astar/docs/jobrepairpath.html) Repairs the path of agents. [JobRepairPathHelpers](https://arongranberg.com/astar/docs/jobrepairpathhelpers.html) [JobStartOffMeshLinkTransition](https://arongranberg.com/astar/docs/jobstartoffmeshlinktransition.html) [JobSyncEntitiesToTransforms](https://arongranberg.com/astar/docs/jobsyncentitiestotransforms.html) [JobUpdateMovementStatistics](https://arongranberg.com/astar/docs/jobupdatemovementstatistics.html) [LateSyncSystem](https://arongranberg.com/astar/docs/latesyncsystem.html) System that runs after all movement systems and repairs the agent's path and syncs its orientation to the associated Transform component, if one exists. [ManagedAgentOffMeshLinkTraversal](https://arongranberg.com/astar/docs/managedagentoffmeshlinktraversal.html) Holds managed information about an off-mesh link that the agent is currently traversing. [ManagedEntityAccess](https://arongranberg.com/astar/docs/managedentityaccess.html) Utility for efficient random access to managed entity component data from the main thread. [ManagedMovementOverride](https://arongranberg.com/astar/docs/managedmovementoverride.html) Component that stores a delegate that can be used to override movement control and movement settings for a specific entity. [ManagedMovementOverrideAfterControl](https://arongranberg.com/astar/docs/managedmovementoverrideaftercontrol.html) [ManagedMovementOverrideBeforeControl](https://arongranberg.com/astar/docs/managedmovementoverridebeforecontrol.html) [ManagedMovementOverrideBeforeMovement](https://arongranberg.com/astar/docs/managedmovementoverridebeforemovement.html) [ManagedMovementOverrides](https://arongranberg.com/astar/docs/managedmovementoverrides.html) Helper for adding and removing hooks to the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component. [ManagedSettings](https://arongranberg.com/astar/docs/managedsettings.html) Settings for agent movement that require managed types. [ManagedState](https://arongranberg.com/astar/docs/managedstate.html) Runtime state for agent movement that requires managed types. [MovementControl](https://arongranberg.com/astar/docs/movementcontrol.html) Desired movement for an agent. [MovementPlaneFromGraphSystem](https://arongranberg.com/astar/docs/movementplanefromgraphsystem.html) [MovementSettings](https://arongranberg.com/astar/docs/movementsettings.html) [MovementState](https://arongranberg.com/astar/docs/movementstate.html) [MovementStatistics](https://arongranberg.com/astar/docs/movementstatistics.html) [MovementStatisticsSystem](https://arongranberg.com/astar/docs/movementstatisticssystem.html) System that updates the destination of agents with a [DestinationEntity](https://arongranberg.com/astar/docs/destinationentity.html) component. [MovementTarget](https://arongranberg.com/astar/docs/movementtarget.html) [OrientationYAxisForward](https://arongranberg.com/astar/docs/orientationyaxisforward.html) Tag component to indicate that the agent's forward direction is along the Y axis. [PhysicsSceneRef](https://arongranberg.com/astar/docs/physicssceneref.html) The physics scene to use for raycasting. [PollPendingPathsSystem](https://arongranberg.com/astar/docs/pollpendingpathssystem.html) Checks if paths have been calculated, and updates the agent's paths if they have. [ReadyToTraverseOffMeshLink](https://arongranberg.com/astar/docs/readytotraverseoffmeshlink.html) Enabled if the agnet is ready to start traversing an off-mesh link. [RepairPathSystem](https://arongranberg.com/astar/docs/repairpathsystem.html) [ResolvedMovement](https://arongranberg.com/astar/docs/resolvedmovement.html) Holds the final movement data for an entity. [SchedulePathSearchSystem](https://arongranberg.com/astar/docs/schedulepathsearchsystem.html) [SearchState](https://arongranberg.com/astar/docs/searchstate.html) [SimulateMovement](https://arongranberg.com/astar/docs/simulatemovement.html) Tag component to enable movement for an entity. [SimulateMovementControl](https://arongranberg.com/astar/docs/simulatemovementcontrol.html) Tag component to allow the agent to calculate how it wants to move. [SimulateMovementFinalize](https://arongranberg.com/astar/docs/simulatemovementfinalize.html) Tag component to allow the agent to move according to its desired movement parameters. [SimulateMovementRepair](https://arongranberg.com/astar/docs/simulatemovementrepair.html) Tag component to allow the agent to repair its path and recalculate various statistics. [SyncDestinationTransformSystem](https://arongranberg.com/astar/docs/syncdestinationtransformsystem.html) [SyncPositionWithTransform](https://arongranberg.com/astar/docs/syncpositionwithtransform.html) Tag component to enable syncing between an agent's Transform and the agent entity's position. [SyncRotationWithTransform](https://arongranberg.com/astar/docs/syncrotationwithtransform.html) Tag component to enable syncing between an agent's Transform and the agent entity's rotation. [SyncTransformsToEntitiesSystem](https://arongranberg.com/astar/docs/synctransformstoentitiessystem.html) [TraverseOffMeshLinkSystem](https://arongranberg.com/astar/docs/traverseoffmeshlinksystem.html) Public Methods -------------- AfterControlDelegate (entity, dt, localTransform, shape, movementPlane, destination, movementState, movementSettings, movementControl) ##### delegate void AfterControlDelegate ( | | | | | --- | --- | --- | | Entity | entity | | | float | dt | | | ref LocalTransform | localTransform | | | ref[AgentCylinderShape](https://arongranberg.com/astar/docs/agentcylindershape.html) | shape | | | ref[AgentMovementPlane](https://arongranberg.com/astar/docs/agentmovementplane.html) | movementPlane | | | ref[DestinationPoint](https://arongranberg.com/astar/docs/destinationpoint.html) | destination | | | ref[MovementState](https://arongranberg.com/astar/docs/movementstate.html) | movementState | | | ref[MovementSettings](https://arongranberg.com/astar/docs/movementsettings.html) | movementSettings | | | ref[MovementControl](https://arongranberg.com/astar/docs/movementcontrol.html) | movementControl | | ) BeforeControlDelegate (entity, dt, localTransform, shape, movementPlane, destination, movementState, movementSettings) ##### delegate void BeforeControlDelegate ( | | | | | --- | --- | --- | | Entity | entity | | | float | dt | | | ref LocalTransform | localTransform | | | ref[AgentCylinderShape](https://arongranberg.com/astar/docs/agentcylindershape.html) | shape | | | ref[AgentMovementPlane](https://arongranberg.com/astar/docs/agentmovementplane.html) | movementPlane | | | ref[DestinationPoint](https://arongranberg.com/astar/docs/destinationpoint.html) | destination | | | ref[MovementState](https://arongranberg.com/astar/docs/movementstate.html) | movementState | | | ref[MovementSettings](https://arongranberg.com/astar/docs/movementsettings.html) | movementSettings | | ) BeforeMovementDelegate (entity, dt, localTransform, shape, movementPlane, destination, movementState, movementSettings, movementControl, resolvedMovement) ##### delegate void BeforeMovementDelegate ( | | | | | --- | --- | --- | | Entity | entity | | | float | dt | | | ref LocalTransform | localTransform | | | ref[AgentCylinderShape](https://arongranberg.com/astar/docs/agentcylindershape.html) | shape | | | ref[AgentMovementPlane](https://arongranberg.com/astar/docs/agentmovementplane.html) | movementPlane | | | ref[DestinationPoint](https://arongranberg.com/astar/docs/destinationpoint.html) | destination | | | ref[MovementState](https://arongranberg.com/astar/docs/movementstate.html) | movementState | | | ref[MovementSettings](https://arongranberg.com/astar/docs/movementsettings.html) | movementSettings | | | ref[MovementControl](https://arongranberg.com/astar/docs/movementcontrol.html) | movementControl | | | ref[ResolvedMovement](https://arongranberg.com/astar/docs/resolvedmovement.html) | resolvedMovement | | ) Public Enums ------------ MovementPlaneSource How to calculate which direction is "up" for the agent. ##### MovementPlaneSource | | | | --- | --- | | Graph | The graph's natural up direction will be used to align the agent.

This is the most common option. | | NavmeshNormal | The agent will be aligned with the normal of the navmesh.

This is useful when you have a spherical world, or some other strange shape.

The agent will look at the normal of the navmesh around the point it is currently standing on to determine which way is up. The radius of the agent will be used to determine the size of the area to sample the normal from. A bit of smoothing is done to make sure sharp changes in the normal do not cause the agent to rotate too fast.

Note

If you have a somewhat flat world, and you want to align the agent to the ground, this is not the option you want. Instead, you might want to disable [FollowerEntity.updateRotation](https://arongranberg.com/astar/docs/followerentity.html#updateRotation)
and then align the transform using a custom script.

Warning

Using this option has a performance penalty.

Your browser does not support the video tag.

See

[Spherical Worlds](https://arongranberg.com/astar/docs/spherical.html) | | Raycast | The agent will be aligned with the ground normal.

This is useful when you have a spherical world, or some other strange shape.

You may want to use this instead of the **NavmeshNormal** option if your collider is smoother than your navmesh. For example, if you have a spherical world with a sphere collider, you may want to use this option instead of the **NavmeshNormal** option.

Note

If you have a somewhat flat world, and you want to align the agent to the ground, this is not the option you want. Instead, you might want to disable [FollowerEntity.updateRotation](https://arongranberg.com/astar/docs/followerentity.html#updateRotation)
and then align the transform using a custom script.

Warning

Using this option has a performance penalty. | How to calculate which direction is "up" for the agent. --- # RWLock - A* Pathfinding Project Class RWLock ============ Public A simple read/write lock for use with the Unity Job System. The RW-lock makes the following assumptions: * Only the main thread will call the methods on this lock. * If jobs are to use locked data, you should call [Read](https://arongranberg.com/astar/docs/rwlock/read.html#Read) or [Write](https://arongranberg.com/astar/docs/rwlock/write.html#Write) on the lock and pass the returned JobHandle as a dependency the job, and then call [WriteLockAsync.UnlockAfter](https://arongranberg.com/astar/docs/writelockasync/unlockafter.html#UnlockAfter) on the lock object, with the newly scheduled job's handle. * When taking a Read lock, you should only read data, but if you take a Write lock you may modify data. * On the main thread, multiple synchronous write locks may be nested. You do not need to care about dependencies when calling the [ReadSync](https://arongranberg.com/astar/docs/rwlock/readsync.html#ReadSync) and [WriteSync](https://arongranberg.com/astar/docs/rwlock/writesync.html#WriteSync) methods. That's handled automatically for you. See [https://en.wikipedia.org/wiki/Readers%E2%80%93writer\_lock](https://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock) `var readLock = [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) .[active](https://arongranberg.com/astar/docs/astarpath.html#active) .[LockGraphDataForReading](https://arongranberg.com/astar/docs/astarpath/lockgraphdataforreading.html#LockGraphDataForReading) (); var handle = new MyJob { // ... }.Schedule(readLock.dependency); readLock.[UnlockAfter](https://arongranberg.com/astar/docs/readlockasync/unlockafter.html#UnlockAfter) (handle); ` Inner Types ----------- [CombinedReadLockAsync](https://arongranberg.com/astar/docs/combinedreadlockasync.html) [LockSync](https://arongranberg.com/astar/docs/locksync.html) [ReadLockAsync](https://arongranberg.com/astar/docs/readlockasync.html) [WriteLockAsync](https://arongranberg.com/astar/docs/writelockasync.html) Public Methods -------------- [Read](https://arongranberg.com/astar/docs/rwlock/read.html#Read) () Aquire a read lock on the main thread. [ReadSync](https://arongranberg.com/astar/docs/rwlock/readsync.html#ReadSync) () Aquire a read lock on the main thread. [Write](https://arongranberg.com/astar/docs/rwlock/write.html#Write) () Aquire a write lock on the main thread. [WriteSync](https://arongranberg.com/astar/docs/rwlock/writesync.html#WriteSync) () Aquire a write lock on the main thread. Private/Protected Members ------------------------- [AddPendingAsync](https://arongranberg.com/astar/docs/rwlock/addpendingasync.html#AddPendingAsync) () [AddPendingSync](https://arongranberg.com/astar/docs/rwlock/addpendingsync.html#AddPendingSync) () [RemovePendingAsync](https://arongranberg.com/astar/docs/rwlock/removependingasync.html#RemovePendingAsync) () [RemovePendingSync](https://arongranberg.com/astar/docs/rwlock/removependingsync.html#RemovePendingSync) () lastRead Private ##### JobHandle lastRead lastWrite Private ##### JobHandle lastWrite --- # GraphUpdateProcessor - A* Pathfinding Project Class GraphUpdateProcessor ========================== Public Public Methods -------------- [AddToQueue](https://arongranberg.com/astar/docs/graphupdateprocessor/addtoqueue.html#AddToQueue) (ob) Update all graphs using the [GraphUpdateObject](https://arongranberg.com/astar/docs/graphupdateobject.html) . [DiscardQueued](https://arongranberg.com/astar/docs/graphupdateprocessor/discardqueued.html#DiscardQueued) () Discards all queued graph updates. [GetWorkItem](https://arongranberg.com/astar/docs/graphupdateprocessor/getworkitem.html#GetWorkItem) () Work item which can be used to apply all queued updates. [GraphUpdateProcessor](https://arongranberg.com/astar/docs/graphupdateprocessor/graphupdateprocessor.html#GraphUpdateProcessor) (astar) Public Static Methods --------------------- [ApplyGraphUpdatePromises](https://arongranberg.com/astar/docs/graphupdateprocessor/applygraphupdateprom.html#ApplyGraphUpdatePromises) (promises, context) [PrepareGraphUpdatePromises](https://arongranberg.com/astar/docs/graphupdateprocessor/preparegraphupdatepr.html#PrepareGraphUpdatePromises) (promises, timeSlice) [ProcessGraphUpdatePromises](https://arongranberg.com/astar/docs/graphupdateprocessor/processgraphupdatepr.html#ProcessGraphUpdatePromises) (promises, context, timeSlice) Public Variables ---------------- IsAnyGraphUpdateInProgress Returns if any graph updates are in progress. Public ##### bool IsAnyGraphUpdateInProgress Returns if any graph updates are in progress. IsAnyGraphUpdateQueued Returns if any graph updates are waiting to be applied. Public ##### bool IsAnyGraphUpdateQueued Returns if any graph updates are waiting to be applied. Private/Protected Members ------------------------- MarkerApply Private Static Readonly ##### ProfilerMarker MarkerApply = new ProfilerMarker("Applying Graph Update") MarkerCalculate Private Static Readonly ##### ProfilerMarker MarkerCalculate = new ProfilerMarker("Calculating Graph Update") MarkerSleep Private Static Readonly ##### ProfilerMarker MarkerSleep = new ProfilerMarker(ProfilerCategory.Loading, "Sleep") [ProcessGraphUpdates](https://arongranberg.com/astar/docs/graphupdateprocessor/processgraphupdates.html#ProcessGraphUpdates) (context, force) Updates graphs. [QueueGraphUpdatesInternal](https://arongranberg.com/astar/docs/graphupdateprocessor/queuegraphupdatesint.html#QueueGraphUpdatesInternal) (context) Schedules graph updates internally. anyGraphUpdateInProgress Used for IsAnyGraphUpdateInProgress. Private ##### bool anyGraphUpdateInProgress Used for IsAnyGraphUpdateInProgress. astar Holds graphs that can be updated. Private Readonly ##### [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) astar Holds graphs that can be updated. graphUpdateQueue Queue containing all waiting graph update queries. Private Readonly ##### Queue<[GraphUpdateObject](https://arongranberg.com/astar/docs/graphupdateobject.html) \> graphUpdateQueue = new Queue<[GraphUpdateObject](https://arongranberg.com/astar/docs/graphupdateobject.html) \>() Queue containing all waiting graph update queries. Add to this queue by using [AddToQueue](https://arongranberg.com/astar/docs/graphupdateprocessor/addtoqueue.html#AddToQueue) . See [AddToQueue](https://arongranberg.com/astar/docs/graphupdateprocessor/addtoqueue.html#AddToQueue) pendingGraphUpdates Private Readonly ##### List<[GraphUpdateObject](https://arongranberg.com/astar/docs/graphupdateobject.html) \> pendingGraphUpdates = new List<[GraphUpdateObject](https://arongranberg.com/astar/docs/graphupdateobject.html) \>() pendingPromises Private Readonly ##### List<([IGraphUpdatePromise](https://arongranberg.com/astar/docs/igraphupdatepromise.html) , IEnumerator)> pendingPromises = new List<([IGraphUpdatePromise](https://arongranberg.com/astar/docs/igraphupdatepromise.html) , IEnumerator)>() --- # AgentOffMeshLinkTraversal - A* Pathfinding Project Struct AgentOffMeshLinkTraversal Extends IComponentData ======================================================= Public Holds unmanaged information about an off-mesh link that the agent is currently traversing. This component is added to the agent when it starts traversing an off-mesh link. It is removed when the agent has finished traversing the link. See [ManagedAgentOffMeshLinkTraversal](https://arongranberg.com/astar/docs/managedagentoffmeshlinktraversal.html) Public Methods -------------- [AgentOffMeshLinkTraversal](https://arongranberg.com/astar/docs/agentoffmeshlinktraversal/agentoffmeshlin.html#AgentOffMeshLinkTraversal) (linkInfo) Public Variables ---------------- isReverse True if the agent is traversing the off-mesh link from original link's end to its start point. Public ##### bool isReverse True if the agent is traversing the off-mesh link from original link's end to its start point. Note The [relativeStart](https://arongranberg.com/astar/docs/offmeshlinktracer.html#relativeStart) and [relativeEnd](https://arongranberg.com/astar/docs/offmeshlinktracer.html#relativeEnd) fields are always set from the agent's perspective. So the agent always moves from [relativeStart](https://arongranberg.com/astar/docs/offmeshlinktracer.html#relativeStart) to [relativeEnd](https://arongranberg.com/astar/docs/offmeshlinktracer.html#relativeEnd) . relativeEnd The end point of the off-mesh link from the agent's perspective. Public ##### float3 relativeEnd The end point of the off-mesh link from the agent's perspective. This is the point where the agent will finish traversing the off-mesh link, regardless of if the link is traversed from start to end or from end to start. relativeStart The start point of the off-mesh link from the agent's perspective. Public ##### float3 relativeStart The start point of the off-mesh link from the agent's perspective. This is the point where the agent starts traversing the off-mesh link, regardless of if the link is traversed from the start to end or from end to start. Deprecated Members ------------------ firstPosition The start point of the off-mesh link from the agent's perspective. Public ##### float3 firstPosition The start point of the off-mesh link from the agent's perspective. This is the point where the agent starts traversing the off-mesh link, regardless of if the link is traversed from the start to end or from end to start. Deprecated Use relativeStart instead secondPosition The end point of the off-mesh link from the agent's perspective. Public ##### float3 secondPosition The end point of the off-mesh link from the agent's perspective. This is the point where the agent will finish traversing the off-mesh link, regardless of if the link is traversed from start to end or from end to start. Deprecated Use relativeEnd instead --- # AbortOffMeshLinkTraversal - A* Pathfinding Project Class AbortOffMeshLinkTraversal Extends Exception ================================================= Public Thrown when the off-mesh link traversal should be aborted. See [AgentOffMeshLinkTraversalContext.Abort](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext/abort.html#Abort) --- # AgentShouldRecalculatePath - A* Pathfinding Project Struct AgentShouldRecalculatePath Extends IComponentData, IEnableableComponent ============================================================================== Public Tag component which, when enabled, indicates that the agent should recalculate its path immediately. The enabled state is updated every simulation loop. It cannot be set externally. --- # GlobalNodeStorage - A* Pathfinding Project Class GlobalNodeStorage ======================= Package Inner Types ----------- [DebugPathNode](https://arongranberg.com/astar/docs/debugpathnode.html) [IndexedStack](https://arongranberg.com/astar/docs/indexedstack.html) [JobAllocateNodes](https://arongranberg.com/astar/docs/joballocatenodes.html) [PathfindingThreadData](https://arongranberg.com/astar/docs/pathfindingthreaddata.html) Public Methods -------------- [AllocateNodesJob](https://arongranberg.com/astar/docs/globalnodestorage/allocatenodesjob.html#AllocateNodesJob) (result, count, createNode, variantsPerNode) [DestroyNode](https://arongranberg.com/astar/docs/globalnodestorage/destroynode.html#DestroyNode) (node) Destroyes the given node. [GetNode](https://arongranberg.com/astar/docs/globalnodestorage/getnode.html#GetNode) (nodeIndex) [GlobalNodeStorage](https://arongranberg.com/astar/docs/globalnodestorage/globalnodestorage.html#GlobalNodeStorage) (astar) [GrowTemporaryNodeStorage](https://arongranberg.com/astar/docs/globalnodestorage/growtemporarynodestorag.html#GrowTemporaryNodeStorage) (threadID) Grows temporary node storage for the given thread. [InitializeNode](https://arongranberg.com/astar/docs/globalnodestorage/initializenode.html#InitializeNode) (node) Initializes temporary path data for a node. [OnDisable](https://arongranberg.com/astar/docs/globalnodestorage/ondisable.html#OnDisable) () [SetThreadCount](https://arongranberg.com/astar/docs/globalnodestorage/setthreadcount.html#SetThreadCount) (threadCount) Public Variables ---------------- destroyedNodesVersion Number of nodes that have been destroyed in total. Public ##### uint destroyedNodesVersion Number of nodes that have been destroyed in total. nextNodeIndex Holds the next node index which has not been used by any previous node. Public ##### uint nextNodeIndex = 1 Holds the next node index which has not been used by any previous node. See [nodeIndexPools](https://arongranberg.com/astar/docs/globalnodestorage.html#nodeIndexPools) pathfindingThreadData Public ##### [PathfindingThreadData](https://arongranberg.com/astar/docs/pathfindingthreaddata.html) \[\] pathfindingThreadData = new [PathfindingThreadData](https://arongranberg.com/astar/docs/pathfindingthreaddata.html) \[0\] reservedPathNodeData The number of nodes for which path node data has been reserved. Public ##### uint reservedPathNodeData = 0 The number of nodes for which path node data has been reserved. Will be at least as high as [nextNodeIndex](https://arongranberg.com/astar/docs/globalnodestorage.html#nextNodeIndex) Private/Protected Members ------------------------- [DisposeThreadData](https://arongranberg.com/astar/docs/globalnodestorage/disposethreaddata.html#DisposeThreadData) () InitialTemporaryNodes Private Static ##### const int InitialTemporaryNodes = 256 [ReserveNodeIndices](https://arongranberg.com/astar/docs/globalnodestorage/reservenodeindices.html#ReserveNodeIndices) (nextNodeIndex) Reserves space for global node data. astar Private Readonly ##### [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) astar lastAllocationJob Private ##### Unity.Jobs.JobHandle lastAllocationJob nodeIndexPools Holds indices for nodes that have been destroyed. Private Readonly ##### [IndexedStack](https://arongranberg.com/astar/docs/indexedstack.html) \[\] nodeIndexPools = new \[\] { new [IndexedStack](https://arongranberg.com/astar/docs/indexedstack.html) (), new [IndexedStack](https://arongranberg.com/astar/docs/indexedstack.html) (), new [IndexedStack](https://arongranberg.com/astar/docs/indexedstack.html) (), } Holds indices for nodes that have been destroyed. To avoid trashing a lot of memory structures when nodes are frequently deleted and created, node indices are reused. There's one pool for each possible number of node variants (1, 2 and 3). nodes Maps from NodeIndex to node. Private ##### [GraphNode](https://arongranberg.com/astar/docs/graphnode.html) \[\] nodes = new [GraphNode](https://arongranberg.com/astar/docs/graphnode.html) \[0\] Maps from NodeIndex to node. temporaryNodeCount Private ##### int temporaryNodeCount = [InitialTemporaryNodes](https://arongranberg.com/astar/docs/globalnodestorage.html#InitialTemporaryNodes) --- # PathReturnQueue - A* Pathfinding Project Class PathReturnQueue ===================== Public Public Methods -------------- [Enqueue](https://arongranberg.com/astar/docs/pathreturnqueue/enqueue.html#Enqueue) (path) [PathReturnQueue](https://arongranberg.com/astar/docs/pathreturnqueue/pathreturnqueue.html#PathReturnQueue) (pathsClaimedSilentlyBy, OnReturnedPaths) [ReturnPaths](https://arongranberg.com/astar/docs/pathreturnqueue/returnpaths.html#ReturnPaths) (timeSlice) Returns all paths in the return stack. Private/Protected Members ------------------------- OnReturnedPaths Private Readonly ##### System.Action OnReturnedPaths pathReturnQueueReading Private ##### Queue<[Path](https://arongranberg.com/astar/docs/path.html) \> pathReturnQueueReading = new Queue<[Path](https://arongranberg.com/astar/docs/path.html) \>() pathReturnQueueWriting Holds all paths which are waiting to be flagged as completed. Private ##### Queue<[Path](https://arongranberg.com/astar/docs/path.html) \> pathReturnQueueWriting = new Queue<[Path](https://arongranberg.com/astar/docs/path.html) \>() Holds all paths which are waiting to be flagged as completed. See [ReturnPaths](https://arongranberg.com/astar/docs/pathreturnqueue/returnpaths.html#ReturnPaths) pathsClaimedSilentlyBy Paths are claimed silently by some object to prevent them from being recycled while still in use. Private Readonly ##### System.Object pathsClaimedSilentlyBy Paths are claimed silently by some object to prevent them from being recycled while still in use. This will be set to the [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) object. --- # HierarchicalGraph - A* Pathfinding Project Class HierarchicalGraph ======================= Public Holds a hierarchical graph to speed up certain pathfinding queries. A common type of query that needs to be very fast is on the form 'is this node reachable from this other node'. This is for example used when picking the end node of a path. The end node is determined as the closest node to the end point that can be reached from the start node. This data structure's primary purpose is to keep track of which connected component each node is contained in, in order to make such queries fast. See [https://en.wikipedia.org/wiki/Connected\_component\_(graph\_theory)](https://en.wikipedia.org/wiki/Connected_component_(graph_theory)) A connected component is a set of nodes such that there is a valid path between every pair of nodes in that set. Thus the query above can simply be answered by checking if they are in the same connected component. The connected component is exposed on nodes as the [Pathfinding.GraphNode.Area](https://arongranberg.com/astar/docs/graphnode.html#Area) property and on this class using the [GetConnectedComponent](https://arongranberg.com/astar/docs/hierarchicalgraph/getconnectedcomponent.html#GetConnectedComponent) method. Note This class does not calculate strictly connected components. In case of one-way connections, it will still consider the nodes to be in the same connected component. In the image below (showing a 200x200 grid graph) each connected component is colored using a separate color. The actual color doesn't signify anything in particular however, only that they are different. ![](https://arongranberg.com/astar/docs/images/hierarchical/connected_components@2x.png) Prior to version 4.2 the connected components were just a number stored on each node, and when a graph was updated the connected components were completely recalculated. This can be done relatively efficiently using a flood filling algorithm (see [https://en.wikipedia.org/wiki/Flood\_fill](https://en.wikipedia.org/wiki/Flood_fill) ) however it still requires a pass through every single node which can be quite costly on larger graphs. This class instead builds a much smaller graph that still respects the same connectivity as the original graph. Each node in this hierarchical graph represents a larger number of real nodes that are one single connected component. Take a look at the image below for an example. In the image each color is a separate hierarchical node, and the black connections go between the center of each hierarchical node. ![](https://arongranberg.com/astar/docs/images/hierarchical/hierarchical_sample@2x.png) With the hierarchical graph, the connected components can be calculated by flood filling the hierarchical graph instead of the real graph. Then when we need to know which connected component a node belongs to, we look up the connected component of the hierarchical node the node belongs to. The benefit is not immediately obvious. The above is just a bit more complicated way to accomplish the same thing. However the real benefit comes when updating the graph. When the graph is updated, all hierarchical nodes which contain any node that was affected by the update is removed completely and then once all have been removed new hierarchical nodes are recalculated in their place. Once this is done the connected components of the whole graph can be updated by flood filling only the hierarchical graph. Since the hierarchical graph is vastly smaller than the real graph, this is significantly faster. Your browser does not support the video tag. So finally using all of this, the connected components of the graph can be recalculated very quickly as the graph is updated. The effect of this grows larger the larger the graph is, and the smaller the graph update is. Making a small update to a 1000x1000 grid graph is on the order of 40 times faster with these optimizations. When scanning a graph or making updates to the whole graph at the same time there is however no speed boost. In fact due to the extra complexity it is a bit slower, however after profiling the extra time seems to be mostly insignificant compared to the rest of the cost of scanning the graph. Your browser does not support the video tag. See [Pathfinding.PathUtilities.IsPathPossible](https://arongranberg.com/astar/docs/pathutilities/ispathpossible.html#IsPathPossible3) [Pathfinding.NearestNodeConstraint](https://arongranberg.com/astar/docs/nearestnodeconstraint.html) [Pathfinding.GraphNode.Area](https://arongranberg.com/astar/docs/graphnode.html#Area) Inner Types ----------- [HierarhicalNodeData](https://arongranberg.com/astar/docs/hierarhicalnodedata.html) Burst-accessible data about the hierarhical nodes. [JobRecalculateComponents](https://arongranberg.com/astar/docs/jobrecalculatecomponents.html) Public Methods -------------- [AddDirtyNode](https://arongranberg.com/astar/docs/hierarchicalgraph/adddirtynode.html#AddDirtyNode) (node) Marks this node as dirty because it's connectivity or walkability has changed. [GetConnectedComponent](https://arongranberg.com/astar/docs/hierarchicalgraph/getconnectedcomponent.html#GetConnectedComponent) (hierarchicalNodeIndex) Get the connected component index of a hierarchical node. [GetHierarchicalNodeVersion](https://arongranberg.com/astar/docs/hierarchicalgraph/gethierarchicalnodevers.html#GetHierarchicalNodeVersion) (index) [GetHierarhicalNodeData](https://arongranberg.com/astar/docs/hierarchicalgraph/gethierarhicalnodedata.html#GetHierarhicalNodeData) (readLock) Data about the hierarhical nodes. [JobRecalculateIfNecessary](https://arongranberg.com/astar/docs/hierarchicalgraph/jobrecalculateifnecessa.html#JobRecalculateIfNecessary) (dependsOn=…) Schedule a job to recalculate the hierarchical graph and the connected components if any nodes have been marked as dirty. [OnDrawGizmos](https://arongranberg.com/astar/docs/hierarchicalgraph/ondrawgizmos.html#OnDrawGizmos) (gizmos, renderInGame) [OnEnable](https://arongranberg.com/astar/docs/hierarchicalgraph/onenable.html#OnEnable) () Initializes the [HierarchicalGraph](https://arongranberg.com/astar/docs/hierarchicalgraph.html) data. [RecalculateAll](https://arongranberg.com/astar/docs/hierarchicalgraph/recalculateall.html#RecalculateAll) () Recalculate everything from scratch. [RecalculateIfNecessary](https://arongranberg.com/astar/docs/hierarchicalgraph/recalculateifnecessary.html#RecalculateIfNecessary) () Recalculate the hierarchical graph and the connected components if any nodes have been marked as dirty. [ReserveNodeIndices](https://arongranberg.com/astar/docs/hierarchicalgraph/reservenodeindices.html#ReserveNodeIndices) (nodeIndexCount) Public Variables ---------------- NumConnectedComponents Public ##### int NumConnectedComponents navmeshEdges Public ##### [NavmeshEdges](https://arongranberg.com/astar/docs/navmeshedges.html) navmeshEdges version Public ##### int version Private/Protected Members ------------------------- [HierarchicalGraph](https://arongranberg.com/astar/docs/hierarchicalgraph/hierarchicalgraph.html#HierarchicalGraph) (nodeStorage) MaxChildrenPerNode Private Static ##### const int MaxChildrenPerNode = [Tiling](https://arongranberg.com/astar/docs/hierarchicalgraph.html#Tiling) \* [Tiling](https://arongranberg.com/astar/docs/hierarchicalgraph.html#Tiling) MinChildrenPerNode Private Static ##### const int MinChildrenPerNode = [MaxChildrenPerNode](https://arongranberg.com/astar/docs/hierarchicalgraph.html#MaxChildrenPerNode) /2 [OnCreatedNode](https://arongranberg.com/astar/docs/hierarchicalgraph/oncreatednode.html#OnCreatedNode) (node) [OnDestroyedNode](https://arongranberg.com/astar/docs/hierarchicalgraph/ondestroyednode.html#OnDestroyedNode) (node) [OnDisable](https://arongranberg.com/astar/docs/hierarchicalgraph/ondisable.html#OnDisable) () Disposes of all unmanaged data and clears managed data. Tiling Private Static ##### const int Tiling = 16 anyNodesDestroyed Private ##### bool anyNodesDestroyed = false areas Private ##### int\[\] areas bounds Internal ##### NativeList<[Bounds](https://docs.unity3d.com/ScriptReference/Bounds.html) \> bounds children Internal ##### List<[GraphNode](https://arongranberg.com/astar/docs/graphnode.html) \>\[\] children connectionAllocations Internal ##### NativeList connectionAllocations connectionAllocator Internal ##### [SlabAllocator](https://arongranberg.com/astar/docs/slaballocator.html) connectionAllocator currentConnections Private ##### List currentConnections = new List() dirtiedHierarchicalNodes Private ##### NativeList dirtiedHierarchicalNodes dirty Private ##### byte\[\] dirty dirtyNodes Private ##### [HierarchicalBitset](https://arongranberg.com/astar/docs/hierarchicalbitset.html) dirtyNodes freeNodeIndices Private ##### [CircularBuffer](https://arongranberg.com/astar/docs/circularbuffer.html) freeNodeIndices gcHandle Internal ##### [GCHandle](https://arongranberg.com/astar/docs/%3Cundefined%3E) gcHandle gizmoVersion Private ##### int gizmoVersion = 0 nodeStorage Private ##### [GlobalNodeStorage](https://arongranberg.com/astar/docs/globalnodestorage.html) nodeStorage numHierarchicalNodes Holds areas.Length as a burst-accessible reference. Private ##### NativeReference numHierarchicalNodes Holds areas.Length as a burst-accessible reference. rwLock Private ##### [RWLock](https://arongranberg.com/astar/docs/rwlock.html) rwLock = new [RWLock](https://arongranberg.com/astar/docs/rwlock.html) () temporaryQueue Private ##### Queue<[GraphNode](https://arongranberg.com/astar/docs/graphnode.html) \> temporaryQueue = new Queue<[GraphNode](https://arongranberg.com/astar/docs/graphnode.html) \>() temporaryStack Private ##### Stack temporaryStack = new Stack() versions Private ##### int\[\] versions --- # AgentOffMeshLinkTraversalContext - A* Pathfinding Project Class AgentOffMeshLinkTraversalContext Extends ICloneable ========================================================= Public Context with helpers for traversing an off-mesh link. This will be passed to the code that is responsible for traversing the off-mesh link. Warning This context should **never** be accessed outside of an implementation of the [IOffMeshLinkStateMachine](https://arongranberg.com/astar/docs/ioffmeshlinkstatemachine.html) interface. Inner Types ----------- [AbortOffMeshLinkTraversal](https://arongranberg.com/astar/docs/abortoffmeshlinktraversal.html) Thrown when the off-mesh link traversal should be aborted. Public Methods -------------- [Abort](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext/abort.html#Abort) (teleportToStart=true) Aborts traversing the off-mesh link. [AgentOffMeshLinkTraversalContext](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext/agentoff.html#AgentOffMeshLinkTraversalContext) (link) [Clone](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext/clone.html#Clone) () [DisableLocalAvoidance](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext/disablel.html#DisableLocalAvoidance) () Disables local avoidance for the agent. [DisableRotationSmoothing](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext/disabler.html#DisableRotationSmoothing) () Disables rotation smoothing for the agent. [MoveTowards](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext/movetowa.html#MoveTowards) (position, rotation, gravity, slowdown) Move towards a point while ignoring the navmesh. [Restore](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext/restore.html#Restore) () Restores the agent's settings to what it was before the link traversal started. [SetInternalData](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext/setinter.html#SetInternalData) (entity, transform, movementPlane, movementControl, movementSettings, linkInfo, movementDisabled, localAvoidanceDisabled, state, deltaTime) Internal method to set the data of the context. [Teleport](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext/teleport.html#Teleport) (position) Teleports the agent to the given position. Public Variables ---------------- deltaTime Delta time since the last link simulation. Public ##### float deltaTime Delta time since the last link simulation. During high time scales, the simulation may run multiple substeps per frame. This is **not** the same as Time.deltaTime. Inside the link coroutine, you should always use this field instead of Time.deltaTime. enableBuiltInMovement True if the agent's built-in movement logic should be enabled. Public ##### bool? enableBuiltInMovement True if the agent's built-in movement logic should be enabled. When traversing an off-mesh link, you typically want the agent's movement to be completely controlled by an animation, or some other code. However, sometimes you may want to use the built-in movement logic to move the agent. Using the [MoveTowards](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext/movetowa.html#MoveTowards) method will automatically enable the agent's movement logic during that frame. Note This will be reset to false every frame. Right before the off-mesh link traversal coroutine is executed. See [MoveTowards](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext/movetowa.html#MoveTowards) entity The entity that is traversing the off-mesh link. Public ##### Entity entity The entity that is traversing the off-mesh link. gameObject GameObject associated with the agent. Public ##### [GameObject](https://docs.unity3d.com/ScriptReference/GameObject.html) gameObject GameObject associated with the agent. In most cases, an agent is associated with an agent, but this is not always the case. For example, if you have created an entity without using the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component, this property may return null. Note When directly modifying the agent's transform during a link traversal, you should use the [transform](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext.html#transform) property instead of modifying the GameObject's transform. link Information about the off-mesh link that the agent is traversing. Public ##### [OffMeshLinks.OffMeshLinkTracer](https://arongranberg.com/astar/docs/offmeshlinktracer.html) link Information about the off-mesh link that the agent is traversing. managedState Some internal state of the agent. Public ##### [ManagedState](https://arongranberg.com/astar/docs/managedstate.html) managedState Some internal state of the agent. movementControl How the agent should move. Public ##### ref[MovementControl](https://arongranberg.com/astar/docs/movementcontrol.html) movementControl How the agent should move. The agent will move according to this data, every frame, if [enableBuiltInMovement](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext.html#enableBuiltInMovement) is enabled. Note [enableBuiltInMovement](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext.html#enableBuiltInMovement) needs to be enabled every tick to allow the agent to move. movementPlane The plane in which the agent is moving. Public ##### ref[NativeMovementPlane](https://arongranberg.com/astar/docs/nativemovementplane.html) movementPlane The plane in which the agent is moving. In a 3D game, this will typically be the XZ plane, but in a 2D game it will typically be the XY plane. Games on spherical planets could have planes that are aligned with the surface of the planet. movementSettings The movement settings for the agent. Public ##### ref[MovementSettings](https://arongranberg.com/astar/docs/movementsettings.html) movementSettings The movement settings for the agent. transform [ECS](https://arongranberg.com/astar/docs/ecs2.html) LocalTransform component attached to the agent. Public ##### ref LocalTransform transform [ECS](https://arongranberg.com/astar/docs/ecs2.html) LocalTransform component attached to the agent. Private/Protected Members ------------------------- backupRotationSmoothing Protected ##### float backupRotationSmoothing = float.NaN concreteLink The off-mesh link that is being traversed. Internal ##### [OffMeshLinks.OffMeshLinkConcrete](https://arongranberg.com/astar/docs/offmeshlinkconcrete.html) concreteLink The off-mesh link that is being traversed. See [link](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext.html#link) gameObjectCache Protected ##### [GameObject](https://docs.unity3d.com/ScriptReference/GameObject.html) gameObjectCache linkInfoPtr Internal ##### unsafe[AgentOffMeshLinkTraversal](https://arongranberg.com/astar/docs/agentoffmeshlinktraversal.html) \* linkInfoPtr localAvoidanceDisabled Internal ##### EnabledRefRW<[AgentOffMeshLinkLocalAvoidanceDisabled](https://arongranberg.com/astar/docs/agentoffmeshlinklocalavoidancedisabled.html) \> localAvoidanceDisabled movementControlPtr Internal ##### unsafe[MovementControl](https://arongranberg.com/astar/docs/movementcontrol.html) \* movementControlPtr movementDisabled Internal ##### EnabledRefRW<[AgentOffMeshLinkMovementDisabled](https://arongranberg.com/astar/docs/agentoffmeshlinkmovementdisabled.html) \> movementDisabled movementPlanePtr Internal ##### unsafe[AgentMovementPlane](https://arongranberg.com/astar/docs/agentmovementplane.html) \* movementPlanePtr movementSettingsPtr Internal ##### unsafe[MovementSettings](https://arongranberg.com/astar/docs/movementsettings.html) \* movementSettingsPtr transformPtr Internal ##### unsafe LocalTransform \* transformPtr Deprecated Members ------------------ linkInfo Information about the off-mesh link that the agent is traversing. Public ##### [AgentOffMeshLinkTraversal](https://arongranberg.com/astar/docs/agentoffmeshlinktraversal.html) linkInfo Information about the off-mesh link that the agent is traversing. Deprecated Use the [link](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext.html#link) property instead --- # AIGizmosSystem - A* Pathfinding Project Struct AIGizmosSystem Extends ISystem ===================================== Public Draws gizmos and debug information for [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) agents. When outside of play mode, the [FollowerEntity.DrawGizmos](https://arongranberg.com/astar/docs/followerentity/drawgizmos.html#DrawGizmos) method will draw some of the same gizmos, since this system cannot be used then (entities only exist in play mode). Inner Types ----------- [DrawerCallback](https://arongranberg.com/astar/docs/drawercallback.html) Public Methods -------------- [DrawGizmos](https://arongranberg.com/astar/docs/aigizmossystem/drawgizmos.html#DrawGizmos) (systemState) [OnCreate](https://arongranberg.com/astar/docs/aigizmossystem/oncreate.html#OnCreate) (state) [OnUpdate](https://arongranberg.com/astar/docs/aigizmossystem/onupdate.html#OnUpdate) (systemState) Public Variables ---------------- MovementStateTypeHandleRO Public ##### ComponentTypeHandle<[MovementState](https://arongranberg.com/astar/docs/movementstate.html) \> MovementStateTypeHandleRO ResolvedMovementHandleRO Public ##### ComponentTypeHandle<[ResolvedMovement](https://arongranberg.com/astar/docs/resolvedmovement.html) \> ResolvedMovementHandleRO jobRepairPathScheduler Public ##### [JobRepairPath.Scheduler](https://arongranberg.com/astar/docs/scheduler.html) jobRepairPathScheduler Public Static Variables ----------------------- manuallyTriggered Public Static ##### bool manuallyTriggered --- # GraphUpdateLock - A* Pathfinding Project Struct GraphUpdateLock Extends IDisposable ========================================== Public Prevents pathfinding from running while held. Public Methods -------------- [Dispose](https://arongranberg.com/astar/docs/graphupdatelock/dispose.html#Dispose) () [GraphUpdateLock](https://arongranberg.com/astar/docs/graphupdatelock/graphupdatelock.html#GraphUpdateLock) (pathProcessor, block) [Release](https://arongranberg.com/astar/docs/graphupdatelock/release.html#Release) () Allow pathfinding to start running again if no other locks are still held. Public Variables ---------------- Held True while this lock is preventing the pathfinding threads from processing more paths. Public ##### bool Held True while this lock is preventing the pathfinding threads from processing more paths. Note that the pathfinding threads may not be paused yet (if this lock was obtained using PausePathfinding(false)). id Public ##### int id pathProcessor Public ##### [PathProcessor](https://arongranberg.com/astar/docs/pathprocessor.html) pathProcessor --- # PathProcessor - A* Pathfinding Project Class PathProcessor =================== Public Inner Types ----------- [GraphUpdateLock](https://arongranberg.com/astar/docs/graphupdatelock.html) Prevents pathfinding from running while held. Public Methods -------------- [Dispose](https://arongranberg.com/astar/docs/pathprocessor/dispose.html#Dispose) () Cleans up all native memory managed by this instance. [PausePathfinding](https://arongranberg.com/astar/docs/pathprocessor/pausepathfinding.html#PausePathfinding) (block) Prevents pathfinding threads from starting to calculate any new paths. [SetThreadCount](https://arongranberg.com/astar/docs/pathprocessor/setthreadcount.html#SetThreadCount) (processors, multithreaded) Changes the number of threads used for pathfinding. [StopThreads](https://arongranberg.com/astar/docs/pathprocessor/stopthreads.html#StopThreads) () Calls 'Join' on each of the threads to block until they have completed. [TickNonMultithreaded](https://arongranberg.com/astar/docs/pathprocessor/ticknonmultithreaded.html#TickNonMultithreaded) () Does pathfinding calculations when not using multithreading. Public Variables ---------------- IsUsingMultithreading Returns whether or not multithreading is used. Public ##### bool IsUsingMultithreading Returns whether or not multithreading is used. NumThreads Number of parallel pathfinders. Public ##### int NumThreads Number of parallel pathfinders. Returns the number of concurrent processes which can calculate paths at once. When using multithreading, this will be the number of threads, if not using multithreading it is always 1 (since only 1 coroutine is used). See threadInfos [IsUsingMultithreading](https://arongranberg.com/astar/docs/pathprocessor.html#IsUsingMultithreading) Public Events ------------- OnPathPostSearch Public ##### System.Action<[PathHandler](https://arongranberg.com/astar/docs/pathhandler.html) ,[Path](https://arongranberg.com/astar/docs/path.html) \> OnPathPostSearch OnPathPreSearch Public ##### System.Action<[Path](https://arongranberg.com/astar/docs/path.html) \> OnPathPreSearch OnQueueUnblocked Public ##### System.Action OnQueueUnblocked Private/Protected Members ------------------------- [CalculatePaths](https://arongranberg.com/astar/docs/pathprocessor/calculatepaths.html#CalculatePaths) (pathHandler) Main pathfinding method. [CalculatePathsThreaded](https://arongranberg.com/astar/docs/pathprocessor/calculatepathsthreaded.html#CalculatePathsThreaded) (pathHandler, receiver) Main pathfinding method (multithreaded). [Lock](https://arongranberg.com/astar/docs/pathprocessor/lock.html#Lock) (block) MarkerCalculatePath Private Static Readonly ##### Unity.Profiling.ProfilerMarker MarkerCalculatePath = new Unity.Profiling.ProfilerMarker("Calculating [Path](https://arongranberg.com/astar/docs/path.html) ") MarkerPreparePath Private Static Readonly ##### Unity.Profiling.ProfilerMarker MarkerPreparePath = new Unity.Profiling.ProfilerMarker("Prepare [Path](https://arongranberg.com/astar/docs/path.html) ") [PathProcessor](https://arongranberg.com/astar/docs/pathprocessor/pathprocessor.html#PathProcessor) (astar, returnQueue, processors, multithreaded) [StartThreads](https://arongranberg.com/astar/docs/pathprocessor/startthreads.html#StartThreads) () [Unlock](https://arongranberg.com/astar/docs/pathprocessor/unlock.html#Unlock) (id) astar Private Readonly ##### [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) astar coroutineReceiver Private ##### [BlockableChannel](https://arongranberg.com/astar/docs/blockablechannel.html) <[Path](https://arongranberg.com/astar/docs/path.html) \>.Receiver coroutineReceiver locks Private Readonly ##### List locks = new List() multithreaded Private ##### bool multithreaded nextLockID Private ##### int nextLockID = 0 pathHandlers Private ##### [PathHandler](https://arongranberg.com/astar/docs/pathhandler.html) \[\] pathHandlers queue Internal ##### [BlockableChannel](https://arongranberg.com/astar/docs/blockablechannel.html) <[Path](https://arongranberg.com/astar/docs/path.html) \> queue returnQueue Private Readonly ##### [PathReturnQueue](https://arongranberg.com/astar/docs/pathreturnqueue.html) returnQueue threadCoroutine When no multithreading is used, the IEnumerator is stored here. Private ##### IEnumerator threadCoroutine When no multithreading is used, the IEnumerator is stored here. When no multithreading is used, a coroutine is used instead. It is not directly called with StartCoroutine but a separate function has just a while loop which increments the main IEnumerator. This is done so other functions can step the thread forward at any time, without having to wait for Unity to update it. See [CalculatePaths](https://arongranberg.com/astar/docs/pathprocessor/calculatepaths.html#CalculatePaths) [CalculatePathsThreaded](https://arongranberg.com/astar/docs/pathprocessor/calculatepathsthreaded.html#CalculatePathsThreaded) threads References to each of the pathfinding threads. Private ##### [Thread](https://arongranberg.com/astar/docs/pathfinding.html#Thread) \[\] threads References to each of the pathfinding threads. --- # WorkItemProcessor - A* Pathfinding Project Class WorkItemProcessor Extends [IWorkItemContext](https://arongranberg.com/astar/docs/iworkitemcontext.html) ============================================================================================================== Public Inner Types ----------- [BoundsVisualization](https://arongranberg.com/astar/docs/boundsvisualization.html) [IndexedQueue](https://arongranberg.com/astar/docs/indexedqueue.html) Similar to Queue but allows random access. Public Methods -------------- [AddWorkItem](https://arongranberg.com/astar/docs/workitemprocessor/addworkitem.html#AddWorkItem) (item) Add a work item to be processed when pathfinding is paused. [DrawGizmos](https://arongranberg.com/astar/docs/workitemprocessor/drawgizmos.html#DrawGizmos) () [EnsureValidFloodFill](https://arongranberg.com/astar/docs/workitemprocessor/ensurevalidfloodfill.html#EnsureValidFloodFill) () If a WorkItem needs to have a valid area information during execution, call this method to ensure there are no pending flood fills. [ProcessWorkItemsForScan](https://arongranberg.com/astar/docs/workitemprocessor/processworkitemsforscan.html#ProcessWorkItemsForScan) (force) Process graph updating work items. [ProcessWorkItemsForUpdate](https://arongranberg.com/astar/docs/workitemprocessor/processworkitemsforupda.html#ProcessWorkItemsForUpdate) (force) Process graph updating work items. [VisualizeOriginalGraphUpdateBounds](https://arongranberg.com/astar/docs/workitemprocessor/visualizeoriginalgraphu.html#VisualizeOriginalGraphUpdateBounds) (bounds) Add a visualization for showing the original bounds of a graph update. [WorkItemProcessor](https://arongranberg.com/astar/docs/workitemprocessor/workitemprocessor.html#WorkItemProcessor) (astar) Public Variables ---------------- anyQueued True if any work items are queued right now. Public ##### bool anyQueued True if any work items are queued right now. workItemsInProgress True while a batch of work items are being processed. Public ##### bool workItemsInProgress True while a batch of work items are being processed. Set to true when a work item is started to be processed, reset to false when all work items are complete. Work item updates are often spread out over several frames, this flag will be true during the whole time the updates are in progress. workItemsInProgressRightNow Used to prevent waiting for work items to complete inside other work items as that will cause the program to hang. Public ##### bool workItemsInProgressRightNow Used to prevent waiting for work items to complete inside other work items as that will cause the program to hang. Public Events ------------- OnGraphsUpdated Public ##### System.Action OnGraphsUpdated Private/Protected Members ------------------------- [DirtyBounds](https://arongranberg.com/astar/docs/workitemprocessor/dirtybounds.html) (bounds) Mark a particular region of the world as having been changed. [PreUpdate](https://arongranberg.com/astar/docs/workitemprocessor/preupdate.html#PreUpdate) () Call to send a GraphModifier.EventType.PreUpdate event to all graph modifiers. [ProcessWorkItems](https://arongranberg.com/astar/docs/workitemprocessor/processworkitems.html#ProcessWorkItems) (force, sendEvents) [SetGraphDirty](https://arongranberg.com/astar/docs/workitemprocessor/setgraphdirty.html#SetGraphDirty) (graph) Trigger a graph modification event. anyGraphsDirty Private ##### bool anyGraphsDirty = true astar Private Readonly ##### [AstarPath](https://arongranberg.com/astar/docs/astarpath.html) astar boundsVisualizations Private Readonly ##### List<[BoundsVisualization](https://arongranberg.com/astar/docs/boundsvisualization.html) \> boundsVisualizations = new List<[BoundsVisualization](https://arongranberg.com/astar/docs/boundsvisualization.html) \>() preUpdateEventSent Private ##### bool preUpdateEventSent = false workItems Private Readonly ##### [IndexedQueue](https://arongranberg.com/astar/docs/indexedqueue.html) <[AstarWorkItem](https://arongranberg.com/astar/docs/astarworkitem.html) \> workItems = new [IndexedQueue](https://arongranberg.com/astar/docs/indexedqueue.html) <[AstarWorkItem](https://arongranberg.com/astar/docs/astarworkitem.html) \>() Deprecated Members ------------------ [QueueFloodFill](https://arongranberg.com/astar/docs/workitemprocessor/queuefloodfill.html#QueueFloodFill) () Call during work items to queue a flood fill. --- # DrawerCallback - A* Pathfinding Project Class DrawerCallback Extends IDrawGizmos ======================================== Public Public Methods -------------- [DrawGizmos](https://arongranberg.com/astar/docs/drawercallback/drawgizmos.html#DrawGizmos) () [DrawerCallback](https://arongranberg.com/astar/docs/drawercallback/drawercallback.html#DrawerCallback) (world) Public Variables ---------------- Exists Public ##### bool Exists Private/Protected Members ------------------------- world Private ##### World world --- # AIMovementSystemGroup - A* Pathfinding Project Class AIMovementSystemGroup Extends ComponentSystemGroup ======================================================== Public Inner Types ----------- [TimeScaledRateManager](https://arongranberg.com/astar/docs/timescaledratemanager.html) Rate manager which runs a system group multiple times if the delta time is higher than desired, but always executes the group at least once per frame. Public Variables ---------------- CustomTimeScale Additional time scale multiplier to apply to the simulation. Public ##### double CustomTimeScale Additional time scale multiplier to apply to the simulation. This can be used to speed up or slow down the simulation instead of using Unity's Time.timeScale. The final time scale will be Unity's Time.timeScale multiplied by this value. Default value is 1.0. `var aiMovementSystemGroup = Unity.Entities.World.DefaultGameObjectInjectionWorld.GetExistingSystemManaged(); aiMovementSystemGroup.CustomTimeScale = 3.0; ` Private/Protected Members ------------------------- [OnCreate](https://arongranberg.com/astar/docs/aimovementsystemgroup/oncreate.html#OnCreate) () [OnDestroy](https://arongranberg.com/astar/docs/aimovementsystemgroup/ondestroy.html#OnDestroy) () [OnUpdate](https://arongranberg.com/astar/docs/aimovementsystemgroup/onupdate.html#OnUpdate) () --- # AIMoveSystem - A* Pathfinding Project Struct AIMoveSystem Extends ISystem =================================== Public Public Methods -------------- [OnCreate](https://arongranberg.com/astar/docs/aimovesystem/oncreate.html#OnCreate) (state) [OnUpdate](https://arongranberg.com/astar/docs/aimovesystem/onupdate.html#OnUpdate) (systemState) [RunMovementOverrideBeforeMovement](https://arongranberg.com/astar/docs/aimovesystem/runmovementoverridebeforemov.html#RunMovementOverrideBeforeMovement) (systemState, dt) [ScheduleApplyGravity](https://arongranberg.com/astar/docs/aimovesystem/scheduleapplygravity.html#ScheduleApplyGravity) (systemState, dt) Public Variables ---------------- entityQueryMovementOverride Public ##### EntityQuery entityQueryMovementOverride entityQueryWithGravity Public ##### EntityQuery entityQueryWithGravity Public Static Variables ----------------------- MarkerMovementOverride Public Static Readonly ##### ProfilerMarker MarkerMovementOverride = new ProfilerMarker("MovementOverrideBeforeMovement") --- # TimeScaledRateManager - A* Pathfinding Project Class TimeScaledRateManager Extends IRateManager, IDisposable ============================================================= Public Rate manager which runs a system group multiple times if the delta time is higher than desired, but always executes the group at least once per frame. Public Methods -------------- [Dispose](https://arongranberg.com/astar/docs/timescaledratemanager/dispose.html#Dispose) () [OnSimulationStepsFinished](https://arongranberg.com/astar/docs/timescaledratemanager/onsimulationstepsfi.html#OnSimulationStepsFinished) (totalSimulationProcessingTime) [ShouldGroupUpdate](https://arongranberg.com/astar/docs/timescaledratemanager/shouldgroupupdate.html#ShouldGroupUpdate) (group) [TimeScaledRateManager](https://arongranberg.com/astar/docs/timescaledratemanager/timescaledratemanag.html#TimeScaledRateManager) () Public Variables ---------------- CustomTimeScale Additional time scale multiplier to apply to the simulation. Public ##### double CustomTimeScale = 1.0 Additional time scale multiplier to apply to the simulation. This can be used to speed up or slow down the simulation instead of using Unity's Time.timeScale. The final time scale will be Unity's Time.timeScale multiplied by this value. Default value is 1.0. `var aiMovementSystemGroup = Unity.Entities.World.DefaultGameObjectInjectionWorld.GetExistingSystemManaged(); aiMovementSystemGroup.CustomTimeScale = 3.0; ` NumUpdatesThisFrame Public ##### int NumUpdatesThisFrame Timestep Public ##### float Timestep Public Static Variables ----------------------- CheapSimulationOnly True if it was determined that zero substeps should be simulated. Public Static ##### bool CheapSimulationOnly True if it was determined that zero substeps should be simulated. In this case all systems will get an opportunity to run a single update, but they should avoid systems that don't have to run every single frame. CheapStepDeltaTime Public Static ##### float CheapStepDeltaTime IsFirstSubstep True when this is the first substep of the current simulation. Public Static ##### bool IsFirstSubstep True when this is the first substep of the current simulation. IsLastSubstep True when this is the last substep of the current simulation. Public Static ##### bool IsLastSubstep True when this is the last substep of the current simulation. Private/Protected Members ------------------------- cheapSimulationOnly Private Static ##### bool cheapSimulationOnly cheapTimeData Private Static ##### TimeData cheapTimeData cheapTimeDataQueue Private ##### NativeList cheapTimeDataQueue inGroup Private Static ##### bool inGroup isFirstSubstep Private Static ##### bool isFirstSubstep isLastSubstep Private Static ##### bool isLastSubstep lastCheapSimulation Private ##### double lastCheapSimulation lastFullSimulation Private ##### double lastFullSimulation maximumDt Private ##### float maximumDt = 1.0f / 30.0f numUpdatesThisFrame Private ##### int numUpdatesThisFrame ownProcessingTimePerIteration Private ##### float ownProcessingTimePerIteration = 0 stepDt Private ##### float stepDt timeDataQueue Private ##### NativeList timeDataQueue updateIndex Private ##### int updateIndex --- # ComponentRef - A* Pathfinding Project Struct ComponentRef =================== Public Wrapper for a pointer. Very similar to the entities package RefRW struct. But unfortunately that one cannot be used because the required constructor is not exposed. Public Methods -------------- [ComponentRef](https://arongranberg.com/astar/docs/componentref/componentref.html#ComponentRef) (ptr) Public Variables ---------------- ptr Public ##### unsafe byte \* ptr value Public ##### ref T value --- # AutoRepathPolicy - A* Pathfinding Project Struct AutoRepathPolicy Extends IComponentData ============================================== Public Policy for how often to recalculate an agent's path. See [FollowerEntity.autoRepath](https://arongranberg.com/astar/docs/followerentity.html#autoRepath) This is the unmanaged equivalent of [Pathfinding.AutoRepathPolicy](https://arongranberg.com/astar/docs/autorepathpolicy.html) . Public Methods -------------- [AutoRepathPolicy](https://arongranberg.com/astar/docs/autorepathpolicy/autorepathpolicy.html#AutoRepathPolicy) (policy) [OnPathCalculated](https://arongranberg.com/astar/docs/autorepathpolicy/onpathcalculated.html#OnPathCalculated) (hadError) [OnScheduledPathRecalculation](https://arongranberg.com/astar/docs/autorepathpolicy/onscheduledpathrecalcula.html#OnScheduledPathRecalculation) (destination, time) Must be called when a path request has been scheduled. [Reset](https://arongranberg.com/astar/docs/autorepathpolicy/reset2.html#Reset) () [ShouldRecalculatePath](https://arongranberg.com/astar/docs/autorepathpolicy/shouldrecalculatepath2.html#ShouldRecalculatePath) (position, radius, destination, time, isPathStale) True if the path should be recalculated according to the policy. Public Variables ---------------- lastDestination Public ##### float3 lastDestination lastRepathTime Public ##### float lastRepathTime mode Policy to use when recalculating paths. Public ##### [Pathfinding.AutoRepathPolicy.Mode](https://arongranberg.com/astar/docs/autorepathpolicy.html#Mode) mode Policy to use when recalculating paths. See [Pathfinding.AutoRepathPolicy.Mode](https://arongranberg.com/astar/docs/autorepathpolicy.html#Mode) for more details. pathFailures Public ##### byte pathFailures period Number of seconds between each automatic path recalculation for Mode.EveryNSeconds, and the maximum interval for Mode.Dynamic. Public ##### float period Number of seconds between each automatic path recalculation for Mode.EveryNSeconds, and the maximum interval for Mode.Dynamic. Public Static Variables ----------------------- Default Public Static ##### [AutoRepathPolicy](https://arongranberg.com/astar/docs/autorepathpolicy2.html) Default Sensitivity How sensitive the agent should be to changes in its destination for Mode.Dynamic. Public Static ##### const float Sensitivity = 10.0f How sensitive the agent should be to changes in its destination for Mode.Dynamic. A higher value means the destination has to move less for the path to be recalculated. See [AutoRepathPolicy.Mode](https://arongranberg.com/astar/docs/autorepathpolicy.html#Mode) --- # DestinationEntity - A* Pathfinding Project Struct DestinationEntity Extends IComponentData, IEnableableComponent ===================================================================== Public Holds an agent's destination as an entity. Every frame, the position of this entity will be copied to the [DestinationPoint.destination](https://arongranberg.com/astar/docs/destinationpoint.html#destination) field of the agent, by the [DestinationEntitySystem](https://arongranberg.com/astar/docs/destinationentitysystem.html) . See [AIDestinationSetter](https://arongranberg.com/astar/docs/aidestinationsetter.html) [IAstarAI.destination](https://arongranberg.com/astar/docs/iastarai.html#destination) [DestinationPoint.destination](https://arongranberg.com/astar/docs/destinationpoint.html#destination) [DestinationEntitySystem](https://arongranberg.com/astar/docs/destinationentitysystem.html) Public Variables ---------------- destination The entity whose position the agent is moving towards. Public ##### Entity destination The entity whose position the agent is moving towards. Every frame, the position of this entity will be copied to the [DestinationPoint.destination](https://arongranberg.com/astar/docs/destinationpoint.html#destination) field of the agent. See [AIDestinationSetter](https://arongranberg.com/astar/docs/aidestinationsetter.html) [IAstarAI.destination](https://arongranberg.com/astar/docs/iastarai.html#destination) useRotation If true, the agent will try to align itself with the rotation of the [destination](https://arongranberg.com/astar/docs/destinationentity.html#destination) entity. Public ##### bool useRotation If true, the agent will try to align itself with the rotation of the [destination](https://arongranberg.com/astar/docs/destinationentity.html#destination) entity. Your browser does not support the video tag. See [FollowerEntity.SetDestination](https://arongranberg.com/astar/docs/followerentity/setdestination.html#SetDestination) --- # DestinationEntitySystem - A* Pathfinding Project Struct DestinationEntitySystem Extends ISystem ============================================== Public System that updates the destination of agents with a [DestinationEntity](https://arongranberg.com/astar/docs/destinationentity.html) component. Every frame, the position of the target entity will be copied to the [DestinationPoint.destination](https://arongranberg.com/astar/docs/destinationpoint.html#destination) field of the agent. If [DestinationEntity.useRotation](https://arongranberg.com/astar/docs/destinationentity.html#useRotation) is true, the facing direction will also be copied. See [AIDestinationSetter](https://arongranberg.com/astar/docs/aidestinationsetter.html) Inner Types ----------- [UpdateDestinationJob](https://arongranberg.com/astar/docs/updatedestinationjob.html) Public Methods -------------- [OnUpdate](https://arongranberg.com/astar/docs/destinationentitysystem/onupdate.html#OnUpdate) (state) --- # UpdateDestinationJob - A* Pathfinding Project Struct UpdateDestinationJob Extends IJobEntity ============================================== Public Public Methods -------------- [Execute](https://arongranberg.com/astar/docs/updatedestinationjob/execute.html#Execute) (destPoint, destEntity) Public Variables ---------------- TransformLookup Public ##### ComponentLookup TransformLookup --- # DestinationMoveInCircleSystem - A* Pathfinding Project Struct DestinationMoveInCircleSystem Extends ISystem ==================================================== Public System that updates the destination of agents with a [DestinationMoveInCircle](https://arongranberg.com/astar/docs/destinationmoveincircle.html) component. Every frame, the calculated destination will be copied to the [DestinationPoint.destination](https://arongranberg.com/astar/docs/destinationpoint.html#destination) field of the agent. See [MoveInCircle](https://arongranberg.com/astar/docs/moveincircle.html) Inner Types ----------- [UpdateDestinationJob](https://arongranberg.com/astar/docs/updatedestinationjob2.html) Public Methods -------------- [OnUpdate](https://arongranberg.com/astar/docs/destinationmoveincirclesystem/onupdate.html#OnUpdate) (state) --- # UpdateDestinationJob - A* Pathfinding Project Struct UpdateDestinationJob Extends IJobEntity ============================================== Public Public Methods -------------- [Execute](https://arongranberg.com/astar/docs/updatedestinationjob/execute2.html#Execute) (destPoint, localTransform, destCircle) Public Variables ---------------- TransformLookup Public ##### ComponentLookup TransformLookup --- # DestinationMoveInCircle - A* Pathfinding Project Struct DestinationMoveInCircle Extends IComponentData, IEnableableComponent =========================================================================== Public [ECS](https://arongranberg.com/astar/docs/ecs2.html) component corresponding to [MoveInCircle](https://arongranberg.com/astar/docs/moveincircle.html) . See [DestinationMoveInCircleSystem](https://arongranberg.com/astar/docs/destinationmoveincirclesystem.html) Public Variables ---------------- offset Public ##### float offset radius Public ##### float radius target Public ##### Unity.Entities.Entity target --- # DrawGizmosJobUtils - A* Pathfinding Project Struct DrawGizmosJobUtils ========================= Public Private/Protected Members ------------------------- [DrawPath](https://arongranberg.com/astar/docs/drawgizmosjobutils/drawpath.html#DrawPath) (draw, vertices, shape) --- # DestinationPoint - A* Pathfinding Project Struct DestinationPoint Extends IComponentData ============================================== Public Holds an agent's destination point. Public Variables ---------------- destination The destination point that the agent is moving towards. Public ##### float3 destination The destination point that the agent is moving towards. This is the point that the agent is trying to reach, but it may not always be possible to reach it. See [AIDestinationSetter](https://arongranberg.com/astar/docs/aidestinationsetter.html) [IAstarAI.destination](https://arongranberg.com/astar/docs/iastarai.html#destination) facingDirection The direction the agent should face when it reaches the destination. Public ##### float3 facingDirection The direction the agent should face when it reaches the destination. If zero, the agent will not try to face any particular direction when reaching the destination. --- # EntityAccess - A* Pathfinding Project Struct EntityAccess =================== Public Utility for efficient random access to entity component data from the main thread. Since this struct returns a reference to the component data, it is faster than using EntityManager.GetComponentData, in particular for larger component types. Warning Some checks are not enforced by this API. It is the user's responsibility to ensure that this struct does not survive past an [ECS](https://arongranberg.com/astar/docs/ecs2.html) system update. If you only use this struct from the main thread and only store it locally on the stack, this should not be a problem. This struct also does not enforce that you only read to the component data if the **readOnly** flag is set. Public Methods -------------- [EntityAccess](https://arongranberg.com/astar/docs/entityaccess/entityaccess.html#EntityAccess) (readOnly) [HasComponent](https://arongranberg.com/astar/docs/entityaccess/hascomponent.html#HasComponent) (storage) [Update](https://arongranberg.com/astar/docs/entityaccess/update.html#Update) (entityManager) Update the component type handle if necessary. Public Variables ---------------- handle Public ##### ComponentTypeHandle handle lastSystemVersion Public ##### uint lastSystemVersion readOnly Public ##### bool readOnly this\[EntityStorageInfo storage\] Public ##### ref T? this\[EntityStorageInfo storage\] worldSequenceNumber Public ##### ulong worldSequenceNumber --- # EntityAccessHelper - A* Pathfinding Project Class EntityAccessHelper ======================== Public Helper for [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) . Public Static Variables ----------------------- GlobalSystemVersionOffset Public Static Readonly ##### int GlobalSystemVersionOffset = UnsafeUtility.GetFieldOffset(typeof(ComponentTypeHandle).GetField("m\_GlobalSystemVersion", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)) --- # EntityStorageCache - A* Pathfinding Project Struct EntityStorageCache ========================= Public Utility for efficient random access to entity storage data from the main thread. Public Methods -------------- [GetComponentData](https://arongranberg.com/astar/docs/entitystoragecache/getcomponentdata.html) (world, entity, access, value) Retrieves a component for a given entity. [Update](https://arongranberg.com/astar/docs/entitystoragecache/update.html#Update) (world, entity, entityManager, storage) Retrieves the storage for a given entity. Public Variables ---------------- entity Public ##### Entity entity lastWorldHash Public ##### int lastWorldHash storage Public ##### EntityStorageInfo storage --- # FallbackResolveMovementSystem - A* Pathfinding Project Struct FallbackResolveMovementSystem Extends ISystem ==================================================== Public Copies [MovementControl](https://arongranberg.com/astar/docs/movementcontrol.html) to [ResolvedMovement](https://arongranberg.com/astar/docs/resolvedmovement.html) when no local avoidance is used. Inner Types ----------- [CopyJob](https://arongranberg.com/astar/docs/copyjob.html) [CopyRotationJob](https://arongranberg.com/astar/docs/copyrotationjob.html) Public Methods -------------- [OnUpdate](https://arongranberg.com/astar/docs/fallbackresolvemovementsystem/onupdate.html#OnUpdate) (systemState) --- # ResolvedMovement - A* Pathfinding Project Struct ResolvedMovement Extends IComponentData ============================================== Public Holds the final movement data for an entity. This is the data that is used by the movement system to move the entity. Public Variables ---------------- rotationSpeed The speed at which the agent should rotate towards [targetRotation](https://arongranberg.com/astar/docs/movementcontrol.html#targetRotation) + [targetRotationOffset](https://arongranberg.com/astar/docs/movementcontrol.html#targetRotationOffset) , in radians per second. Public ##### float rotationSpeed The speed at which the agent should rotate towards [targetRotation](https://arongranberg.com/astar/docs/movementcontrol.html#targetRotation) + [targetRotationOffset](https://arongranberg.com/astar/docs/movementcontrol.html#targetRotationOffset) , in radians per second. speed The speed at which the agent should move towards [targetPoint](https://arongranberg.com/astar/docs/movementcontrol.html#targetPoint) , in meters per second. Public ##### float speed The speed at which the agent should move towards [targetPoint](https://arongranberg.com/astar/docs/movementcontrol.html#targetPoint) , in meters per second. targetPoint The point the agent should move towards. Public ##### float3 targetPoint The point the agent should move towards. targetRotation The desired rotation of the agent, in radians, relative to the current movement plane. Public ##### float targetRotation The desired rotation of the agent, in radians, relative to the current movement plane. When rotating the agent visually, the [targetRotationOffset](https://arongranberg.com/astar/docs/movementcontrol.html#targetRotationOffset) should also be added to this value. See [NativeMovementPlane.ToWorldRotation](https://arongranberg.com/astar/docs/nativemovementplane/toworldrotation.html#ToWorldRotation) [AgentMovementPlane](https://arongranberg.com/astar/docs/agentmovementplane.html) targetRotationHint The desired rotation of the agent, in radians, over a longer time horizon, relative to the current movement plane. Public ##### float targetRotationHint The desired rotation of the agent, in radians, over a longer time horizon, relative to the current movement plane. The [targetRotation](https://arongranberg.com/astar/docs/movementcontrol.html#targetRotation) is usually only over a very short time-horizon, usually a single simulation time step. This variable is used to provide a hint of where the agent wants to rotate to over a slightly longer time scale (on the order of a second or so). It is not used to control movement directly, but it may be used to guide animations, or rotation smoothing. If no better hint is available, this should be set to the same value as [targetRotation](https://arongranberg.com/astar/docs/movementcontrol.html#targetRotation) . See [NativeMovementPlane.ToWorldRotation](https://arongranberg.com/astar/docs/nativemovementplane/toworldrotation.html#ToWorldRotation) [AgentMovementPlane](https://arongranberg.com/astar/docs/agentmovementplane.html) targetRotationOffset Additive modifier to [targetRotation](https://arongranberg.com/astar/docs/movementcontrol.html#targetRotation) , in radians. Public ##### float targetRotationOffset Additive modifier to [targetRotation](https://arongranberg.com/astar/docs/movementcontrol.html#targetRotation) , in radians. This is used by the local avoidance system to rotate the agent, without this causing a feedback loop. This extra rotation will be ignored by the control system which decides how the agent \*wants\* to move. It will instead be directly applied to the agent. See [MovementState.rotationOffset](https://arongranberg.com/astar/docs/movementstate.html#rotationOffset) , which must be updated after rotating the agent using this value. turningRadiusMultiplier Public ##### float turningRadiusMultiplier --- # MovementControl - A* Pathfinding Project Struct MovementControl Extends IComponentData ============================================= Public Desired movement for an agent. This data will be fed to the local avoidance system to calculate the final movement of the agent. If no local avoidance is used, it will be directly copied to [ResolvedMovement](https://arongranberg.com/astar/docs/resolvedmovement.html) . See [ResolvedMovement](https://arongranberg.com/astar/docs/resolvedmovement.html) Public Variables ---------------- endOfPath The end of the current path. Public ##### float3 endOfPath The end of the current path. This informs the local avoidance system about the final desired destination for the agent. This is used to make agents stop if the destination is crowded and it cannot reach its destination. If this is not set, agents will often move forever around a crowded destination, always trying to find some way to get closer, but never finding it. hierarchicalNodeIndex The index of the hierarchical node that the agent is currently in. Public ##### int hierarchicalNodeIndex The index of the hierarchical node that the agent is currently in. Will be -1 if the hierarchical node index is not known. See [HierarchicalGraph](https://arongranberg.com/astar/docs/hierarchicalgraph.html) [MovementState.hierarchicalNodeIndex](https://arongranberg.com/astar/docs/movementstate.html#hierarchicalNodeIndex) maxSpeed The maximum speed at which the agent may move, in meters per second. Public ##### float maxSpeed The maximum speed at which the agent may move, in meters per second. It is recommended to keep this slightly above [speed](https://arongranberg.com/astar/docs/movementcontrol.html#speed) , to allow the local avoidance system to move agents around more efficiently when necessary. overrideLocalAvoidance If true, this agent will ignore other agents during local avoidance, but other agents will still avoid this one. Public ##### bool overrideLocalAvoidance If true, this agent will ignore other agents during local avoidance, but other agents will still avoid this one. This is useful for example for a player character which should not avoid other agents, but other agents should avoid the player. rotationSpeed The speed at which the agent should rotate towards [targetRotation](https://arongranberg.com/astar/docs/movementcontrol.html#targetRotation) + [targetRotationOffset](https://arongranberg.com/astar/docs/movementcontrol.html#targetRotationOffset) , in radians per second. Public ##### float rotationSpeed The speed at which the agent should rotate towards [targetRotation](https://arongranberg.com/astar/docs/movementcontrol.html#targetRotation) + [targetRotationOffset](https://arongranberg.com/astar/docs/movementcontrol.html#targetRotationOffset) , in radians per second. speed The speed at which the agent should move towards [targetPoint](https://arongranberg.com/astar/docs/movementcontrol.html#targetPoint) , in meters per second. Public ##### float speed The speed at which the agent should move towards [targetPoint](https://arongranberg.com/astar/docs/movementcontrol.html#targetPoint) , in meters per second. targetPoint The point the agent should move towards. Public ##### float3 targetPoint The point the agent should move towards. targetRotation The desired rotation of the agent, in radians, relative to the current movement plane. Public ##### float targetRotation The desired rotation of the agent, in radians, relative to the current movement plane. When rotating the agent visually, the [targetRotationOffset](https://arongranberg.com/astar/docs/movementcontrol.html#targetRotationOffset) should also be added to this value. See [NativeMovementPlane.ToWorldRotation](https://arongranberg.com/astar/docs/nativemovementplane/toworldrotation.html#ToWorldRotation) [AgentMovementPlane](https://arongranberg.com/astar/docs/agentmovementplane.html) targetRotationHint The desired rotation of the agent, in radians, over a longer time horizon, relative to the current movement plane. Public ##### float targetRotationHint The desired rotation of the agent, in radians, over a longer time horizon, relative to the current movement plane. The [targetRotation](https://arongranberg.com/astar/docs/movementcontrol.html#targetRotation) is usually only over a very short time-horizon, usually a single simulation time step. This variable is used to provide a hint of where the agent wants to rotate to over a slightly longer time scale (on the order of a second or so). It is not used to control movement directly, but it may be used to guide animations, or rotation smoothing. If no better hint is available, this should be set to the same value as [targetRotation](https://arongranberg.com/astar/docs/movementcontrol.html#targetRotation) . See [NativeMovementPlane.ToWorldRotation](https://arongranberg.com/astar/docs/nativemovementplane/toworldrotation.html#ToWorldRotation) [AgentMovementPlane](https://arongranberg.com/astar/docs/agentmovementplane.html) targetRotationOffset Additive modifier to [targetRotation](https://arongranberg.com/astar/docs/movementcontrol.html#targetRotation) , in radians. Public ##### float targetRotationOffset Additive modifier to [targetRotation](https://arongranberg.com/astar/docs/movementcontrol.html#targetRotation) , in radians. This is used by the local avoidance system to rotate the agent, without this causing a feedback loop. This extra rotation will be ignored by the control system which decides how the agent \*wants\* to move. It will instead be directly applied to the agent. See [MovementState.rotationOffset](https://arongranberg.com/astar/docs/movementstate.html#rotationOffset) , which must be updated after rotating the agent using this value. --- # CopyJob - A* Pathfinding Project Struct CopyJob Extends IJobEntity ================================= Public Public Methods -------------- [Execute](https://arongranberg.com/astar/docs/copyjob/execute.html#Execute) (control, resolved) --- # CopyRotationJob - A* Pathfinding Project Struct CopyRotationJob Extends IJobEntity ========================================= Public Public Methods -------------- [Execute](https://arongranberg.com/astar/docs/copyrotationjob/execute.html#Execute) (control, resolved) --- # FollowerControlSystem - A* Pathfinding Project Struct FollowerControlSystem Extends ISystem ============================================ Public Public Methods -------------- [OnCreate](https://arongranberg.com/astar/docs/followercontrolsystem/oncreate.html#OnCreate) (state) [OnDestroy](https://arongranberg.com/astar/docs/followercontrolsystem/ondestroy.html#OnDestroy) (state) [OnUpdate](https://arongranberg.com/astar/docs/followercontrolsystem/onupdate.html#OnUpdate) (systemState) [ProcessControlLoop](https://arongranberg.com/astar/docs/followercontrolsystem/processcontrolloop.html#ProcessControlLoop) (systemState, dt) Public Variables ---------------- entityQueryControlManaged Public ##### EntityQuery entityQueryControlManaged entityQueryControlManaged2 Public ##### EntityQuery entityQueryControlManaged2 redrawScope Public ##### RedrawScope redrawScope Public Static Variables ----------------------- MarkerMovementOverrideAfterControl Public Static Readonly ##### ProfilerMarker MarkerMovementOverrideAfterControl = new ProfilerMarker("MovementOverrideAfterControl") MarkerMovementOverrideBeforeControl Public Static Readonly ##### ProfilerMarker MarkerMovementOverrideBeforeControl = new ProfilerMarker("MovementOverrideBeforeControl") --- # GravityState - A* Pathfinding Project Struct GravityState Extends IComponentData, IEnableableComponent ================================================================ Public Agent state related to gravity. Public Variables ---------------- verticalVelocity Current vertical velocity of the agent. Public ##### float verticalVelocity Current vertical velocity of the agent. This is the velocity that the agent is moving with due to gravity. It is not necessarily the same as the Y component of the estimated velocity. --- # EntityDoesNotExistException - A* Pathfinding Project Class EntityDoesNotExistException Extends Exception =================================================== Public Public Methods -------------- [EntityDoesNotExistException](https://arongranberg.com/astar/docs/entitydoesnotexistexception/entitydoesnot.html#EntityDoesNotExistException) () --- # InitManagedStateSystem - A* Pathfinding Project Struct InitManagedStateSystem Extends ISystem ============================================= Public Creates a [ManagedState](https://arongranberg.com/astar/docs/managedstate.html) component for every entity with a [ManagedSettings](https://arongranberg.com/astar/docs/managedsettings.html) component. This ensures all baked [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) entities get a [ManagedState](https://arongranberg.com/astar/docs/managedstate.html) component when they are created. See [ManagedState](https://arongranberg.com/astar/docs/managedstate.html) [PathTracer](https://arongranberg.com/astar/docs/pathtracer.html) [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) Public Methods -------------- [OnUpdate](https://arongranberg.com/astar/docs/initmanagedstatesystem/onupdate.html#OnUpdate) (state) --- # ManagedState - A* Pathfinding Project Class ManagedState Extends IComponentData, IDisposable, ICloneable ================================================================== Public Runtime state for agent movement that requires managed types. The Unity [ECS](https://arongranberg.com/astar/docs/ecs2.html) in general wants everything in components to be unmanaged types. However, some things cannot be unmanaged types, for example delegates, interfaces and objects. There are also other things like path references and node references which are not unmanaged types at the moment. This component is used to store those things. This component is created at runtime and does not store any settings that need to be persistent. Public Methods -------------- [CancelCurrentPathRequest](https://arongranberg.com/astar/docs/managedstate/cancelcurrentpathrequest.html#CancelCurrentPathRequest) () [ClearPath](https://arongranberg.com/astar/docs/managedstate/clearpath.html#ClearPath) () [Dispose](https://arongranberg.com/astar/docs/managedstate/dispose.html#Dispose) () [PopNextLinkFromPath](https://arongranberg.com/astar/docs/managedstate/popnextlinkfrompath.html#PopNextLinkFromPath) () Pops the current part, and the next part from the start of the path. Public Static Methods --------------------- [SetPath](https://arongranberg.com/astar/docs/managedstate/setpath.html#SetPath) (path, state, movementPlane, destination) Make the AI follow the specified path. Public Variables ---------------- activePath [Path](https://arongranberg.com/astar/docs/path.html) that is being followed, if any. Public ##### [Path](https://arongranberg.com/astar/docs/path.html) activePath [Path](https://arongranberg.com/astar/docs/path.html) that is being followed, if any. The agent may have moved away from this path since it was calculated. So it may not be up to date. enableGravity True if gravity is enabled for this agent. Public ##### bool enableGravity = true True if gravity is enabled for this agent. The agent will always fall down according to its own movement plane. The gravity applied is Physics.gravity.y. Enabling this will enable the [GravityState](https://arongranberg.com/astar/docs/gravitystate.html) component of the entity. This has no effect if the agent's orientation is set to YAxisForward (2D mode). Gravity does not really make sense for top-down 2D games. The gravity setting is also hidden from the inspector in this mode. Note When the agent is used in a subscene, this field has no effect at runtime. Instead, disable or enable the [GravityState](https://arongranberg.com/astar/docs/gravitystate.html) component directly. enableLocalAvoidance True if local avoidance is enabled for this agent. Public ##### bool enableLocalAvoidance True if local avoidance is enabled for this agent. Enabling this will automatically add a [Pathfinding.ECS.RVO.RVOAgent](https://arongranberg.com/astar/docs/rvoagent.html) component to the entity. See [Local Avoidance](https://arongranberg.com/astar/docs/localavoidance.html) Note When the agent is used in a subscene, this field has no effect at runtime. Instead, add or remove the [Pathfinding.ECS.RVO.RVOAgent](https://arongranberg.com/astar/docs/rvoagent.html) component. onTraverseOffMeshLink Callback for when the agent starts to traverse an off-mesh link. Public ##### [IOffMeshLinkHandler](https://arongranberg.com/astar/docs/ioffmeshlinkhandler.html) onTraverseOffMeshLink Callback for when the agent starts to traverse an off-mesh link. pathTracer Calculates in which direction to move to follow the path. Public ##### [PathTracer](https://arongranberg.com/astar/docs/pathtracer.html) pathTracer Calculates in which direction to move to follow the path. pathfindingSettings Public ##### [PathRequestSettings](https://arongranberg.com/astar/docs/pathrequestsettings.html) pathfindingSettings pendingPath [Path](https://arongranberg.com/astar/docs/path.html) that is being calculated, if any. Public ##### [Path](https://arongranberg.com/astar/docs/path.html) pendingPath [Path](https://arongranberg.com/astar/docs/path.html) that is being calculated, if any. rvoSettings Local avoidance settings. Public ##### [RVOAgent](https://arongranberg.com/astar/docs/rvoagent.html) rvoSettings = [RVOAgent.Default](https://arongranberg.com/astar/docs/rvoagent.html#Default) Local avoidance settings. When the agent has local avoidance enabled, these settings will be copied into a [Pathfinding.ECS.RVO.RVOAgent](https://arongranberg.com/astar/docs/rvoagent.html) component which is attached to the agent. Note When the agent is used in a subscene, this field has no effect at runtime. Instead, set the data for the [Pathfinding.ECS.RVO.RVOAgent](https://arongranberg.com/astar/docs/rvoagent.html) component. See [enableLocalAvoidance](https://arongranberg.com/astar/docs/managedstate.html#enableLocalAvoidance) Private/Protected Members ------------------------- [Clone](https://arongranberg.com/astar/docs/managedstate/clone.html#Clone) () Clones the managed state for when an entity is duplicated. Deprecated Members ------------------ autoRepath Settings for when to recalculate the path. Public ##### [Pathfinding.AutoRepathPolicy](https://arongranberg.com/astar/docs/autorepathpolicy2.html) autoRepath Settings for when to recalculate the path. Deprecated Use [FollowerEntity.autoRepath](https://arongranberg.com/astar/docs/followerentity.html#autoRepath) , or the [Pathfinding.ECS.AutoRepathPolicy](https://arongranberg.com/astar/docs/autorepathpolicy2.html) component instead. --- # JobAlignAgentWithMovementDirection - A* Pathfinding Project Struct JobAlignAgentWithMovementDirection Extends IJobEntity ============================================================ Public Aligns the agent's rotation with its movement direction, if the local avoidance system is causing it to move differently than expected. Sometimes the agent may want to move in one direction (or stand still), but the local avoidance system tells it to move somewhere completely different. In those cases, we need to adjust the agent's desired rotation to avoid it looking like it's strafing. Public Methods -------------- [Execute](https://arongranberg.com/astar/docs/jobalignagentwithmovementdirection/execut.html#Execute) (transform, movementSettings, movementState, shape, movementPlane, movementControl, resolvedMovement) Public Variables ---------------- dt Public ##### float dt --- # ManagedSettings - A* Pathfinding Project Class ManagedSettings Extends IComponentData, ICloneable, System::IEquatable ============================================================================================= Public Settings for agent movement that require managed types. This component is used to store settings for agent movement that cannot be put anywhere else. For example, it can store delegates, interfaces and objects. It is used by the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component to store settings for how the agent should move. Fortunately, the settings here are not used often, and so putting them in a managed component does not affect performance much. In contrast to [ManagedState](https://arongranberg.com/astar/docs/managedstate.html) , these settings are persistent. See [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) Public Methods -------------- [Clone](https://arongranberg.com/astar/docs/managedsettings/clone.html#Clone) () [CloneAndSimplifyDefaults](https://arongranberg.com/astar/docs/managedsettings/cloneandsimplifydefaults.html#CloneAndSimplifyDefaults) (simplify) [Equals](https://arongranberg.com/astar/docs/managedsettings/equals.html#Equals) (other) Public Variables ---------------- onTraverseOffMeshLink Callback for when the agent starts to traverse an off-mesh link. Public ##### [IOffMeshLinkHandler](https://arongranberg.com/astar/docs/ioffmeshlinkhandler.html) onTraverseOffMeshLink Callback for when the agent starts to traverse an off-mesh link. See [IOffMeshLinkStateMachine.OnTraverseOffMeshLink](https://arongranberg.com/astar/docs/ioffmeshlinkstatemachine/ontraverseoffmes.html#OnTraverseOffMeshLink) [FollowerEntity.onTraverseOffMeshLink](https://arongranberg.com/astar/docs/followerentity.html#onTraverseOffMeshLink) pathfindingSettings Settings for how an agent searches for paths. Public ##### [PathRequestSettings](https://arongranberg.com/astar/docs/pathrequestsettings.html) pathfindingSettings Settings for how an agent searches for paths. This struct contains information about which graphs the agent can use, which nodes it can traverse, and if any nodes should be easier or harder to traverse. A good default value to start from is [PathRequestSettings.Default](https://arongranberg.com/astar/docs/pathrequestsettings.html#Default) . See [FollowerEntity.pathfindingSettings](https://arongranberg.com/astar/docs/followerentity.html#pathfindingSettings) [Path.UseSettings](https://arongranberg.com/astar/docs/path/usesettings.html#UseSettings) --- # JobClearTemporaryData - A* Pathfinding Project Struct JobClearTemporaryData Extends IJobEntity =============================================== Public Public Methods -------------- [Execute](https://arongranberg.com/astar/docs/jobcleartemporarydata/execute.html#Execute) (movementState, movementControl) --- # JobApplyGravity - A* Pathfinding Project Struct JobApplyGravity Extends IJobEntity ========================================= Public Public Methods -------------- [Execute](https://arongranberg.com/astar/docs/jobapplygravity/execute.html#Execute) (transform, movementSettings, movementPlane, gravityState, movementPlaneSource, entityIndexInQuery) [ResolveGravity](https://arongranberg.com/astar/docs/jobapplygravity/resolvegravity.html#ResolveGravity) (hit, grounded, transform, movementPlane, gravityState) Public Variables ---------------- dt Public ##### float dt raycastCommands Public ##### NativeArray raycastCommands raycastHits Public ##### NativeArray<[RaycastHit](https://docs.unity3d.com/ScriptReference/RaycastHit.html) \> raycastHits --- # JobControl - A* Pathfinding Project Struct JobControl Extends IJobEntity, IJobEntityChunkBeginEnd ============================================================= Public Public Methods -------------- [Execute](https://arongranberg.com/astar/docs/jobcontrol/execute.html#Execute) (transform, state, destination, shape, movementPlane, settings, resolvedMovement, controlOutput) [OnChunkBegin](https://arongranberg.com/astar/docs/jobcontrol/onchunkbegin.html#OnChunkBegin) (chunk, unfilteredChunkIndex, useEnabledMask, chunkEnabledMask) [OnChunkEnd](https://arongranberg.com/astar/docs/jobcontrol/onchunkend.html#OnChunkEnd) (chunk, unfilteredChunkIndex, useEnabledMask, chunkEnabledMask, chunkWasExecuted) Public Static Methods --------------------- [ClampToNavmesh](https://arongranberg.com/astar/docs/jobcontrol/clamptonavmesh.html#ClampToNavmesh) (position, closestOnNavmesh, shape, movementPlane) Public Variables ---------------- draw Public ##### CommandBuilder draw dt Public ##### float dt edgesScratch Public ##### NativeList edgesScratch indicesScratch Public ##### NativeList indicesScratch navmeshEdgeData Public ##### [NavmeshEdges.NavmeshBorderData](https://arongranberg.com/astar/docs/navmeshborderdata.html) navmeshEdgeData Private/Protected Members ------------------------- MarkerConvertObstacles Private Static Readonly ##### ProfilerMarker MarkerConvertObstacles = new ProfilerMarker("ConvertObstacles") --- # JobDrawFollowerGizmosBase - A* Pathfinding Project Struct JobDrawFollowerGizmosBase Extends IJobEntity, IJobEntityChunkBeginEnd ============================================================================ Public Public Methods -------------- [Execute](https://arongranberg.com/astar/docs/jobdrawfollowergizmosbase/execute.html#Execute) (transform, shape, destination) [OnChunkBegin](https://arongranberg.com/astar/docs/jobdrawfollowergizmosbase/onchunkbegin.html#OnChunkBegin) (chunk, unfilteredChunkIndex, useEnabledMask, chunkEnabledMask) [OnChunkEnd](https://arongranberg.com/astar/docs/jobdrawfollowergizmosbase/onchunkend.html#OnChunkEnd) (chunk, unfilteredChunkIndex, useEnabledMask, chunkEnabledMask, chunkWasExecuted) Public Static Methods --------------------- [DrawGizmos](https://arongranberg.com/astar/docs/jobdrawfollowergizmosbase/drawgizmos.html#DrawGizmos) (draw, transform, shape, destination, draw2D) Public Variables ---------------- draw Public ##### CommandBuilder draw orientation Public ##### [OrientationMode](https://arongranberg.com/astar/docs/pathfinding.html#OrientationMode) orientation Private/Protected Members ------------------------- ShapeGizmoColor Internal Static Readonly ##### UnityEngine.Color ShapeGizmoColor = new UnityEngine.Color(240/255f, 213/255f, 30/255f) --- # JobManagedMovementOverrideAfterControl - A* Pathfinding Project Struct JobManagedMovementOverrideAfterControl Extends IJobEntity ================================================================ Public Public Methods -------------- [Execute](https://arongranberg.com/astar/docs/jobmanagedmovementoverrideaftercontrol/ex.html#Execute) (managedOverride, entity, localTransform, shape, movementPlane, destination, movementState, movementSettings, movementControl) Public Variables ---------------- dt Public ##### float dt --- # JobManagedMovementOverrideBeforeControl - A* Pathfinding Project Struct JobManagedMovementOverrideBeforeControl Extends IJobEntity ================================================================= Public Public Methods -------------- [Execute](https://arongranberg.com/astar/docs/jobmanagedmovementoverridebeforecontrol/e.html#Execute) (managedOverride, entity, localTransform, shape, movementPlane, destination, movementState, movementSettings) Public Variables ---------------- dt Public ##### float dt --- # JobManagedMovementOverrideBeforeMovement - A* Pathfinding Project Struct JobManagedMovementOverrideBeforeMovement Extends IJobEntity ================================================================== Public Public Methods -------------- [Execute](https://arongranberg.com/astar/docs/jobmanagedmovementoverridebeforemovement/.html#Execute) (managedOverride, entity, localTransform, shape, movementPlane, destination, movementState, movementSettings, movementControl, resolvedMovement) Public Variables ---------------- dt Public ##### float dt --- # JobManagedOffMeshLinkTransition - A* Pathfinding Project Struct JobManagedOffMeshLinkTransition Extends IJobEntity ========================================================= Public Public Methods -------------- [Execute](https://arongranberg.com/astar/docs/jobmanagedoffmeshlinktransition/execute.html#Execute) (entity, state, transform, movementPlane, movementControl, movementSettings, linkInfo, managedLinkInfo, movementDisabled, localAvoidanceDisabled) Public Static Methods --------------------- [MoveNext](https://arongranberg.com/astar/docs/jobmanagedoffmeshlinktransition/movenext.html#MoveNext) (entity, state, transform, movementPlane, movementControl, movementSettings, linkInfo, managedLinkInfo, movementDisabled, localAvoidanceDisabled, deltaTime) Public Variables ---------------- commandBuffer Public ##### EntityCommandBuffer commandBuffer deltaTime Public ##### float deltaTime --- # JobDrawFollowerGizmos - A* Pathfinding Project Struct JobDrawFollowerGizmos Extends IJobChunk ============================================== Public Public Methods -------------- [Execute](https://arongranberg.com/astar/docs/jobdrawfollowergizmos/execute.html) (...) Public Variables ---------------- AgentCylinderShapeHandleRO Public ##### ComponentTypeHandle<[AgentCylinderShape](https://arongranberg.com/astar/docs/agentcylindershape.html) \> AgentCylinderShapeHandleRO AgentMovementPlaneHandleRO Public ##### ComponentTypeHandle<[AgentMovementPlane](https://arongranberg.com/astar/docs/agentmovementplane.html) \> AgentMovementPlaneHandleRO LocalTransformTypeHandleRO Public ##### ComponentTypeHandle LocalTransformTypeHandleRO ManagedStateHandleRW Public ##### ComponentTypeHandle<[ManagedState](https://arongranberg.com/astar/docs/managedstate.html) \> ManagedStateHandleRW MovementSettingsHandleRO Public ##### ComponentTypeHandle<[MovementSettings](https://arongranberg.com/astar/docs/movementsettings.html) \> MovementSettingsHandleRO MovementStateHandleRO Public ##### ComponentTypeHandle<[MovementState](https://arongranberg.com/astar/docs/movementstate.html) \> MovementStateHandleRO ResolvedMovementHandleRO Public ##### ComponentTypeHandle<[ResolvedMovement](https://arongranberg.com/astar/docs/resolvedmovement.html) \> ResolvedMovementHandleRO draw Public ##### CommandBuilder draw entityManagerHandle Public ##### [GCHandle](https://arongranberg.com/astar/docs/%3Cundefined%3E) entityManagerHandle scratchBuffer1 Public ##### NativeList scratchBuffer1 scratchBuffer2 Public ##### NativeArray scratchBuffer2 Public Static Variables ----------------------- InternalRotation Public Static Readonly ##### UnityEngine.Color InternalRotation = Palette.Colorbrewer.Set1.Orange Path Public Static Readonly ##### UnityEngine.Color Path = Palette.Colorbrewer.Set1.Orange TargetInternalRotation Public Static Readonly ##### UnityEngine.Color TargetInternalRotation = Palette.Colorbrewer.Set1.Yellow TargetInternalRotationHint Public Static Readonly ##### UnityEngine.Color TargetInternalRotationHint = Palette.Colorbrewer.Set1.Pink UnsmoothedRotation Public Static Readonly ##### UnityEngine.Color UnsmoothedRotation = Palette.Colorbrewer.Set1.Purple VisualRotationColor Public Static Readonly ##### UnityEngine.Color VisualRotationColor = Palette.Colorbrewer.Set1.Blue --- # JobManagedOffMeshLinkTransitionCleanup - A* Pathfinding Project Struct JobManagedOffMeshLinkTransitionCleanup Extends IJobEntity ================================================================ Public Public Methods -------------- [Execute](https://arongranberg.com/astar/docs/jobmanagedoffmeshlinktransitioncleanup/ex.html#Execute) (managedLinkInfo) --- # JobPrepareAgentRaycasts - A* Pathfinding Project Struct JobPrepareAgentRaycasts Extends IJobEntity ================================================= Public Public Methods -------------- [ApplyGravity](https://arongranberg.com/astar/docs/jobprepareagentraycasts/applygravity.html#ApplyGravity) (gravityState) [CalculateRaycastCommands](https://arongranberg.com/astar/docs/jobprepareagentraycasts/calculateraycastc.html#CalculateRaycastCommands) (transform, shape, movementPlane, movementSettings, gravityState, physicsScene) [Execute](https://arongranberg.com/astar/docs/jobprepareagentraycasts/execute.html#Execute) (transform, shape, movementPlane, state, movementSettings, resolvedMovement, movementStatistics, gravityState, physicsWorldIndex, entityIndexInQuery) Public Variables ---------------- dt Public ##### float dt gravity Public ##### float gravity raycastCommands Public ##### NativeArray raycastCommands raycastQueryParameters Public ##### QueryParameters raycastQueryParameters --- # JobMoveAgent - A* Pathfinding Project Struct JobMoveAgent Extends IJobEntity ====================================== Public Public Methods -------------- [Execute](https://arongranberg.com/astar/docs/jobmoveagent/execute.html#Execute) (transform, shape, movementPlane, state, movementSettings, resolvedMovement, movementStatistics) Public Static Methods --------------------- [MoveAgent](https://arongranberg.com/astar/docs/jobmoveagent/moveagent.html#MoveAgent) (transform, shape, movementPlane, state, movementSettings, resolvedMovement, movementStatistics, dt) [MoveWithoutGravity](https://arongranberg.com/astar/docs/jobmoveagent/movewithoutgravity.html#MoveWithoutGravity) (position, resolvedMovement, movementPlane, dt) Calculates the amount the agent should move during this simulation step, based on the [ResolvedMovement](https://arongranberg.com/astar/docs/resolvedmovement.html) component. [ResolvePositionSmoothing](https://arongranberg.com/astar/docs/jobmoveagent/resolvepositionsmoothing.html#ResolvePositionSmoothing) (movementDelta, state, movementSettings, dt) [ResolveRotation](https://arongranberg.com/astar/docs/jobmoveagent/resolverotation.html#ResolveRotation) (rotation, state, resolvedMovement, movementSettings, movementPlane, dt) Calculates the final rotation for the agent on this simulation step, based on the [ResolvedMovement](https://arongranberg.com/astar/docs/resolvedmovement.html) component. Public Variables ---------------- dt Public ##### float dt --- # FollowerEntityProxy - A* Pathfinding Project Struct FollowerEntityProxy Extends [IAstarAI](https://arongranberg.com/astar/docs/iastarai.html) ================================================================================================= Public Proxy for a [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) using pure [ECS](https://arongranberg.com/astar/docs/ecs2.html) components. This struct behaves almost identically to the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) MonoBehaviour component, but it wraps an Entity in a given world instead. It is used primarily when you are using subscenes, and therefore cannot use the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component at runtime. This struct gives you the same high-level API as the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component, but without the overhead of dealing with GameObjects and MonoBehaviours. Warning This struct can only be used on the main thread outside of [ECS](https://arongranberg.com/astar/docs/ecs2.html) jobs. When accessing [ECS](https://arongranberg.com/astar/docs/ecs2.html) components from within jobs, you must use the [ECS](https://arongranberg.com/astar/docs/ecs2.html) api directly. Usage ----- 1. Create a subscene (see unity entities documentation). 2. Create an agent GameObject with a [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component within that subscene. 3. At runtime, the GameObject will be automatically converted to an entity. 4. You can then use the [FollowerEntityProxy](https://arongranberg.com/astar/docs/followerentityproxy.html) struct to interact with the entity. `var follower = new [FollowerEntityProxy](https://arongranberg.com/astar/docs/followerentityproxy/followerentityproxy.html#FollowerEntityProxy) ([world](https://arongranberg.com/astar/docs/followerentityproxy.html#world) , [entity](https://arongranberg.com/astar/docs/followerentityproxy.html#entity) ); follower.maxSpeed = 5; follower.destination = new Vector3(1, 2, 3); if (follower.currentNode.Tag == 1) { Debug.Log("The agent is right now traversing a node with tag 1"); } ` See [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) Inner Types ----------- [EntityDoesNotExistException](https://arongranberg.com/astar/docs/entitydoesnotexistexception.html) Public Methods -------------- [AssertEntityExists](https://arongranberg.com/astar/docs/followerentityproxy/assertentityexists.html#AssertEntityExists) () [Destroy](https://arongranberg.com/astar/docs/followerentityproxy/destroy.html#Destroy) () Destroys the entity and clears the proxy. [FinalizeMovement](https://arongranberg.com/astar/docs/followerentityproxy/finalizemovement.html#FinalizeMovement) (nextPosition, nextRotation) Move the agent. [FollowerEntityProxy](https://arongranberg.com/astar/docs/followerentityproxy/followerentityproxy.html#FollowerEntityProxy) (world, entity) [GetRemainingPath](https://arongranberg.com/astar/docs/followerentityproxy/getremainingpath.html) (buffer, \[partsBuffer\], stale) Fills **buffer** with the remaining path. [Move](https://arongranberg.com/astar/docs/followerentityproxy/move.html#Move) (deltaPosition) Move the agent. [MovementUpdate](https://arongranberg.com/astar/docs/followerentityproxy/movementupdate.html#MovementUpdate) (deltaTime, nextPosition, nextRotation) Calculate how the agent will move during this frame. [SearchPath](https://arongranberg.com/astar/docs/followerentityproxy/searchpath.html#SearchPath) () Recalculate the current path. [SetDestination](https://arongranberg.com/astar/docs/followerentityproxy/setdestination.html#SetDestination) (destination, facingDirection=…) Set the position in the world that this agent should move to. [SetPath](https://arongranberg.com/astar/docs/followerentityproxy/setpath.html#SetPath) (path, updateDestinationFromPath=true) Make the AI follow the specified path. [Teleport](https://arongranberg.com/astar/docs/followerentityproxy/teleport.html#Teleport) (newPosition, clearPath=true) Instantly move the agent to a new position. Public Static Methods --------------------- [DisposeScratchData](https://arongranberg.com/astar/docs/followerentityproxy/disposescratchdata.html#DisposeScratchData) () [InitScratchData](https://arongranberg.com/astar/docs/followerentityproxy/initscratchdata.html#InitScratchData) () Public Variables ---------------- autoRepath Policy for when the agent recalculates its path. Public ##### [ECS.AutoRepathPolicy](https://arongranberg.com/astar/docs/autorepathpolicy2.html) ? autoRepath Policy for when the agent recalculates its path. See [ECS.AutoRepathPolicy](https://arongranberg.com/astar/docs/autorepathpolicy2.html) currentNode Node which the agent is currently traversing. Public ##### [GraphNode](https://arongranberg.com/astar/docs/graphnode.html) currentNode Node which the agent is currently traversing. You can, for example, use this to make the agent use a different animation when traversing nodes with a specific tag. Note Will be null if the agent does not have a path, or if the node under the agent has just been destroyed by a graph update. When traversing an off-mesh link, this will return the final non-link node in the path before the agent started traversing the link. debugFlags Enables or disables debug drawing for this agent. Public ##### [PIDMovement.DebugFlags](https://arongranberg.com/astar/docs/pidmovement.html#DebugFlags) ? debugFlags Enables or disables debug drawing for this agent. This is a bitmask with multiple flags so that you can choose exactly what you want to debug. See [PIDMovement.DebugFlags](https://arongranberg.com/astar/docs/pidmovement.html#DebugFlags) [Bitmask Tutorial](https://arongranberg.com/astar/docs/bitmasks.html) desiredVelocity Velocity that this agent wants to move with. Public ##### [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) desiredVelocity Velocity that this agent wants to move with. Includes gravity and local avoidance if applicable. In world units per second. See [velocity](https://arongranberg.com/astar/docs/followerentity.html#velocity) Note The [Pathfinding.AILerp](https://arongranberg.com/astar/docs/ailerp.html) movement script doesn't use local avoidance or gravity so this property will always be identical to [velocity](https://arongranberg.com/astar/docs/followerentity.html#velocity) on that component. desiredVelocityWithoutLocalAvoidance Velocity that this agent wants to move with before taking local avoidance into account. Public ##### [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) desiredVelocityWithoutLocalAvoidance Velocity that this agent wants to move with before taking local avoidance into account. Includes gravity. In world units per second. Setting this property will set the current velocity that the agent is trying to move with, including gravity. This can be useful if you want to make the agent come to a complete stop in a single frame or if you want to modify the velocity in some way. `// Set the velocity to zero, but keep the current gravity var newVelocity = new Vector3(0, ai.desiredVelocityWithoutLocalAvoidance.y, 0); ai.desiredVelocityWithoutLocalAvoidance = newVelocity; ` Note The [Pathfinding.AILerp](https://arongranberg.com/astar/docs/ailerp.html) movement script doesn't use local avoidance so this property will always be identical to [velocity](https://arongranberg.com/astar/docs/followerentity.html#velocity) on that component. Warning Trying to set this property on an [AILerp](https://arongranberg.com/astar/docs/ailerp.html) component will throw an exception since its velocity cannot meaningfully be changed abitrarily. If you are not using local avoidance then this property will in almost all cases be identical to [desiredVelocity](https://arongranberg.com/astar/docs/followerentity.html#desiredVelocity) plus some noise due to floating point math. See [velocity](https://arongranberg.com/astar/docs/followerentity.html#velocity) [desiredVelocity](https://arongranberg.com/astar/docs/followerentity.html#desiredVelocity) [Move](https://arongranberg.com/astar/docs/followerentity/move.html#Move) [MovementUpdate](https://arongranberg.com/astar/docs/followerentity/movementupdate.html#MovementUpdate) destination Position in the world that this agent should move to. Public ##### Vector3? destination Position in the world that this agent should move to. If no destination has been set yet, then (+infinity, +infinity, +infinity) will be returned. Setting this property will immediately try to repair the path if the agent already has a path. This will also immediately update properties like [reachedDestination](https://arongranberg.com/astar/docs/followerentity.html#reachedDestination) , [reachedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedEndOfPath) and [remainingDistance](https://arongranberg.com/astar/docs/followerentity.html#remainingDistance) . The agent may do a full path recalculation if the local repair was not sufficient, but this will at earliest happen in the next simulation step. `IEnumerator [Start](https://arongranberg.com/astar/docs/followerentity/start.html#Start) () { ai.destination = somePoint; // Wait until the AI has reached the destination while (!ai.reachedEndOfPath) { yield return null; } // The agent has reached the destination now } ` See [SetDestination](https://arongranberg.com/astar/docs/followerentity/setdestination.html#SetDestination) , which also allows you to set a facing direction for the agent. destinationFacingDirection Direction the agent will try to face when it reaches the destination. Public ##### Vector3? destinationFacingDirection Direction the agent will try to face when it reaches the destination. If this is zero, the agent will not try to face any particular direction. The following video shows three agents, one with no facing direction set, and then two agents with varying values of the [lead in radius](https://arongranberg.com/astar/docs/pidmovement.html#leadInRadiusWhenApproachingDestination) . Your browser does not support the video tag. To set this, use [SetDestination](https://arongranberg.com/astar/docs/followerentity/setdestination.html#SetDestination) . See [MovementSettings.follower.leadInRadiusWhenApproachingDestination](https://arongranberg.com/astar/docs/pidmovement.html#leadInRadiusWhenApproachingDestination) [SetDestination](https://arongranberg.com/astar/docs/followerentity/setdestination.html#SetDestination) enableGravity Enables or disables gravity. Public ##### bool enableGravity Enables or disables gravity. If gravity is enabled, the agent will accelerate downwards, and use a raycast to check if it should stop falling. This has no effect if the agent's [orientation](https://arongranberg.com/astar/docs/followerentity.html#orientation) is set to YAxisForward (2D mode). Gravity does not really make sense for top-down 2D games. The gravity setting is also hidden from the inspector in this mode. See [groundMask](https://arongranberg.com/astar/docs/followerentity.html#groundMask) enableLocalAvoidance True if local avoidance is enabled for this agent. Public ##### bool enableLocalAvoidance True if local avoidance is enabled for this agent. Enabling this will automatically add a [Pathfinding.ECS.RVO.RVOAgent](https://arongranberg.com/astar/docs/rvoagent.html) component to the entity. See [Local Avoidance](https://arongranberg.com/astar/docs/localavoidance.html) Note When the agent is used in a subscene, this field has no effect at runtime. Instead, add or remove the [Pathfinding.ECS.RVO.RVOAgent](https://arongranberg.com/astar/docs/rvoagent.html) component. Note Setting this property cannot be done via this proxy. Instead, you must add or remove the [RVOAgent](https://arongranberg.com/astar/docs/rvoagent.html) component from the entity. See [FollowerEntity.enableLocalAvoidance](https://arongranberg.com/astar/docs/followerentity.html#enableLocalAvoidance) , which supports both get and set. [rvoSettings](https://arongranberg.com/astar/docs/followerentityproxy.html#rvoSettings) endOfPath End point of path the agent is currently following. Public ##### [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) endOfPath End point of path the agent is currently following. If the agent has no path (or if it's not calculated yet), this will return the [destination](https://arongranberg.com/astar/docs/followerentityproxy.html#destination) instead. If the agent has no destination it will return the agent's current position. The end of the path is usually identical or very close to the [destination](https://arongranberg.com/astar/docs/followerentityproxy.html#destination) , but it may differ if the path for example was blocked by a wall, so that the agent couldn't get any closer. See [GetRemainingPath](https://arongranberg.com/astar/docs/followerentity/getremainingpath.html#GetRemainingPath) entity Public ##### Entity entity entityExists True if the [entity](https://arongranberg.com/astar/docs/followerentityproxy.html#entity) exists. Public ##### bool entityExists True if the [entity](https://arongranberg.com/astar/docs/followerentityproxy.html#entity) exists. This is typically true if the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component is active and enabled and the game is running. See [entity](https://arongranberg.com/astar/docs/followerentityproxy.html#entity) groundMask Determines which layers the agent will stand on. Public ##### LayerMask? groundMask Determines which layers the agent will stand on. The agent will use a raycast each frame to check if it should stop falling. This layer mask should ideally not contain the agent's own layer, if the agent has a collider, as this may cause it to try to stand on top of itself. hasPath True if this agent currently has a valid path that it follows. Public ##### bool hasPath True if this agent currently has a valid path that it follows. This is true if the agent has a path and the path is not stale. A path may become stale if the graph is updated close to the agent and it hasn't had time to recalculate its path yet. height Height of the agent in world units. Public ##### float? height Height of the agent in world units. This is visualized in the scene view as a yellow cylinder around the character. This value is used for various heuristics, and for visualization purposes. For example, the destination is only considered reached if the destination is not above the agent's head, and it's not more than half the agent's height below its feet. If local lavoidance is enabled, this is also used to filter out collisions with agents and obstacles that are too far above or below the agent. isStopped Gets or sets if the agent should stop moving. Public ##### bool? isStopped Gets or sets if the agent should stop moving. If this is set to true the agent will immediately start to slow down as quickly as it can to come to a full stop. The agent will still react to local avoidance and gravity (if applicable), but it will not try to move in any particular direction. The current path of the agent will not be cleared, so when this is set to false again the agent will continue moving along the previous path. This is a purely user-controlled parameter, so for example it is not set automatically when the agent stops moving because it has reached the target. Use [reachedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedEndOfPath) for that. If this property is set to true while the agent is traversing an off-mesh link ([RichAI](https://arongranberg.com/astar/docs/richai.html) script only), then the agent will continue traversing the link and stop once it has completed it. Note This is not the same as the [simulateMovement](https://arongranberg.com/astar/docs/followerentity.html#simulateMovement) setting which some movement scripts have. The [simulateMovement](https://arongranberg.com/astar/docs/followerentity.html#simulateMovement) setting disables movement calculations completely (which among other things makes it not be affected by local avoidance or gravity). For the [AILerp](https://arongranberg.com/astar/docs/ailerp.html) movement script which doesn't use gravity or local avoidance anyway changing this property is very similar to changing [simulateMovement](https://arongranberg.com/astar/docs/followerentity.html#simulateMovement) . The [steeringTarget](https://arongranberg.com/astar/docs/followerentity.html#steeringTarget) property will continue to indicate the point which the agent would move towards if it would not be stopped. For most movement scripts, this will make the agent slow down quickly, but not instantly stop. If you want to instantly stop the agent, you could either disable the whole component instead (but then it will not react to local avoidance, of course, and it will clear its current path), or you could set [desiredVelocityWithoutLocalAvoidance](https://arongranberg.com/astar/docs/followerentity.html#desiredVelocityWithoutLocalAvoidance) to Vector3.zero, which will stop it immediately. isTraversingOffMeshLink True if the agent is currently traversing an off-mesh link. Public ##### bool isTraversingOffMeshLink True if the agent is currently traversing an off-mesh link. See [Off-mesh links](https://arongranberg.com/astar/docs/offmeshlinks2.html) [onTraverseOffMeshLink](https://arongranberg.com/astar/docs/followerentity.html#onTraverseOffMeshLink) [offMeshLink](https://arongranberg.com/astar/docs/followerentity.html#offMeshLink) localAvoidanceTemporarilyDisabled True if the agent's local avoidance is temporarily disabled, due to traversing an off-mesh link. Public ##### bool localAvoidanceTemporarilyDisabled True if the agent's local avoidance is temporarily disabled, due to traversing an off-mesh link. When traversing an off-mesh link, the traversal code may temporarily disable local avoidance to allow the agent to traverse the link without being pushed around by other agents. See [AgentOffMeshLinkLocalAvoidanceDisabled](https://arongranberg.com/astar/docs/agentoffmeshlinklocalavoidancedisabled.html) [AgentOffMeshLinkTraversalContext.DisableLocalAvoidance](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext/disablel.html#DisableLocalAvoidance) When the agent is not traversing an off-mesh link, this will always return false. Note A false value does not imply that the agent is actually using local avoidance. See [enableLocalAvoidance](https://arongranberg.com/astar/docs/followerentityproxy.html#enableLocalAvoidance) for that. maxRotationSpeed Maximum rotation speed in degrees per second. Public ##### float? maxRotationSpeed Maximum rotation speed in degrees per second. If the agent would have to rotate faster than this, it will instead slow down to get more time to rotate. The agent may want to rotate faster than [rotationSpeed](https://arongranberg.com/astar/docs/pidmovement.html#rotationSpeed) if there's not enough space, so that it has to move in a more narrow arc. It may also want to rotate faster if it is very close to its destination and it wants to make sure it ends up on the right spot without any circling. It is recommended to keep this at a value slightly larger than [rotationSpeed](https://arongranberg.com/astar/docs/pidmovement.html#rotationSpeed) . See [rotationSpeed](https://arongranberg.com/astar/docs/pidmovement.html#rotationSpeed) maxSpeed Max speed in world units per second. Public ##### float? maxSpeed Max speed in world units per second. movementOverrides Provides callbacks during various parts of the movement calculations. Public ##### [ManagedMovementOverrides](https://arongranberg.com/astar/docs/managedmovementoverrides.html) movementOverrides Provides callbacks during various parts of the movement calculations. With this property you can register callbacks that will be called during various parts of the movement calculations. These can be used to modify movement of the agent. The following example demonstrates how one can hook into one of the available phases and modify the agent's movement. In this case, the movement is modified to become wavy. Your browser does not support the video tag. `using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) ; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) .[ECS](https://arongranberg.com/astar/docs/ecs2.html) ; using Unity.Entities; using Unity.[Mathematics](https://arongranberg.com/astar/docs/mathematics.html) ; using Unity.Transforms; using UnityEngine; public class MovementModifierNoise : MonoBehaviour { public float strength = 1; public float frequency = 1; float phase; public void [Start](https://arongranberg.com/astar/docs/followerentity/start.html#Start) () { // Register a callback to modify the movement. // This will be called during every simulation step for the agent. // This may be called multiple times per frame if the time scale is high or fps is low, // or less than once per frame, if the fps is very high. GetComponent().movementOverrides.AddBeforeControlCallback(MovementOverride); // Randomize a phase, to make different agents behave differently phase = UnityEngine.Random.value * 1000; } public void [OnDisable](https://arongranberg.com/astar/docs/followerentity/ondisable.html#OnDisable) () { // Remove the callback when the component is disabled GetComponent().movementOverrides.RemoveBeforeControlCallback(MovementOverride); } public void MovementOverride (Entity [entity](https://arongranberg.com/astar/docs/followerentity.html#entity) , float dt, ref LocalTransform localTransform, ref AgentCylinderShape [shape](https://arongranberg.com/astar/docs/followerentity.html#shape) , ref AgentMovementPlane [movementPlane](https://arongranberg.com/astar/docs/followerentity.html#movementPlane) , ref DestinationPoint [destination](https://arongranberg.com/astar/docs/followerentity.html#destination) , ref MovementState movementState, ref MovementSettings [movementSettings](https://arongranberg.com/astar/docs/followerentity.html#movementSettings) ) { // Rotate the next corner the agent is moving towards around the agent by a random angle. // This will make the agent appear to move in a drunken fashion. // Don't modify the movement as much if we are very close to the end of the path var strengthMultiplier = Mathf.Min(1, movementState.remainingDistanceToEndOfPart / Mathf.Max([shape](https://arongranberg.com/astar/docs/followerentity.html#shape) .[radius](https://arongranberg.com/astar/docs/agentcylindershape.html#radius) , [movementSettings](https://arongranberg.com/astar/docs/followerentity.html#movementSettings) .[follower](https://arongranberg.com/astar/docs/movementsettings.html#follower) .[slowdownTime](https://arongranberg.com/astar/docs/pidmovement.html#slowdownTime) * [movementSettings](https://arongranberg.com/astar/docs/followerentity.html#movementSettings) .[follower](https://arongranberg.com/astar/docs/movementsettings.html#follower) .[speed](https://arongranberg.com/astar/docs/pidmovement.html#speed) )); strengthMultiplier *= strengthMultiplier; // Generate a smoothly varying rotation angle var rotationAngleRad = strength * strengthMultiplier * (Mathf.PerlinNoise1D(Time.time * frequency + phase) - 0.5f); // Clamp it to at most plus or minus 90 degrees rotationAngleRad = Mathf.Clamp(rotationAngleRad, -math.PI*0.5f, math.PI*0.5f); // Convert the rotation angle to a world-space quaternion. // We use the movement plane to rotate around the agent's up axis, // making this code work in both 2D and 3D games. var [rotation](https://arongranberg.com/astar/docs/followerentity.html#rotation) = [movementPlane](https://arongranberg.com/astar/docs/followerentity.html#movementPlane) .value.[ToWorldRotation](https://arongranberg.com/astar/docs/nativemovementplane/toworldrotation.html#ToWorldRotation) (rotationAngleRad); // Rotate the direction to the next corner around the agent movementState.nextCorner = localTransform.Position + math.mul([rotation](https://arongranberg.com/astar/docs/followerentity.html#rotation) , movementState.nextCorner - localTransform.Position); } } `There are a few different phases that you can register callbacks for: * **BeforeControl:** Called before the agent's movement is calculated. At this point, the agent has a valid path, and the next corner that is moving towards has been calculated. * **AfterControl:** Called after the agent's desired movement is calculated. The agent has stored its desired movement in the [MovementControl](https://arongranberg.com/astar/docs/movementcontrol.html) component. Local avoidance has not yet run. * **BeforeMovement:** Called right before the agent's movement is applied. At this point the agent's final movement (including local avoidance) is stored in the [ResolvedMovement](https://arongranberg.com/astar/docs/resolvedmovement.html) component, which you may modify. Warning If any agent has a callback registered here, a sync point will be created for all agents when the callback runs. This can make the simulation not able to utilize multiple threads as effectively. If you have a lot of agents, consider using a custom entity component system instead. But as always, profile first to see if this is actually a problem for your game. The callbacks may be called multiple times per frame, if the fps is low, or if the time scale is high. It may also be called less than once per frame if the fps is very high. Each callback is provided with a **dt** parameter, which is the time in seconds since the last simulation step. You should prefer using this instead of Time.deltaTime. See [simulateMovement](https://arongranberg.com/astar/docs/followerentity.html#simulateMovement) [updatePosition](https://arongranberg.com/astar/docs/followerentity.html#updatePosition) [updateRotation](https://arongranberg.com/astar/docs/followerentity.html#updateRotation) Note This API is unstable. It may change in future versions. movementPlane The plane the agent is moving in. Public ##### [NativeMovementPlane](https://arongranberg.com/astar/docs/nativemovementplane.html) movementPlane The plane the agent is moving in. This is typically the ground plane, which will be the XZ plane in a 3D game, and the XY plane in a 2D game. Ultimately it depends on the graph orientation. If you are doing pathfinding on a spherical world (see [Spherical Worlds](https://arongranberg.com/astar/docs/spherical.html) ), the the movement plane will be the tangent plane of the sphere at the agent's position. movementPlaneSource How to calculate which direction is "up" for the agent. Public ##### [MovementPlaneSource](https://arongranberg.com/astar/docs/ecs2.html#MovementPlaneSource) ? movementPlaneSource How to calculate which direction is "up" for the agent. In almost all cases, you should use the **Graph** option. This will make the agent use the graph's natural "up" direction. However, if you are using a spherical world, or a world with some other strange shape, then you may want to use the NavmeshNormal or Raycast options. See [Spherical Worlds](https://arongranberg.com/astar/docs/spherical.html) movementSettings Various movement settings. Public ##### [MovementSettings](https://arongranberg.com/astar/docs/movementsettings.html) ? movementSettings Various movement settings. Some of these settings are exposed on the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) directly. For example [maxSpeed](https://arongranberg.com/astar/docs/followerentity.html#maxSpeed) . Note The return value is a struct. If you want to change some settings, you'll need to modify the returned struct and then assign it back to this property. nearestNavmeshBorder Border of the navmesh closest to the agent's current position. Public ##### [GraphHitInfo](https://arongranberg.com/astar/docs/graphhitinfo.html) nearestNavmeshBorder Border of the navmesh closest to the agent's current position. The border of the navmesh is what separates the walkable and unwalkable part of the world. ![](https://arongranberg.com/astar/docs/images/navmesh_contour.png) Your browser does not support the video tag. If no border could be found (for example if the agent has no path), then the **hit.point** field will be positive infinity. Note hit.node will always be null, as it is currently not possible for the code to figure out which border belongs to what node. You can call [AstarPath.GetNearest](https://arongranberg.com/astar/docs/astarpath/getnearest.html) with hit.point if you need this information. See [currentNode](https://arongranberg.com/astar/docs/followerentity.html#currentNode) [AstarPath.GetNearestBorder](https://arongranberg.com/astar/docs/astarpath/getnearestborder.html) offMeshLink The off-mesh link that the agent is currently traversing. Public ##### [OffMeshLinks.OffMeshLinkTracer](https://arongranberg.com/astar/docs/offmeshlinktracer.html) offMeshLink The off-mesh link that the agent is currently traversing. This will be a default [OffMeshLinks.OffMeshLinkTracer](https://arongranberg.com/astar/docs/offmeshlinktracer.html) if the agent is not traversing an off-mesh link (the [OffMeshLinks.OffMeshLinkTracer.link](https://arongranberg.com/astar/docs/offmeshlinktracer.html#link) field will be null). Note If the off-mesh link is destroyed while the agent is traversing it, this property will still return the link. But be careful about accessing properties like [OffMeshLinkSource.gameObject](https://arongranberg.com/astar/docs/offmeshlinksource.html#gameObject) , as that may refer to a destroyed gameObject. See [Off-mesh links](https://arongranberg.com/astar/docs/offmeshlinks2.html) [onTraverseOffMeshLink](https://arongranberg.com/astar/docs/followerentity.html#onTraverseOffMeshLink) [isTraversingOffMeshLink](https://arongranberg.com/astar/docs/followerentity.html#isTraversingOffMeshLink) onSearchPath Called when the agent recalculates its path. Public ##### System.Action onSearchPath Called when the agent recalculates its path. This is called both for automatic path recalculations (see [canSearch](https://arongranberg.com/astar/docs/followerentityproxy.html#canSearch) ) and manual ones (see [SearchPath](https://arongranberg.com/astar/docs/followerentityproxy/searchpath.html#SearchPath) ). See Take a look at the [Pathfinding.AIDestinationSetter](https://arongranberg.com/astar/docs/aidestinationsetter.html) source code for an example of how it can be used. onTraverseOffMeshLink Callback to be called when an agent starts traversing an off-mesh link. Public ##### [IOffMeshLinkHandler](https://arongranberg.com/astar/docs/ioffmeshlinkhandler.html) ? onTraverseOffMeshLink Callback to be called when an agent starts traversing an off-mesh link. The handler will be called when the agent starts traversing an off-mesh link. It allows you to to control the agent for the full duration of the link traversal. Use the passed context struct to get information about the link and to control the agent. `using UnityEngine; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) ; using System.[Collections](https://arongranberg.com/astar/docs/collections.html) ; using [Pathfinding](https://arongranberg.com/astar/docs/pathfinding.html) .[ECS](https://arongranberg.com/astar/docs/ecs2.html) ; namespace Pathfinding.Examples { public class FollowerJumpLink : MonoBehaviour, IOffMeshLinkHandler, IOffMeshLinkStateMachine { // Register this class as the handler for off-mesh links when the component is enabled void [OnEnable](https://arongranberg.com/astar/docs/followerentity/onenable.html#OnEnable) () => GetComponent().onTraverseOffMeshLink = this; void [OnDisable](https://arongranberg.com/astar/docs/followerentity/ondisable.html#OnDisable) () => GetComponent().onTraverseOffMeshLink = null; IOffMeshLinkStateMachine IOffMeshLinkHandler.GetOffMeshLinkStateMachine(AgentOffMeshLinkTraversalContext context) => this; void IOffMeshLinkStateMachine.OnFinishTraversingOffMeshLink (AgentOffMeshLinkTraversalContext context) { Debug.Log("An agent finished traversing an off-mesh link"); } void IOffMeshLinkStateMachine.OnAbortTraversingOffMeshLink () { Debug.Log("An agent aborted traversing an off-mesh link"); } IEnumerable IOffMeshLinkStateMachine.OnTraverseOffMeshLink (AgentOffMeshLinkTraversalContext ctx) { var start = (Vector3)ctx.link.relativeStart; var end = (Vector3)ctx.link.relativeEnd; var dir = end - start; // Disable local avoidance while traversing the off-mesh link. // If it was enabled, it will be automatically re-enabled when the agent finishes traversing the link. ctx.DisableLocalAvoidance(); // Move and rotate the agent to face the other side of the link. // When reaching the off-mesh link, the agent may be facing the wrong direction. while (!ctx.MoveTowards( [position](https://arongranberg.com/astar/docs/followerentity.html#position) : start, [rotation](https://arongranberg.com/astar/docs/followerentity.html#rotation) : Quaternion.LookRotation(dir, ctx.movementPlane.up), gravity: true, slowdown: true).reached) { yield return null; } var bezierP0 = start; var bezierP1 = start + Vector3.up*5; var bezierP2 = end + Vector3.up*5; var bezierP3 = end; var jumpDuration = 1.0f; // Animate the AI to jump from the start to the end of the link for (float t = 0; t < jumpDuration; t += ctx.deltaTime) { ctx.transform.Position = AstarSplines.CubicBezier(bezierP0, bezierP1, bezierP2, bezierP3, Mathf.SmoothStep(0, 1, t / jumpDuration)); yield return null; } } } } ` Warning Off-mesh links can be destroyed or disabled at any moment. The built-in code will attempt to make the agent continue following the link even if it is destroyed, but if you write your own traversal code, you should be aware of this. You can alternatively set the corresponding property property on the off-mesh link ( [NodeLink2.onTraverseOffMeshLink](https://arongranberg.com/astar/docs/nodelink2.html#onTraverseOffMeshLink) ) to specify a callback for a specific off-mesh link. Note The agent's off-mesh link handler takes precedence over the link's off-mesh link handler, if both are set. See [Off-mesh links](https://arongranberg.com/astar/docs/offmeshlinks2.html) for more details and example code [isTraversingOffMeshLink](https://arongranberg.com/astar/docs/followerentity.html#isTraversingOffMeshLink) orientation Determines which direction the agent moves in. Public ##### [OrientationMode](https://arongranberg.com/astar/docs/pathfinding.html#OrientationMode) ? orientation Determines which direction the agent moves in. For 3D games you most likely want the ZAxisIsForward option as that is the convention for 3D games. For 2D games you most likely want the YAxisIsForward option as that is the convention for 2D games. When using ZAxisForward, the +Z axis will be the forward direction of the agent, +Y will be upwards, and +X will be the right direction. When using YAxisForward, the +Y axis will be the forward direction of the agent, +Z will be upwards, and +X will be the right direction. Note This only affects the rotation of the GameObject's Transform, not the entity's internal rotation. Thus it has no effect when the agent is baked in a subscene, since there is no Transform object in that case. ![](https://arongranberg.com/astar/docs/images/aibase_forward_axis.png) pathPending True if a path is currently being calculated. Public ##### bool pathPending True if a path is currently being calculated. pathfindingSettings Pathfinding settings. Public ##### ref[PathRequestSettings](https://arongranberg.com/astar/docs/pathrequestsettings.html) pathfindingSettings Pathfinding settings. The settings in this struct controls how the agent calculates paths to its destination. This is analogous to the [Seeker](https://arongranberg.com/astar/docs/seeker.html) component used for other movement scripts. See [PathRequestSettings](https://arongranberg.com/astar/docs/pathrequestsettings.html) position Position of the agent. Public ##### Vector3? position Position of the agent. In world space. See [rotation](https://arongranberg.com/astar/docs/followerentity.html#rotation) If you want to move the agent you may use [Teleport](https://arongranberg.com/astar/docs/followerentity/teleport.html#Teleport) or [Move](https://arongranberg.com/astar/docs/followerentity/move.html#Move) . positionSmoothing How much to smooth the visual position of the agent. Public ##### float? positionSmoothing How much to smooth the visual position of the agent. This does not affect movement, but smoothes out the position of the agent visually. Recommended values are between 0.0 and 0.5. A value of zero will disable smoothing completely. This will make the agent seem to lag slightly behind the internal position of the agent. It may also cut corners slightly. The unit for this field is seconds. radius Radius of the agent in world units. Public ##### float? radius Radius of the agent in world units. This is visualized in the scene view as a yellow cylinder around the character. Note that this does not affect pathfinding in any way. The graph used completely determines where the agent can move. Note The [Pathfinding.AILerp](https://arongranberg.com/astar/docs/ailerp.html) script doesn't really have any use of knowing the radius or the height of the character, so this property will always return 0 in that script. reachedCrowdedEndOfPath Like [reachedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedEndOfPath) , but will also return true if the end of the path is crowded, and this agent has stopped because it cannot get closer. Public ##### bool reachedCrowdedEndOfPath Like [reachedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedEndOfPath) , but will also return true if the end of the path is crowded, and this agent has stopped because it cannot get closer. This is only relevant if the agent is using local avoidance. Otherwise, this will be identical to [reachedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedEndOfPath) . If the agent has a stale path (e.g. because the destination changed significantly, or a graph update happened near the agent), false will be returned until the path has been recalculated (typically in the next one or two frames). You can see a visualization of this state by enabling "Reached State" in the [Local Avoidance Debug Rendering](https://arongranberg.com/astar/docs/rvoagent.html#debug) field. Note The agent may not be completely stopped when this is true. It knows that there are other agents in the way, but it might still be able to slowly make some progress. Check the [velocity](https://arongranberg.com/astar/docs/followerentity.html#velocity) property to see if the agent is actually moving. In the video below, the agents will get a red ring around them when this property is true. Your browser does not support the video tag. See [Local Avoidance](https://arongranberg.com/astar/docs/localavoidance.html) . [ReachedEndOfPath](https://arongranberg.com/astar/docs/rvo2.html#ReachedEndOfPath) reachedDestination True if the ai has reached the [destination](https://arongranberg.com/astar/docs/followerentityproxy.html#destination) . Public ##### bool reachedDestination True if the ai has reached the [destination](https://arongranberg.com/astar/docs/followerentityproxy.html#destination) . The agent considers the destination reached when it is within [stopDistance](https://arongranberg.com/astar/docs/followerentityproxy.html#stopDistance) world units from the [destination](https://arongranberg.com/astar/docs/followerentityproxy.html#destination) . Additionally, the destination must not be above the agent's head, and it must not be more than half the agent's height below its feet. If a facing direction was specified when setting the destination, this will only return true once the agent is approximately facing the correct orientation. This value will be updated immediately when the [destination](https://arongranberg.com/astar/docs/followerentityproxy.html#destination) is changed. `IEnumerator [Start](https://arongranberg.com/astar/docs/followerentity/start.html#Start) () { ai.destination = somePoint; // Start to search for a path to the destination immediately ai.SearchPath(); // Wait until the agent has reached the destination while (!ai.reachedDestination) { yield return null; } // The agent has reached the destination now } ` Note The agent may not be able to reach the destination. In that case this property may never become true. Sometimes [reachedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedEndOfPath) is more appropriate. See [stopDistance](https://arongranberg.com/astar/docs/followerentityproxy.html#stopDistance) [remainingDistance](https://arongranberg.com/astar/docs/followerentity.html#remainingDistance) [reachedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedEndOfPath) [reachedCrowdedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedCrowdedEndOfPath) reachedEndOfPath True if the agent has reached the end of the current path. Public ##### bool reachedEndOfPath True if the agent has reached the end of the current path. The agent considers the end of the path reached when it is within [stopDistance](https://arongranberg.com/astar/docs/followerentityproxy.html#stopDistance) world units from the end of the path. Additionally, the end of the path must not be above the agent's head, and it must not be more than half the agent's height below its feet. If a facing direction was specified when setting the destination, this will only return true once the agent is approximately facing the correct orientation. This value will be updated immediately when the [destination](https://arongranberg.com/astar/docs/followerentityproxy.html#destination) is changed. Note Reaching the end of the path does not imply that it has reached its desired destination, as the destination may not even be possible to reach. Sometimes [reachedDestination](https://arongranberg.com/astar/docs/followerentity.html#reachedDestination) is more appropriate. See [remainingDistance](https://arongranberg.com/astar/docs/followerentity.html#remainingDistance) [reachedDestination](https://arongranberg.com/astar/docs/followerentity.html#reachedDestination) [reachedCrowdedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedCrowdedEndOfPath) remainingDistance Approximate remaining distance along the current path to the end of the path. Public ##### float remainingDistance Approximate remaining distance along the current path to the end of the path. This is an approximation for performance reasons, and the agent also does not know the true distance at all times. It tends to be a bit lower than the true distance. It will get more accurate as the agent gets closer to the end of the path. If you want a more accurate distance (at a higher performance cost), you can call GetRemainingPath and sum the length of it. Note This is the distance to the end of the path, which may or may not be the same as the destination. If the character cannot reach the destination it will try to move as close as possible to it. This value will update immediately if the [destination](https://arongranberg.com/astar/docs/followerentity.html#destination) property is changed, or if the agent is moved using the [position](https://arongranberg.com/astar/docs/followerentity.html#position) property or the [Teleport](https://arongranberg.com/astar/docs/followerentity/teleport.html#Teleport) method. If the agent has no path, or if the current path is stale (e.g. if the graph has been updated close to the agent, and it hasn't had time to recalculate its path), this will return positive infinity. See [reachedDestination](https://arongranberg.com/astar/docs/followerentity.html#reachedDestination) [reachedEndOfPath](https://arongranberg.com/astar/docs/followerentity.html#reachedEndOfPath) [pathPending](https://arongranberg.com/astar/docs/followerentity.html#pathPending) rotation Rotation of the agent. Public ##### Quaternion? rotation Rotation of the agent. In world space. The entity internally always treats the Z axis as forward, but this property respects the [orientation](https://arongranberg.com/astar/docs/followerentity.html#orientation) field. So it will return either a rotation with the Y axis as forward, or Z axis as forward, depending on the [orientation](https://arongranberg.com/astar/docs/followerentity.html#orientation) field. Note if [updateRotation](https://arongranberg.com/astar/docs/followerentity.html#updateRotation) is true (which is the default), this will also set the transform's rotation. If [updateRotation](https://arongranberg.com/astar/docs/followerentity.html#updateRotation) is false, only the agent's internal rotation will be set. This will return the agent's rotation even if [updateRotation](https://arongranberg.com/astar/docs/followerentity.html#updateRotation) is false. See [position](https://arongranberg.com/astar/docs/followerentity.html#position) rotationSmoothing How much to smooth the visual rotation of the agent. Public ##### float? rotationSmoothing How much to smooth the visual rotation of the agent. This does not affect movement, but smoothes out how the agent rotates visually. Recommended values are between 0.0 and 0.5. A value of zero will disable smoothing completely. The smoothing is done primarily using an exponential moving average, but with a small linear term to make the rotation converge faster when the agent is almost facing the desired direction. Adding smoothing will make the visual rotation of the agent lag a bit behind the actual rotation. Too much smoothing may make the agent seem sluggish, and appear to move sideways. The unit for this field is seconds. rotationSpeed Desired rotation speed in degrees per second. Public ##### float? rotationSpeed Desired rotation speed in degrees per second. If the agent is in an open area and gets a new destination directly behind itself, it will start to rotate around with exactly this rotation speed. The agent will slow down its rotation speed as it approaches its desired facing direction. So for example, when it is only 90 degrees away from its desired facing direction, it will only rotate with about half this speed. See [maxRotationSpeed](https://arongranberg.com/astar/docs/pidmovement.html#maxRotationSpeed) rvoSettings Local avoidance settings. Public ##### [RVOAgent](https://arongranberg.com/astar/docs/rvoagent.html) rvoSettings Local avoidance settings. simulateMovement Enables or disables movement completely. Public ##### bool simulateMovement Enables or disables movement completely. If you want the agent to stand still, but still react to local avoidance and use gravity: use [isStopped](https://arongranberg.com/astar/docs/followerentity.html#isStopped) instead. Disabling this will remove the [SimulateMovement](https://arongranberg.com/astar/docs/simulatemovement.html) component from the entity, which prevents most systems from running for this entity. When disabled, the [velocity](https://arongranberg.com/astar/docs/followerentity.html#velocity) property, and many other informational properties, will no longer update. See [autoRepath](https://arongranberg.com/astar/docs/followerentity.html#autoRepath) [isStopped](https://arongranberg.com/astar/docs/followerentity.html#isStopped) steeringTarget Point on the path which the agent is currently moving towards. Public ##### [Vector3](https://docs.unity3d.com/ScriptReference/Vector3.html) steeringTarget Point on the path which the agent is currently moving towards. This is usually a point a small distance ahead of the agent or the end of the path. If the agent does not have a path at the moment, then the agent's current position will be returned. stopDistance How far away from the destination should the agent aim to stop, in world units. Public ##### float? stopDistance How far away from the destination should the agent aim to stop, in world units. If the agent is within this distance from the destination point it will be considered to have reached the destination. Even if you want the agent to stop precisely at a given point, it is recommended to keep this slightly above zero. If it is exactly zero, the agent may have a hard time deciding that it has actually reached the end of the path, due to floating point errors and such. Note This will not be multiplied the agent's scale. updatePosition Determines if the character's position should be coupled to the Transform's position. Public ##### bool updatePosition Determines if the character's position should be coupled to the Transform's position. If false then all movement calculations will happen as usual, but the GameObject that this component is attached to will not move. Instead, only the [position](https://arongranberg.com/astar/docs/followerentity.html#position) property and the internal entity's position will change. This is useful if you want to control the movement of the character using some other means, such as root motion, but still want the AI to move freely. Note This has no effect when the agent is baked in a subscene, since there is no Transform to sync with. See [simulateMovement](https://arongranberg.com/astar/docs/followerentity.html#simulateMovement) which in contrast to this field will disable all [movement](https://arongranberg.com/astar/docs/followerentity.html#movement) calculations. [updateRotation](https://arongranberg.com/astar/docs/followerentity.html#updateRotation) updateRotation Determines if the character's rotation should be coupled to the Transform's rotation. Public ##### bool updateRotation Determines if the character's rotation should be coupled to the Transform's rotation. If false then all movement calculations will happen as usual, but the GameObject that this component is attached to will not rotate. Instead, only the [rotation](https://arongranberg.com/astar/docs/followerentity.html#rotation) property and the internal entity's rotation will change. This is particularly useful for 2D games where you want the Transform to stay in the same orientation, and instead swap out the displayed sprite to indicate the direction the character is facing. You can enable [PIDMovement.DebugFlags](https://arongranberg.com/astar/docs/pidmovement.html#DebugFlags) .Rotation in [debugFlags](https://arongranberg.com/astar/docs/followerentity.html#debugFlags) to draw a gizmos arrow in the scene view to indicate the agent's internal rotation. Note This has no effect when the agent is baked in a subscene, since there is no Transform to sync with. See [updatePosition](https://arongranberg.com/astar/docs/followerentity.html#updatePosition) [rotation](https://arongranberg.com/astar/docs/followerentity.html#rotation) [orientation](https://arongranberg.com/astar/docs/followerentity.html#orientation) velocity Actual velocity that the agent is moving with, including gravity. Public ##### Vector3? velocity Actual velocity that the agent is moving with, including gravity. In world units per second. This is useful for, for example, selecting which animations to play, and at what speeds. Note Any value set here will be overriden during the next simulation step. Nevertheless, it can be useful to set this value if you have disabled the agent's movement logic using e.g. [simulateMovement](https://arongranberg.com/astar/docs/followerentity.html#simulateMovement) . This value is only an output statistic. It is not used to control the agent's movement. See [desiredVelocity](https://arongranberg.com/astar/docs/followerentity.html#desiredVelocity) world Public ##### World world Public Static Variables ----------------------- indicesScratch Public Static ##### NativeArray indicesScratch nextCornersScratch Public Static ##### NativeList nextCornersScratch Private/Protected Members ------------------------- [CancelCurrentPathRequest](https://arongranberg.com/astar/docs/followerentityproxy/cancelcurrentpathrequ.html#CancelCurrentPathRequest) () [ClearPath](https://arongranberg.com/astar/docs/followerentityproxy/clearpath.html#ClearPath) () [ResetControl](https://arongranberg.com/astar/docs/followerentityproxy/resetcontrol.html#ResetControl) (resolvedMovement, controlOutput, movementPlane, position, rotation, endOfPath) [ToggleComponent](https://arongranberg.com/astar/docs/followerentityproxy/togglecomponent.html#ToggleComponent) (world, entity, enabled, mustExist) Adds or removes a component from an entity. [ToggleComponentEnabled](https://arongranberg.com/astar/docs/followerentityproxy/togglecomponentenable.html#ToggleComponentEnabled) (world, entity, enabled, mustExist) Enables or disables a component on an entity. agentCylinderShapeAccessRO Internal Static ##### [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[AgentCylinderShape](https://arongranberg.com/astar/docs/agentcylindershape.html) \> agentCylinderShapeAccessRO = new [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[AgentCylinderShape](https://arongranberg.com/astar/docs/agentcylindershape.html) \>(true) agentCylinderShapeAccessRW Internal Static ##### [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[AgentCylinderShape](https://arongranberg.com/astar/docs/agentcylindershape.html) \> agentCylinderShapeAccessRW = new [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[AgentCylinderShape](https://arongranberg.com/astar/docs/agentcylindershape.html) \>(false) agentOffMeshLinkTraversalRO Internal Static ##### [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[AgentOffMeshLinkTraversal](https://arongranberg.com/astar/docs/agentoffmeshlinktraversal.html) \> agentOffMeshLinkTraversalRO = new [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[AgentOffMeshLinkTraversal](https://arongranberg.com/astar/docs/agentoffmeshlinktraversal.html) \>(true) autoRepathPolicyRW Internal Static ##### [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[ECS.AutoRepathPolicy](https://arongranberg.com/astar/docs/autorepathpolicy2.html) \> autoRepathPolicyRW = new [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[ECS.AutoRepathPolicy](https://arongranberg.com/astar/docs/autorepathpolicy2.html) \>(false) destinationPointAccessRO Internal Static ##### [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[DestinationPoint](https://arongranberg.com/astar/docs/destinationpoint.html) \> destinationPointAccessRO = new [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[DestinationPoint](https://arongranberg.com/astar/docs/destinationpoint.html) \>(true) destinationPointAccessRW Internal Static ##### [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[DestinationPoint](https://arongranberg.com/astar/docs/destinationpoint.html) \> destinationPointAccessRW = new [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[DestinationPoint](https://arongranberg.com/astar/docs/destinationpoint.html) \>(false) entityStorageCache Internal Static ##### [EntityStorageCache](https://arongranberg.com/astar/docs/entitystoragecache.html) entityStorageCache likelyHasReasonableComponents True if the entity seems to have the required components. Internal ##### bool likelyHasReasonableComponents True if the entity seems to have the required components. This is used to detect entities which still exist, but which have had all their [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) components removed. localTransformAccessRO Internal Static ##### [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) localTransformAccessRO = new [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) (true) localTransformAccessRW Internal Static ##### [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) localTransformAccessRW = new [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) (false) managedSettingsAccessRO Internal Static ##### [ManagedEntityAccess](https://arongranberg.com/astar/docs/managedentityaccess.html) <[ManagedSettings](https://arongranberg.com/astar/docs/managedsettings.html) \> managedSettingsAccessRO = new [ManagedEntityAccess](https://arongranberg.com/astar/docs/managedentityaccess.html) <[ManagedSettings](https://arongranberg.com/astar/docs/managedsettings.html) \>(true) managedSettingsAccessRW Internal Static ##### [ManagedEntityAccess](https://arongranberg.com/astar/docs/managedentityaccess.html) <[ManagedSettings](https://arongranberg.com/astar/docs/managedsettings.html) \> managedSettingsAccessRW = new [ManagedEntityAccess](https://arongranberg.com/astar/docs/managedentityaccess.html) <[ManagedSettings](https://arongranberg.com/astar/docs/managedsettings.html) \>(false) managedStateAccessRO Internal Static ##### [ManagedEntityAccess](https://arongranberg.com/astar/docs/managedentityaccess.html) <[ManagedState](https://arongranberg.com/astar/docs/managedstate.html) \> managedStateAccessRO = new [ManagedEntityAccess](https://arongranberg.com/astar/docs/managedentityaccess.html) <[ManagedState](https://arongranberg.com/astar/docs/managedstate.html) \>(true) managedStateAccessRW Internal Static ##### [ManagedEntityAccess](https://arongranberg.com/astar/docs/managedentityaccess.html) <[ManagedState](https://arongranberg.com/astar/docs/managedstate.html) \> managedStateAccessRW = new [ManagedEntityAccess](https://arongranberg.com/astar/docs/managedentityaccess.html) <[ManagedState](https://arongranberg.com/astar/docs/managedstate.html) \>(false) movementControlAccessRO Internal Static ##### [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[MovementControl](https://arongranberg.com/astar/docs/movementcontrol.html) \> movementControlAccessRO = new [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[MovementControl](https://arongranberg.com/astar/docs/movementcontrol.html) \>(true) movementControlAccessRW Internal Static ##### [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[MovementControl](https://arongranberg.com/astar/docs/movementcontrol.html) \> movementControlAccessRW = new [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[MovementControl](https://arongranberg.com/astar/docs/movementcontrol.html) \>(false) movementOutputAccessRW Internal Static ##### [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[MovementStatistics](https://arongranberg.com/astar/docs/movementstatistics.html) \> movementOutputAccessRW = new [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[MovementStatistics](https://arongranberg.com/astar/docs/movementstatistics.html) \>(false) movementPlaneAccessRO Internal Static ##### [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[AgentMovementPlane](https://arongranberg.com/astar/docs/agentmovementplane.html) \> movementPlaneAccessRO = new [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[AgentMovementPlane](https://arongranberg.com/astar/docs/agentmovementplane.html) \>(true) movementPlaneAccessRW Internal Static ##### [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[AgentMovementPlane](https://arongranberg.com/astar/docs/agentmovementplane.html) \> movementPlaneAccessRW = new [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[AgentMovementPlane](https://arongranberg.com/astar/docs/agentmovementplane.html) \>(false) movementSettingsAccessRO Internal Static ##### [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[MovementSettings](https://arongranberg.com/astar/docs/movementsettings.html) \> movementSettingsAccessRO = new [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[MovementSettings](https://arongranberg.com/astar/docs/movementsettings.html) \>(true) movementSettingsAccessRW Internal Static ##### [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[MovementSettings](https://arongranberg.com/astar/docs/movementsettings.html) \> movementSettingsAccessRW = new [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[MovementSettings](https://arongranberg.com/astar/docs/movementsettings.html) \>(false) movementStateAccessRO Internal Static ##### [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[MovementState](https://arongranberg.com/astar/docs/movementstate.html) \> movementStateAccessRO = new [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[MovementState](https://arongranberg.com/astar/docs/movementstate.html) \>(true) movementStateAccessRW Internal Static ##### [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[MovementState](https://arongranberg.com/astar/docs/movementstate.html) \> movementStateAccessRW = new [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[MovementState](https://arongranberg.com/astar/docs/movementstate.html) \>(false) movementStatisticsAccessRO Internal Static ##### [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[MovementStatistics](https://arongranberg.com/astar/docs/movementstatistics.html) \> movementStatisticsAccessRO = new [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[MovementStatistics](https://arongranberg.com/astar/docs/movementstatistics.html) \>(true) movementStatisticsAccessRW Internal Static ##### [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[MovementStatistics](https://arongranberg.com/astar/docs/movementstatistics.html) \> movementStatisticsAccessRW = new [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[MovementStatistics](https://arongranberg.com/astar/docs/movementstatistics.html) \>(false) readyToTraverseOffMeshLinkRW Internal Static ##### [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[ReadyToTraverseOffMeshLink](https://arongranberg.com/astar/docs/readytotraverseoffmeshlink.html) \> readyToTraverseOffMeshLinkRW = new [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[ReadyToTraverseOffMeshLink](https://arongranberg.com/astar/docs/readytotraverseoffmeshlink.html) \>(false) resolvedMovementAccessRO Internal Static ##### [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[ResolvedMovement](https://arongranberg.com/astar/docs/resolvedmovement.html) \> resolvedMovementAccessRO = new [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[ResolvedMovement](https://arongranberg.com/astar/docs/resolvedmovement.html) \>(true) resolvedMovementAccessRW Internal Static ##### [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[ResolvedMovement](https://arongranberg.com/astar/docs/resolvedmovement.html) \> resolvedMovementAccessRW = new [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[ResolvedMovement](https://arongranberg.com/astar/docs/resolvedmovement.html) \>(false) rvoSettingsAccessRO Internal Static ##### [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[RVOAgent](https://arongranberg.com/astar/docs/rvoagent.html) \> rvoSettingsAccessRO = new [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[RVOAgent](https://arongranberg.com/astar/docs/rvoagent.html) \>(true) rvoSettingsAccessRW Internal Static ##### [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[RVOAgent](https://arongranberg.com/astar/docs/rvoagent.html) \> rvoSettingsAccessRW = new [EntityAccess](https://arongranberg.com/astar/docs/entityaccess.html) <[RVOAgent](https://arongranberg.com/astar/docs/rvoagent.html) \>(false) Deprecated Members ------------------ canSearch Enables or disables recalculating the path at regular intervals. Public ##### bool canSearch Enables or disables recalculating the path at regular intervals. Setting this to false does not stop any active path requests from being calculated or stop it from continuing to follow the current path. Note that this only disables automatic path recalculations. If you call the [SearchPath()](https://arongranberg.com/astar/docs/followerentityproxy/searchpath.html#SearchPath) method a path will still be calculated. See [simulateMovement](https://arongranberg.com/astar/docs/followerentityproxy.html#simulateMovement) [isStopped](https://arongranberg.com/astar/docs/followerentityproxy.html#isStopped) Deprecated This has been superseded by [autoRepath.mode](https://arongranberg.com/astar/docs/autorepathpolicy2.html#mode) . --- # JobRepairPath - A* Pathfinding Project Struct JobRepairPath Extends IJobChunk ====================================== Public Repairs the path of agents. This job will repair the agent's path based on the agent's current position and its destination. It will also recalculate various statistics like how far the agent is from the destination, and if it has reached the destination or not. Inner Types ----------- [Scheduler](https://arongranberg.com/astar/docs/scheduler.html) Public Methods -------------- [Execute](https://arongranberg.com/astar/docs/jobrepairpath/execute.html) (...) Public Variables ---------------- indicesScratch Public ##### NativeArray indicesScratch nextCornersScratch Public ##### NativeList nextCornersScratch onlyApplyPendingPaths Public ##### bool onlyApplyPendingPaths scheduler Public ##### [Scheduler](https://arongranberg.com/astar/docs/scheduler.html) scheduler Private/Protected Members ------------------------- MarkerGetNextCorners Private Static Readonly ##### ProfilerMarker MarkerGetNextCorners = new ProfilerMarker("GetNextCorners") MarkerRepair Private Static Readonly ##### ProfilerMarker MarkerRepair = new ProfilerMarker("Repair") MarkerUpdateReachedEndInfo Private Static Readonly ##### ProfilerMarker MarkerUpdateReachedEndInfo = new ProfilerMarker("UpdateReachedEndInfo") --- # PathTracerInfo - A* Pathfinding Project Struct PathTracerInfo ===================== Public Public Variables ---------------- endPointOfFirstPart Public ##### float3 endPointOfFirstPart hasValidEndPoint Public ##### bool hasValidEndPoint isStale Public ##### bool isStale partCount Public ##### int partCount --- # JobRepairPathHelpers - A* Pathfinding Project Class JobRepairPathHelpers ========================== Public Inner Types ----------- [PathTracerInfo](https://arongranberg.com/astar/docs/pathtracerinfo.html) Public Static Methods --------------------- [UpdateReachedEndInfo](https://arongranberg.com/astar/docs/jobrepairpathhelpers/updatereachedendinfo.html#UpdateReachedEndInfo) (nextCorners, state, movementPlane, transform, shape, destination, stopDistance, pathTracer) Checks if the agent has reached its destination, or the end of the path. [UpdateReachedOrientation](https://arongranberg.com/astar/docs/jobrepairpathhelpers/updatereachedorienta.html#UpdateReachedOrientation) (state, transform, movementPlane, destination) Checks if the agent is oriented towards the desired facing direction. Private/Protected Members ------------------------- [ReachedDesiredOrientation](https://arongranberg.com/astar/docs/jobrepairpathhelpers/reacheddesiredorient.html#ReachedDesiredOrientation) (transform, movementPlane, destination) --- # JobStartOffMeshLinkTransition - A* Pathfinding Project Struct JobStartOffMeshLinkTransition ==================================== Public Public Static Methods --------------------- [DefaultOnTraverseOffMeshLink](https://arongranberg.com/astar/docs/jobstartoffmeshlinktransition/defaultontr.html#DefaultOnTraverseOffMeshLink) (ctx) This is a fallback for traversing off-mesh links in case the user has not specified a custom traversal method. Public Variables ---------------- commandBuffer Public ##### EntityCommandBuffer commandBuffer --- # JobSyncEntitiesToTransforms - A* Pathfinding Project Struct JobSyncEntitiesToTransforms Extends IJobParallelForTransform =================================================================== Public Public Methods -------------- [Execute](https://arongranberg.com/astar/docs/jobsyncentitiestotransforms/execute.html#Execute) (index, transform) Public Variables ---------------- entities Public ##### NativeArray entities entityPositions Public ##### ComponentLookup entityPositions movementState Public ##### ComponentLookup<[MovementState](https://arongranberg.com/astar/docs/movementstate.html) \> movementState orientationYAxisForward Public ##### ComponentLookup<[OrientationYAxisForward](https://arongranberg.com/astar/docs/orientationyaxisforward.html) \> orientationYAxisForward syncPositionWithTransform Public ##### ComponentLookup<[SyncPositionWithTransform](https://arongranberg.com/astar/docs/syncpositionwithtransform.html) \> syncPositionWithTransform syncRotationWithTransform Public ##### ComponentLookup<[SyncRotationWithTransform](https://arongranberg.com/astar/docs/syncrotationwithtransform.html) \> syncRotationWithTransform --- # Scheduler - A* Pathfinding Project Struct Scheduler ================ Public Public Methods -------------- [Dispose](https://arongranberg.com/astar/docs/scheduler/dispose.html#Dispose) () [GetEntityQuery](https://arongranberg.com/astar/docs/scheduler/getentityquery.html#GetEntityQuery) (allocator) [ScheduleParallel](https://arongranberg.com/astar/docs/scheduler/scheduleparallel.html#ScheduleParallel) (systemState, query, dependency) [Scheduler](https://arongranberg.com/astar/docs/scheduler/scheduler.html#Scheduler) (systemState) [Update](https://arongranberg.com/astar/docs/scheduler/update.html#Update) (systemState) Public Variables ---------------- AgentCylinderShapeTypeHandleRO Public ##### ComponentTypeHandle<[AgentCylinderShape](https://arongranberg.com/astar/docs/agentcylindershape.html) \> AgentCylinderShapeTypeHandleRO AgentMovementPlaneTypeHandleRO Public ##### ComponentTypeHandle<[AgentMovementPlane](https://arongranberg.com/astar/docs/agentmovementplane.html) \> AgentMovementPlaneTypeHandleRO AutoRepathPolicyRW Public ##### ComponentTypeHandle<[AutoRepathPolicy](https://arongranberg.com/astar/docs/autorepathpolicy2.html) \> AutoRepathPolicyRW DestinationPointTypeHandleRO Public ##### ComponentTypeHandle<[DestinationPoint](https://arongranberg.com/astar/docs/destinationpoint.html) \> DestinationPointTypeHandleRO LocalTransformTypeHandleRO Public ##### ComponentTypeHandle LocalTransformTypeHandleRO ManagedStateTypeHandleRW Public ##### ComponentTypeHandle<[ManagedState](https://arongranberg.com/astar/docs/managedstate.html) \> ManagedStateTypeHandleRW MovementSettingsTypeHandleRO Public ##### ComponentTypeHandle<[MovementSettings](https://arongranberg.com/astar/docs/movementsettings.html) \> MovementSettingsTypeHandleRO MovementStateTypeHandleRW Public ##### ComponentTypeHandle<[MovementState](https://arongranberg.com/astar/docs/movementstate.html) \> MovementStateTypeHandleRW ReadyToTraverseOffMeshLinkTypeHandleRW Public ##### ComponentTypeHandle<[ReadyToTraverseOffMeshLink](https://arongranberg.com/astar/docs/readytotraverseoffmeshlink.html) \> ReadyToTraverseOffMeshLinkTypeHandleRW entityManagerHandle Public ##### [GCHandle](https://arongranberg.com/astar/docs/%3Cundefined%3E) entityManagerHandle onlyApplyPendingPaths Public ##### bool onlyApplyPendingPaths --- # JobUpdateMovementStatistics - A* Pathfinding Project Struct JobUpdateMovementStatistics Extends IJobEntity ===================================================== Public Public Methods -------------- [Execute](https://arongranberg.com/astar/docs/jobupdatemovementstatistics/execute.html#Execute) (transform, movementStatistics) Public Static Methods --------------------- [UpdateStatistics](https://arongranberg.com/astar/docs/jobupdatemovementstatistics/updatestatist.html#UpdateStatistics) (transform, movementStatistics, dt) Public Variables ---------------- dt Public ##### float dt --- # ManagedAgentOffMeshLinkTraversal - A* Pathfinding Project Class ManagedAgentOffMeshLinkTraversal Extends IComponentData, ICloneable, ICleanupComponentData ================================================================================================ Public Holds managed information about an off-mesh link that the agent is currently traversing. This component is added to the agent when it starts traversing an off-mesh link. It is removed when the agent has finished traversing the link. See [AgentOffMeshLinkTraversal](https://arongranberg.com/astar/docs/agentoffmeshlinktraversal.html) Public Methods -------------- [Clone](https://arongranberg.com/astar/docs/managedagentoffmeshlinktraversal/clone.html#Clone) () [ManagedAgentOffMeshLinkTraversal](https://arongranberg.com/astar/docs/managedagentoffmeshlinktraversal/manageda.html) (\[...\]) Public Variables ---------------- context Internal context used to pass component data to the coroutine. Public ##### [AgentOffMeshLinkTraversalContext](https://arongranberg.com/astar/docs/agentoffmeshlinktraversalcontext.html) context Internal context used to pass component data to the coroutine. coroutine Coroutine which is used to traverse the link. Public ##### System.Collections.IEnumerator coroutine Coroutine which is used to traverse the link. handler Public ##### [IOffMeshLinkHandler](https://arongranberg.com/astar/docs/ioffmeshlinkhandler.html) handler stateMachine Public ##### [IOffMeshLinkStateMachine](https://arongranberg.com/astar/docs/ioffmeshlinkstatemachine.html) stateMachine --- # ManagedEntityAccess - A* Pathfinding Project Struct ManagedEntityAccess ========================== Public Utility for efficient random access to managed entity component data from the main thread. Warning Some checks are not enforced by this API. It is the user's responsibility to ensure that this struct does not survive past an [ECS](https://arongranberg.com/astar/docs/ecs2.html) system update. If you only use this struct from the main thread and only store it locally on the stack, this should not be a problem. This struct also does not enforce that you only read to the component data if the **readOnly** flag is set. Public Methods -------------- [ManagedEntityAccess](https://arongranberg.com/astar/docs/managedentityaccess/managedentityaccess.html) (\[entityManager\], readOnly) [Update](https://arongranberg.com/astar/docs/managedentityaccess/update.html#Update) (entityManager) Public Variables ---------------- entityManager Public ##### EntityManager entityManager handle Public ##### ComponentTypeHandle handle readOnly Public ##### bool readOnly this\[EntityStorageInfo storage\] Public ##### T this\[EntityStorageInfo storage\] --- # LateSyncSystem - A* Pathfinding Project Struct LateSyncSystem Extends ISystem ===================================== Public System that runs after all movement systems and repairs the agent's path and syncs its orientation to the associated Transform component, if one exists. Repairing the path after running all the movement simulations is not strictly necessary, but it ensures that any other scripts querying properties like the remaining path, or if the agent has reached its destination, will see up to date information immediately. If the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) was not in a subscene, we need to sync the internal entity's position and rotation to the Transform that the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component is attached to. However, if it was placed in a subscene, the Transform and [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component won't even exist at runtime (except when debugging in the unity editor), and so the sync can be skipped. Public Methods -------------- [OnCreate](https://arongranberg.com/astar/docs/latesyncsystem/oncreate.html#OnCreate) (systemState) [OnDestroy](https://arongranberg.com/astar/docs/latesyncsystem/ondestroy.html#OnDestroy) (systemState) [OnUpdate](https://arongranberg.com/astar/docs/latesyncsystem/onupdate.html#OnUpdate) (systemState) [ScheduleRepairPaths](https://arongranberg.com/astar/docs/latesyncsystem/schedulerepairpaths.html#ScheduleRepairPaths) (systemState, dependency) [ScheduleSyncEntitiesToTransforms](https://arongranberg.com/astar/docs/latesyncsystem/schedulesyncentitiestotran.html#ScheduleSyncEntitiesToTransforms) (systemState, dependency) Public Variables ---------------- entityQueryPrepareMovement Public ##### EntityQuery entityQueryPrepareMovement jobRepairPathScheduler Public ##### [JobRepairPath.Scheduler](https://arongranberg.com/astar/docs/scheduler.html) jobRepairPathScheduler --- # ManagedMovementOverrideAfterControl - A* Pathfinding Project Class ManagedMovementOverrideAfterControl Extends [ManagedMovementOverride](https://arongranberg.com/astar/docs/managedmovementoverride.html) ============================================================================================================================================== Public Public Methods -------------- [Clone](https://arongranberg.com/astar/docs/managedmovementoverrideaftercontrol/clone.html#Clone) () Inherited Public Members ------------------------ [AddCallback](https://arongranberg.com/astar/docs/managedmovementoverride/addcallback.html#AddCallback) (callback) [RemoveCallback](https://arongranberg.com/astar/docs/managedmovementoverride/removecallback.html#RemoveCallback) (callback) callback Public ##### T callback --- # ManagedMovementOverrideBeforeControl - A* Pathfinding Project Class ManagedMovementOverrideBeforeControl Extends [ManagedMovementOverride](https://arongranberg.com/astar/docs/managedmovementoverride.html) , ICloneable =========================================================================================================================================================== Public Public Methods -------------- [Clone](https://arongranberg.com/astar/docs/managedmovementoverridebeforecontrol/clon.html#Clone) () Inherited Public Members ------------------------ [AddCallback](https://arongranberg.com/astar/docs/managedmovementoverride/addcallback.html#AddCallback) (callback) [RemoveCallback](https://arongranberg.com/astar/docs/managedmovementoverride/removecallback.html#RemoveCallback) (callback) callback Public ##### T callback --- # ManagedMovementOverride - A* Pathfinding Project Class ManagedMovementOverride Extends IComponentData ==================================================== Public Component that stores a delegate that can be used to override movement control and movement settings for a specific entity. This is used by the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) to allow other systems to override the movement of the entity. See [FollowerEntity.movementOverrides](https://arongranberg.com/astar/docs/followerentity.html#movementOverrides) Public Methods -------------- [AddCallback](https://arongranberg.com/astar/docs/managedmovementoverride/addcallback.html#AddCallback) (callback) [RemoveCallback](https://arongranberg.com/astar/docs/managedmovementoverride/removecallback.html#RemoveCallback) (callback) Public Variables ---------------- callback Public ##### T callback --- # ManagedMovementOverrideBeforeMovement - A* Pathfinding Project Class ManagedMovementOverrideBeforeMovement Extends [ManagedMovementOverride](https://arongranberg.com/astar/docs/managedmovementoverride.html) ================================================================================================================================================ Public Public Methods -------------- [Clone](https://arongranberg.com/astar/docs/managedmovementoverridebeforemovement/clo.html#Clone) () Inherited Public Members ------------------------ [AddCallback](https://arongranberg.com/astar/docs/managedmovementoverride/addcallback.html#AddCallback) (callback) [RemoveCallback](https://arongranberg.com/astar/docs/managedmovementoverride/removecallback.html#RemoveCallback) (callback) callback Public ##### T callback --- # ManagedMovementOverrides - A* Pathfinding Project Struct ManagedMovementOverrides =============================== Public Helper for adding and removing hooks to the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component. This is used to allow other systems to override the movement of the agent. See [FollowerEntity.movementOverrides](https://arongranberg.com/astar/docs/followerentity.html#movementOverrides) Public Methods -------------- [AddAfterControlCallback](https://arongranberg.com/astar/docs/managedmovementoverrides/addaftercontrolc.html#AddAfterControlCallback) (value) Registers a callback that runs after the agent has calculated how it wants to move, except for local avoidance. [AddBeforeControlCallback](https://arongranberg.com/astar/docs/managedmovementoverrides/addbeforecontrol.html#AddBeforeControlCallback) (value) Registers a callback that runs before the agent calculates how it wants to move, but after it has repaired its path. [AddBeforeMovementCallback](https://arongranberg.com/astar/docs/managedmovementoverrides/addbeforemovemen.html#AddBeforeMovementCallback) (value) Registers a callback that will be called before the agent is moved, but after it has calculated how it wants to move. [AddCallback](https://arongranberg.com/astar/docs/managedmovementoverrides/addcallback.html#AddCallback) (callback) [ManagedMovementOverrides](https://arongranberg.com/astar/docs/managedmovementoverrides/managedmovemento.html#ManagedMovementOverrides) (entity, world) [RemoveAfterControlCallback](https://arongranberg.com/astar/docs/managedmovementoverrides/removeaftercontr.html#RemoveAfterControlCallback) (value) Removes a callback previously added with [AddAfterControlCallback](https://arongranberg.com/astar/docs/managedmovementoverrides/addaftercontrolc.html#AddAfterControlCallback) . [RemoveBeforeControlCallback](https://arongranberg.com/astar/docs/managedmovementoverrides/removebeforecont.html#RemoveBeforeControlCallback) (value) Removes a callback previously added with [AddBeforeControlCallback](https://arongranberg.com/astar/docs/managedmovementoverrides/addbeforecontrol.html#AddBeforeControlCallback) . [RemoveBeforeMovementCallback](https://arongranberg.com/astar/docs/managedmovementoverrides/removebeforemove.html#RemoveBeforeMovementCallback) (value) Removes a callback previously added with [AddBeforeMovementCallback](https://arongranberg.com/astar/docs/managedmovementoverrides/addbeforemovemen.html#AddBeforeMovementCallback) . [RemoveCallback](https://arongranberg.com/astar/docs/managedmovementoverrides/removecallback.html#RemoveCallback) (callback) Public Variables ---------------- entity Public ##### Entity entity world Public ##### World world --- # JobMovementPlaneFromGraph - A* Pathfinding Project Struct JobMovementPlaneFromGraph Extends IJobEntity =================================================== Public Public Methods -------------- [Execute](https://arongranberg.com/astar/docs/jobmovementplanefromgraph/execute.html#Execute) (movementState, movementPlane) Public Variables ---------------- movementPlanes Public ##### NativeArray<[AgentMovementPlane](https://arongranberg.com/astar/docs/agentmovementplane.html) \> movementPlanes --- # MovementPlaneFromGraphSystem - A* Pathfinding Project Struct MovementPlaneFromGraphSystem Extends ISystem =================================================== Public Inner Types ----------- [JobMovementPlaneFromGraph](https://arongranberg.com/astar/docs/jobmovementplanefromgraph.html) [JobMovementPlaneFromNavmeshNormal](https://arongranberg.com/astar/docs/jobmovementplanefromnavmeshnormal.html) Public Methods -------------- [OnCreate](https://arongranberg.com/astar/docs/movementplanefromgraphsystem/oncreate.html#OnCreate) (state) [OnDestroy](https://arongranberg.com/astar/docs/movementplanefromgraphsystem/ondestroy.html#OnDestroy) (state) [OnUpdate](https://arongranberg.com/astar/docs/movementplanefromgraphsystem/onupdate.html#OnUpdate) (systemState) Public Static Methods --------------------- [MovementPlaneFromGraph](https://arongranberg.com/astar/docs/movementplanefromgraphsystem/movementplan.html#MovementPlaneFromGraph) (graph) Natural movement plane for a graph traversing a given graph. [SampleSmoothNavmeshNormal](https://arongranberg.com/astar/docs/movementplanefromgraphsystem/samplesmooth.html#SampleSmoothNavmeshNormal) (node, scratchList, scratchBuffer, position, agentRadius, agentMovementPlane, alpha) [SampleSmoothTriangleNormal](https://arongranberg.com/astar/docs/movementplanefromgraphsystem/samplesmooth2.html#SampleSmoothTriangleNormal) (position, \_triangleVertices, agentMovementPlane, agentRadius, alpha) [SinAngle](https://arongranberg.com/astar/docs/movementplanefromgraphsystem/sinangle.html#SinAngle) (a, b, c) Sine of the angle ABC. [Square](https://arongranberg.com/astar/docs/movementplanefromgraphsystem/square.html#Square) (x) Public Variables ---------------- entityQueryGraph Public ##### EntityQuery entityQueryGraph entityQueryNormal Public ##### EntityQuery entityQueryNormal graphNodeQueue Public ##### [GCHandle](https://arongranberg.com/astar/docs/%3Cundefined%3E) graphNodeQueue --- # JobMovementPlaneFromNavmeshNormal - A* Pathfinding Project Struct JobMovementPlaneFromNavmeshNormal Extends IJobEntity =========================================================== Public Public Methods -------------- [Execute](https://arongranberg.com/astar/docs/jobmovementplanefromnavmeshnormal/execute.html#Execute) (managedState, localTransform, agentMovementPlane, shape) Public Variables ---------------- dt Public ##### float dt que Public ##### List<[GraphNode](https://arongranberg.com/astar/docs/graphnode.html) \> que vertices Public ##### NativeList<[Int3](https://arongranberg.com/astar/docs/int3.html) \> vertices --- # MovementStatistics - A* Pathfinding Project Struct MovementStatistics Extends IComponentData ================================================ Public Public Variables ---------------- estimatedVelocity The estimated velocity that the agent is moving with. Public ##### float3 estimatedVelocity The estimated velocity that the agent is moving with. This includes all form of movement, including local avoidance and gravity. lastPosition The position of the agent at the end of the last movement simulation step. Public ##### float3 lastPosition The position of the agent at the end of the last movement simulation step. --- # MovementSettings - A* Pathfinding Project Struct MovementSettings Extends IComponentData ============================================== Public Public Variables ---------------- debugFlags Flags for enabling debug rendering in the scene view. Public ##### [PIDMovement.DebugFlags](https://arongranberg.com/astar/docs/pidmovement.html#DebugFlags) debugFlags Flags for enabling debug rendering in the scene view. follower Additional movement settings. Public ##### [PIDMovement](https://arongranberg.com/astar/docs/pidmovement.html) follower Additional movement settings. groundMask Layer mask to use for ground placement. Public ##### [LayerMask](https://docs.unity3d.com/ScriptReference/LayerMask.html) groundMask Layer mask to use for ground placement. Make sure this does not include the layer of any colliders attached to this gameobject. See [GravityState](https://arongranberg.com/astar/docs/gravitystate.html) [https://docs.unity3d.com/Manual/Layers.html](https://docs.unity3d.com/Manual/Layers.html) isStopped Gets or sets if the agent should stop moving. Public ##### bool isStopped Gets or sets if the agent should stop moving. If this is set to true the agent will immediately start to slow down as quickly as it can to come to a full stop. The agent will still react to local avoidance and gravity (if applicable), but it will not try to move in any particular direction. The current path of the agent will not be cleared, so when this is set to false again the agent will continue moving along the previous path. This is a purely user-controlled parameter, so for example it is not set automatically when the agent stops moving because it has reached the target. Use [reachedEndOfPath](https://arongranberg.com/astar/docs/iastarai.html#reachedEndOfPath) for that. If this property is set to true while the agent is traversing an off-mesh link ([RichAI](https://arongranberg.com/astar/docs/richai.html) script only), then the agent will continue traversing the link and stop once it has completed it. Note This is not the same as the [simulateMovement](https://arongranberg.com/astar/docs/iastarai.html#simulateMovement) setting which some movement scripts have. The [simulateMovement](https://arongranberg.com/astar/docs/iastarai.html#simulateMovement) setting disables movement calculations completely (which among other things makes it not be affected by local avoidance or gravity). For the [AILerp](https://arongranberg.com/astar/docs/ailerp.html) movement script which doesn't use gravity or local avoidance anyway changing this property is very similar to changing [simulateMovement](https://arongranberg.com/astar/docs/iastarai.html#simulateMovement) . The [steeringTarget](https://arongranberg.com/astar/docs/iastarai.html#steeringTarget) property will continue to indicate the point which the agent would move towards if it would not be stopped. For most movement scripts, this will make the agent slow down quickly, but not instantly stop. If you want to instantly stop the agent, you could either disable the whole component instead (but then it will not react to local avoidance, of course, and it will clear its current path), or you could set [desiredVelocityWithoutLocalAvoidance](https://arongranberg.com/astar/docs/iastarai.html#desiredVelocityWithoutLocalAvoidance) to Vector3.zero, which will stop it immediately. positionSmoothing How much to smooth the visual position of the agent. Public ##### float positionSmoothing How much to smooth the visual position of the agent. This does not affect movement, but smoothes out the position of the agent visually. Recommended values are between 0.0 and 0.5. A value of zero will disable smoothing completely. This will make the agent seem to lag slightly behind the internal position of the agent. It may also cut corners slightly. The unit for this field is seconds. rotationSmoothing How much to smooth the visual rotation of the agent. Public ##### float rotationSmoothing How much to smooth the visual rotation of the agent. This does not affect movement, but smoothes out how the agent rotates visually. Recommended values are between 0.0 and 0.5. A value of zero will disable smoothing completely. The smoothing is done primarily using an exponential moving average, but with a small linear term to make the rotation converge faster when the agent is almost facing the desired direction. Adding smoothing will make the visual rotation of the agent lag a bit behind the actual rotation. Too much smoothing may make the agent seem sluggish, and appear to move sideways. The unit for this field is seconds. stopDistance How far away from the destination should the agent aim to stop, in world units. Public ##### float stopDistance How far away from the destination should the agent aim to stop, in world units. If the agent is within this distance from the destination point it will be considered to have reached the destination. Even if you want the agent to stop precisely at a given point, it is recommended to keep this slightly above zero. If it is exactly zero, the agent may have a hard time deciding that it has actually reached the end of the path, due to floating point errors and such. Note This will not be multiplied the agent's scale. Deprecated Members ------------------ movementPlaneSource How to calculate which direction is "up" for the agent. Public ##### [MovementPlaneSource](https://arongranberg.com/astar/docs/ecs2.html#MovementPlaneSource) movementPlaneSource How to calculate which direction is "up" for the agent. See [MovementPlaneSource](https://arongranberg.com/astar/docs/ecs2.html#MovementPlaneSource) Deprecated Use the [AgentMovementPlaneSource](https://arongranberg.com/astar/docs/agentmovementplanesource.html) component instead, or the movementPlaneSource property on the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component --- # MovementStatisticsSystem - A* Pathfinding Project Struct MovementStatisticsSystem Extends ISystem =============================================== Public System that updates the destination of agents with a [DestinationEntity](https://arongranberg.com/astar/docs/destinationentity.html) component. Every frame, the position of the target entity will be copied to the [DestinationPoint.destination](https://arongranberg.com/astar/docs/destinationpoint.html#destination) field of the agent. If [DestinationEntity.useRotation](https://arongranberg.com/astar/docs/destinationentity.html#useRotation) is true, the facing direction will also be copied. See [AIDestinationSetter](https://arongranberg.com/astar/docs/aidestinationsetter.html) Public Methods -------------- [OnUpdate](https://arongranberg.com/astar/docs/movementstatisticssystem/onupdate.html#OnUpdate) (state) --- # MovementState - A* Pathfinding Project Struct MovementState Extends IComponentData =========================================== Public Public Methods -------------- [MovementState](https://arongranberg.com/astar/docs/movementstate/movementstate.html#MovementState) (agentPosition) [SetPathIsEmpty](https://arongranberg.com/astar/docs/movementstate/setpathisempty.html#SetPathIsEmpty) (agentPosition) Sets the appropriate fields to indicate that the agent has no path. Public Variables ---------------- closestOnNavmesh The closest point on the navmesh to the agent. Public ##### float3 closestOnNavmesh The closest point on the navmesh to the agent. The agent will be snapped to this point. endOfPath The end of the current path. Public ##### float3 endOfPath The end of the current path. Note that the agent may be heading towards an off-mesh link which is not the same as this point. flags Bitmask for various flags. Public ##### ushort flags Bitmask for various flags. followerState State of the [PID](https://arongranberg.com/astar/docs/pid.html) controller for the movement. Public ##### [PIDMovement.PersistentState](https://arongranberg.com/astar/docs/persistentstate.html) followerState State of the [PID](https://arongranberg.com/astar/docs/pid.html) controller for the movement. graphIndex The index of the graph that the agent is currently traversing. Public ##### uint graphIndex The index of the graph that the agent is currently traversing. Will be [GraphNode.InvalidGraphIndex](https://arongranberg.com/astar/docs/graphnode.html#InvalidGraphIndex) if the agent has no path, or the node that the agent is traversing has been destroyed. hasValidEndPoint Public ##### bool? hasValidEndPoint hierarchicalNodeIndex The index of the hierarchical node that the agent is currently in. Public ##### int hierarchicalNodeIndex The index of the hierarchical node that the agent is currently in. Will be -1 if the hierarchical node index is not known. This field is valid during all system updates in the [AIMovementSystemGroup](https://arongranberg.com/astar/docs/aimovementsystemgroup.html) . It will be cleared at the end of that group by [JobClearTemporaryData](https://arongranberg.com/astar/docs/jobcleartemporarydata.html) , so you'll typically not be able to observe it during other times. It is cleared as a safety measure, as it is not guaranteed to be valid after that group has finished running, as graph updates may have changed the graph. See [HierarchicalGraph](https://arongranberg.com/astar/docs/hierarchicalgraph.html) isOnValidNode True if the agent is currently on a valid node. Public ##### bool isOnValidNode True if the agent is currently on a valid node. This is true if the agent has a path, and the node that the agent is traversing is walkable and not destroyed. If false, the [hierarchicalNodeIndex](https://arongranberg.com/astar/docs/movementstate.html#hierarchicalNodeIndex) and [graphIndex](https://arongranberg.com/astar/docs/movementstate.html#graphIndex) fields are invalid. nextCorner The next corner in the path. Public ##### float3 nextCorner The next corner in the path. pathTracerVersion Version number of [PathTracer.version](https://arongranberg.com/astar/docs/pathtracer.html#version) when the movement state was last updated. Public ##### ushort pathTracerVersion Version number of [PathTracer.version](https://arongranberg.com/astar/docs/pathtracer.html#version) when the movement state was last updated. In particular, [closestOnNavmesh](https://arongranberg.com/astar/docs/movementstate.html#closestOnNavmesh) , [nextCorner](https://arongranberg.com/astar/docs/movementstate.html#nextCorner) , [endOfPath](https://arongranberg.com/astar/docs/movementstate.html#endOfPath) , [remainingDistanceToEndOfPart](https://arongranberg.com/astar/docs/movementstate.html#remainingDistanceToEndOfPart) , [reachedDestination](https://arongranberg.com/astar/docs/movementstate.html#reachedDestination) and [reachedEndOfPath](https://arongranberg.com/astar/docs/movementstate.html#reachedEndOfPath) will only be considered up to date if this is equal to the current version number of the path tracer. positionOffset Offset from the agent's internal position to its visual position. Public ##### float3 positionOffset Offset from the agent's internal position to its visual position. This is used when position smoothing is enabled. Otherwise it is zero. reachedDestination True if the agent has reached its destination. Public ##### bool? reachedDestination True if the agent has reached its destination. The destination will be considered reached if all of these conditions are met: * The agent has a path * The path is not stale * The destination is not significantly below the agent's feet. * The destination is not significantly above the agent's head. * The agent is on the last part of the path (there are no more remaining off-mesh links). * The remaining distance to the end of the path + the distance from the end of the path to the destination is less than [MovementSettings.stopDistance](https://arongranberg.com/astar/docs/movementsettings.html#stopDistance) . reachedDestinationAndOrientation True if the agent has reached its destination and is facing the desired orientation. Public ##### bool? reachedDestinationAndOrientation True if the agent has reached its destination and is facing the desired orientation. This will become true if all of these conditions are met: * [reachedDestination](https://arongranberg.com/astar/docs/movementstate.html#reachedDestination) is true * The agent is facing the desired facing direction as specified in [DestinationPoint.facingDirection](https://arongranberg.com/astar/docs/destinationpoint.html#facingDirection) . reachedEndOfPart True if the agent has reached the end of the current part in the path. Public ##### bool? reachedEndOfPart True if the agent has reached the end of the current part in the path. The end of the current part will be considered reached if all of these conditions are met: * The agent has a path * The path is not stale * The end of the current part is not significantly below the agent's feet. * The end of the current part is not significantly above the agent's head. * The remaining distance to the end of the part is not significantly larger than the agent's radius. reachedEndOfPath True if the agent has reached the end of the path. Public ##### bool? reachedEndOfPath True if the agent has reached the end of the path. The end of the path will be considered reached if all of these conditions are met: * The agent has a path * The path is not stale * The end of the path is not significantly below the agent's feet. * The end of the path is not significantly above the agent's head. * The agent is on the last part of the path (there are no more remaining off-mesh links). * The remaining distance to the end of the path is less than [MovementSettings.stopDistance](https://arongranberg.com/astar/docs/movementsettings.html#stopDistance) . reachedEndOfPathAndOrientation True if the agent has reached its destination and is facing the desired orientation. Public ##### bool? reachedEndOfPathAndOrientation True if the agent has reached its destination and is facing the desired orientation. This will become true if all of these conditions are met: * [reachedEndOfPath](https://arongranberg.com/astar/docs/movementstate.html#reachedEndOfPath) is true * The agent is facing the desired facing direction as specified in [DestinationPoint.facingDirection](https://arongranberg.com/astar/docs/destinationpoint.html#facingDirection) . remainingDistanceToEndOfPart The remaining distance until the end of the path, or the next off-mesh link. Public ##### float remainingDistanceToEndOfPart The remaining distance until the end of the path, or the next off-mesh link. rotationOffset The current additional rotation that is applied to the agent. Public ##### float rotationOffset The current additional rotation that is applied to the agent. This is used by the local avoidance system to rotate the agent, without this causing a feedback loop. See [ResolvedMovement.targetRotationOffset](https://arongranberg.com/astar/docs/resolvedmovement.html#targetRotationOffset) rotationOffset2 An additional, purely visual, rotation offset. Public ##### float rotationOffset2 An additional, purely visual, rotation offset. This is used for rotation smoothing, but does not affect the movement of the agent. traversingLastPart True if the agent is traversing the last part of the path. Public ##### bool? traversingLastPart True if the agent is traversing the last part of the path. If false, the agent will have to traverse at least one off-mesh link before it gets to its destination. Public Static Variables ----------------------- GraphIndexMaskInFlags Public Static ##### const ushort GraphIndexMaskInFlags = (ushort)(0xFF << [GraphIndexOffsetInFlags](https://arongranberg.com/astar/docs/movementstate.html#GraphIndexOffsetInFlags) ) GraphIndexOffsetInFlags Public Static ##### const int GraphIndexOffsetInFlags = 8 HasValidEndPointFlag Public Static ##### const int HasValidEndPointFlag = 1 << 6 ReachedDestinationFlag Public Static ##### const int ReachedDestinationFlag = 1 << 0 ReachedEndOfPartFlag Public Static ##### const int ReachedEndOfPartFlag = 1 << 4 ReachedEndOfPathFlag Public Static ##### const int ReachedEndOfPathFlag = 1 << 2 TraversingLastPartFlag Public Static ##### const int TraversingLastPartFlag = 1 << 5 reachedDestinationAndOrientationFlag Public Static ##### const int reachedDestinationAndOrientationFlag = 1 << 1 reachedEndOfPathAndOrientationFlag Public Static ##### const int reachedEndOfPathAndOrientationFlag = 1 << 3 --- # OrientationYAxisForward - A* Pathfinding Project Struct OrientationYAxisForward Extends IComponentData ===================================================== Public Tag component to indicate that the agent's forward direction is along the Y axis. This is used to convert between the forward direction of the GameObject and the internal forward direction, which always uses +Z as forward. See [FollowerEntity.orientation](https://arongranberg.com/astar/docs/followerentity.html#orientation) [OrientationMode](https://arongranberg.com/astar/docs/pathfinding.html#OrientationMode) --- # MovementTarget - A* Pathfinding Project Struct MovementTarget ===================== Public Public Methods -------------- [MovementTarget](https://arongranberg.com/astar/docs/movementtarget/movementtarget.html#MovementTarget) (isReached) Public Variables ---------------- reached Public ##### bool reached Private/Protected Members ------------------------- isReached Internal ##### bool isReached --- # PhysicsSceneRef - A* Pathfinding Project Struct PhysicsSceneRef Extends ISharedComponentData, IQueryTypeParameter, System::IEquatable ============================================================================================================= Public The physics scene to use for raycasting. For most games, this will be the default physics scene. But if your game has more than one physics scene, you can use this component to specify which one to use. The [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) will use PhysicsSceneExtensions.GetPhysicsScene to get the physics scene from the GameObject that the [FollowerEntity](https://arongranberg.com/astar/docs/followerentity.html) component is attached to. Public Methods -------------- [Equals](https://arongranberg.com/astar/docs/physicssceneref/equals.html#Equals) (other) [GetHashCode](https://arongranberg.com/astar/docs/physicssceneref/gethashcode.html#GetHashCode) () Public Variables ---------------- physicsScene Public ##### PhysicsScene physicsScene --- # ReadyToTraverseOffMeshLink - A* Pathfinding Project Struct ReadyToTraverseOffMeshLink Extends IComponentData, IEnableableComponent ============================================================================== Public Enabled if the agnet is ready to start traversing an off-mesh link. --- # PollPendingPathsSystem - A* Pathfinding Project Struct PollPendingPathsSystem Extends ISystem ============================================= Public Checks if paths have been calculated, and updates the agent's paths if they have. This is essentially a replacement for [Path.callback](https://arongranberg.com/astar/docs/path.html#callback) for [ECS](https://arongranberg.com/astar/docs/ecs2.html) agents. This system is a bit different in that it doesn't run in the normal update loop, but instead it will run when the [AstarPath.OnPathsCalculated](https://arongranberg.com/astar/docs/astarpath.html#OnPathsCalculated) event fires. This is to avoid having to call a separate callback for every agent, since that would result in excessive overhead as it would have to synchronize with the [ECS](https://arongranberg.com/astar/docs/ecs2.html) world on every such call. See [AstarPath.OnPathsCalculated](https://arongranberg.com/astar/docs/astarpath.html#OnPathsCalculated) Public Methods -------------- [OnCreate](https://arongranberg.com/astar/docs/pollpendingpathssystem/oncreate.html#OnCreate) (state) [OnDestroy](https://arongranberg.com/astar/docs/pollpendingpathssystem/ondestroy.html#OnDestroy) (state) [OnUpdate](https://arongranberg.com/astar/docs/pollpendingpathssystem/onupdate.html#OnUpdate) (systemState) Public Variables ---------------- entityQueryPrepare Public ##### EntityQuery entityQueryPrepare jobRepairPathScheduler Public ##### [JobRepairPath.Scheduler](https://arongranberg.com/astar/docs/scheduler.html) jobRepairPathScheduler onPathsCalculated Public ##### [GCHandle](https://arongranberg.com/astar/docs/%3Cundefined%3E) onPathsCalculated Public Static Variables ----------------------- anyPendingPaths Public Static ##### bool anyPendingPaths --- # RepairPathSystem - A* Pathfinding Project Struct RepairPathSystem Extends ISystem ======================================= Public Public Methods -------------- [OnCreate](https://arongranberg.com/astar/docs/repairpathsystem/oncreate.html#OnCreate) (state) [OnDestroy](https://arongranberg.com/astar/docs/repairpathsystem/ondestroy.html#OnDestroy) (state) [OnUpdate](https://arongranberg.com/astar/docs/repairpathsystem/onupdate.html#OnUpdate) (systemState) Public Static Methods --------------------- [NextLinkToTraverse](https://arongranberg.com/astar/docs/repairpathsystem/nextlinktotraverse.html#NextLinkToTraverse) (state) [ResolveOffMeshLinkHandler](https://arongranberg.com/astar/docs/repairpathsystem/resolveoffmeshlinkhandle.html#ResolveOffMeshLinkHandler) (settings, ctx) Public Variables ---------------- entityQueryPrepare Public ##### EntityQuery entityQueryPrepare jobRepairPathScheduler Public ##### [JobRepairPath.Scheduler](https://arongranberg.com/astar/docs/scheduler.html) jobRepairPathScheduler --- # SchedulePathSearchSystem - A* Pathfinding Project Struct SchedulePathSearchSystem Extends ISystem =============================================== Public Inner Types ----------- [JobCheckStaleness](https://arongranberg.com/astar/docs/jobcheckstaleness.html) [JobRecalculatePaths](https://arongranberg.com/astar/docs/jobrecalculatepaths.html) [JobShouldRecalculatePaths](https://arongranberg.com/astar/docs/jobshouldrecalculatepaths.html) Public Methods -------------- [OnUpdate](https://arongranberg.com/astar/docs/schedulepathsearchsystem/onupdate.html#OnUpdate) (systemState) Public Static Variables ----------------------- MarkerCheckStaleness Public Static Readonly ##### ProfilerMarker MarkerCheckStaleness = new ProfilerMarker("Check [Path](https://arongranberg.com/astar/docs/path.html) Staleness") MarkerRecalculatePaths Public Static Readonly ##### ProfilerMarker MarkerRecalculatePaths = new ProfilerMarker("Schedule [Path](https://arongranberg.com/astar/docs/path.html) Calculations") MarkerSchedulePathSearch Public Static Readonly ##### ProfilerMarker MarkerSchedulePathSearch = new ProfilerMarker("Schedule [Path](https://arongranberg.com/astar/docs/path.html) Search") MarkerShouldRecalculatePaths Public Static Readonly ##### ProfilerMarker MarkerShouldRecalculatePaths = new ProfilerMarker("Check Should Recalculate Paths") --- # JobCheckStaleness - A* Pathfinding Project Struct JobCheckStaleness Extends IJobEntity, IJobEntityChunkBeginEnd ==================================================================== Public Public Methods -------------- [Execute](https://arongranberg.com/astar/docs/jobcheckstaleness/execute.html#Execute) (state) [OnChunkBegin](https://arongranberg.com/astar/docs/jobcheckstaleness/onchunkbegin.html#OnChunkBegin) (chunk, unfilteredChunkIndex, useEnabledMask, chunkEnabledMask) [OnChunkEnd](https://arongranberg.com/astar/docs/jobcheckstaleness/onchunkend.html#OnChunkEnd) (chunk, unfilteredChunkIndex, useEnabledMask, chunkEnabledMask, chunkWasExecuted) Public Variables ---------------- index Public ##### int index isPathStale Public ##### NativeBitArray isPathStale --- # JobRecalculatePaths - A* Pathfinding Project Struct JobRecalculatePaths Extends IJobEntity ============================================= Public Public Methods -------------- [Execute](https://arongranberg.com/astar/docs/jobrecalculatepaths/execute.html#Execute) (state, settings, autoRepathPolicy, transform, destination, movementPlane) Public Static Methods --------------------- [MaybeRecalculatePath](https://arongranberg.com/astar/docs/jobrecalculatepaths/mayberecalculatepath.html#MaybeRecalculatePath) (state, settings, autoRepathPolicy, transform, destination, movementPlane, time, wantsToRecalculatePath) Public Variables ---------------- time Public ##### float time --- # JobShouldRecalculatePaths - A* Pathfinding Project Struct JobShouldRecalculatePaths Extends IJobEntity =================================================== Public Public Methods -------------- [Execute](https://arongranberg.com/astar/docs/jobshouldrecalculatepaths/execute.html#Execute) (autoRepathPolicy, transform, shape, destination, shouldRecalculatePath) Public Variables ---------------- index Public ##### int index isPathStale Public ##### NativeBitArray isPathStale time Public ##### float time --- # SearchState - A* Pathfinding Project Struct SearchState Extends IComponentData ========================================= Public --- # SimulateMovement - A* Pathfinding Project Struct SimulateMovement Extends IComponentData ============================================== Public Tag component to enable movement for an entity. Without this component, most systems will completely ignore the entity. There are some more specific components that can be used to selectively enable/disable some jobs: * [SimulateMovementRepair](https://arongranberg.com/astar/docs/simulatemovementrepair.html) * [SimulateMovementControl](https://arongranberg.com/astar/docs/simulatemovementcontrol.html) * [SimulateMovementFinalize](https://arongranberg.com/astar/docs/simulatemovementfinalize.html) Removing one of the above components can be useful if you want to override the movement of an agent in some way. --- # SimulateMovementControl - A* Pathfinding Project Struct SimulateMovementControl Extends IComponentData ===================================================== Public Tag component to allow the agent to calculate how it wants to move. Allows the [JobControl](https://arongranberg.com/astar/docs/jobcontrol.html) to run. --- # SimulateMovementFinalize - A* Pathfinding Project Struct SimulateMovementFinalize Extends IComponentData ====================================================== Public Tag component to allow the agent to move according to its desired movement parameters. Allows [AIMoveSystem](https://arongranberg.com/astar/docs/aimovesystem.html) to run the [JobApplyGravity](https://arongranberg.com/astar/docs/jobapplygravity.html) and [JobMoveAgent](https://arongranberg.com/astar/docs/jobmoveagent.html) jobs. By removing this, you can override how the agent's desired movement is converted to actual movement. This snippet replicates most of the built-in movement: `var ai = GetComponent(); // Prevent the agent from moving itself, so that we can override it. ai.world.EntityManager.RemoveComponent(ai.entity); // This will run once or more per frame, and allows you to hook into the movement logic ai.movementOverrides.AddBeforeMovementCallback((Unity.Entities.Entity entity, float dt, ref Unity.Transforms.LocalTransform localTransform, ref AgentCylinderShape shape, ref AgentMovementPlane movementPlane, ref DestinationPoint destination, ref MovementState movementState, ref MovementSettings movementSettings, ref MovementControl movementControl, ref ResolvedMovement resolvedMovement) => { // Just replicate the normal movement as an example, except for gravity and ground collision localTransform.Rotation = JobMoveAgent.ResolveRotation(localTransform.Rotation, ref movementState, in resolvedMovement, in movementSettings, in movementPlane, dt); localTransform.Position += JobMoveAgent.MoveWithoutGravity(localTransform.Position, in resolvedMovement, in movementPlane, dt); }); `Or if you prefer to handle more things yourself: `void Start () { var ai = GetComponent(); // Prevent the agent from moving itself, so that we can override it. ai.world.EntityManager.RemoveComponent(ai.entity); } void Update () { var ai = GetComponent(); // Read how the agent wants to move var resolved = ai.world.EntityManager.GetComponentData(ai.entity); var movementPlane = ai.world.EntityManager.GetComponentData(ai.entity); var movementState = ai.world.EntityManager.GetComponentData(ai.entity); var targetRot = movementPlane.value.ToWorldRotation(resolved.targetRotation + resolved.targetRotationOffset); var movementSettings = ai.world.EntityManager.GetComponentData(ai.entity); var dt = Time.deltaTime; // Move the agent. // This is a very simplified movement logic which has some limitations (it won't work well with local avoidance for example, and since it always runs exactly once per frame, it cannot handle higher time scales), // but it demonstrates the basic idea. Check out the source code for JobMoveAgent for more inspiration. ai.transform.rotation = Quaternion.RotateTowards(ai.transform.rotation, targetRot, resolved.rotationSpeed * dt * Mathf.Rad2Deg); ai.transform.position += Vector3.ClampMagnitude((Vector3)resolved.targetPoint - ai.transform.position, resolved.speed * dt); // Write back the movement state if we have made any changes // In this example we don't, but it's common to want to do this. ai.world.EntityManager.SetComponentData(ai.entity, movementState); } ` --- # SimulateMovementRepair - A* Pathfinding Project Struct SimulateMovementRepair Extends IComponentData ==================================================== Public Tag component to allow the agent to repair its path and recalculate various statistics. Allows the [JobRepairPath](https://arongranberg.com/astar/docs/jobrepairpath.html) to run. Note [JobRepairPath](https://arongranberg.com/astar/docs/jobrepairpath.html) will, at the moment, run even if this component is not present, when manually setting some properties on the agent (e.g. ai.position, ai.destination, etc.). Create a forum post if you have a use case which isn't supported by this. --- # SyncDestinationTransformSystem - A* Pathfinding Project Struct SyncDestinationTransformSystem Extends ISystem ===================================================== Public Public Methods -------------- [OnUpdate](https://arongranberg.com/astar/docs/syncdestinationtransformsystem/onupdate.html#OnUpdate) (systemState) --- # SyncPositionWithTransform - A* Pathfinding Project Struct SyncPositionWithTransform Extends IComponentData ======================================================= Public Tag component to enable syncing between an agent's Transform and the agent entity's position. See [FollowerEntity.updatePosition](https://arongranberg.com/astar/docs/followerentity.html#updatePosition) --- # SyncRotationWithTransform - A* Pathfinding Project Struct SyncRotationWithTransform Extends IComponentData ======================================================= Public Tag component to enable syncing between an agent's Transform and the agent entity's rotation. See [FollowerEntity.updateRotation](https://arongranberg.com/astar/docs/followerentity.html#updateRotation) ---