Overview | Package | Class | Source | Class tree | Glossary | UnrealScript Documentation |
previous class next class | frames no frames |
00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019 00020 00021 00022 00023 00024 00025 00026 00027 00028 00029 00030 00031 00032 00033 00034 00035 00036 00037 00038 00039 00040 00041 00042 00043 00044 00045 00046 00047 00048 00049 00050 00051 00052 00053 00054 00055 00056 00057 00058 00059 00060 00061 00062 00063 00064 00065 00066 00067 00068 00069 00070 00071 00072 00073 00074 00075 00076 00077 00078 00079 00080 00081 00082 00083 00084 00085 00086 00087 00088 00089 00090 00091 00092 00093 00094 00095 00096 00097 00098 00099 00100 00101 00102 00103 00104 00105 00106 00107 00108 00109 00110 00111 00112 00113 00114 00115 00116 00117 00118 00119 00120 00121 00122 00123 00124 00125 00126 00127 00128 00129 00130 00131 00132 00133 00134 00135 00136 00137 00138 00139 00140 00141 00142 00143 00144 00145 00146 00147 00148 00149 00150 00151 00152 00153 00154 00155 00156 00157 00158 00159 00160 00161 00162 00163 00164 00165 00166 00167 00168 00169 00170 00171 00172 00173 00174 00175 00176 00177 00178 00179 00180 00181 00182 00183 00184 00185 00186 00187 00188 00189 00190 00191 00192 00193 00194 00195 00196 00197 00198 00199 00200 00201 00202 00203 00204 00205 00206 00207 00208 00209 00210 00211 00212 00213 00214 00215 00216 00217 00218 00219 00220 00221 00222 00223 00224 00225 00226 00227 00228 00229 00230 00231 00232 00233 00234 00235 00236 00237 00238 00239 00240 00241 00242 00243 00244 00245 00246 00247 00248 00249 00250 00251 00252 00253 00254 00255 00256 00257 00258 00259 00260 00261 00262 00263 00264 00265 00266 00267 00268 00269 00270 00271 00272 00273 00274 00275 00276 00277 00278 00279 00280 00281 00282 00283 00284 00285 00286 00287 00288 00289 00290 00291 00292 00293 00294 00295 00296 00297 00298 00299 00300 00301 00302 00303 00304 00305 00306 00307 00308 00309 00310 00311 00312 00313 00314 00315 00316 00317 00318 00319 00320 00321 00322 00323 00324 00325 00326 00327 00328 00329 00330 00331 00332 00333 00334 00335 00336 00337 00338 00339 00340 00341 00342 00343 00344 00345 00346 00347 00348 00349 00350 00351 00352 00353 00354 00355 00356 00357 00358 00359 00360 00361 00362 00363 00364 00365 00366 00367 00368 00369 00370 00371 00372 00373 00374 00375 00376 00377 00378 00379 00380 00381 00382 00383 00384 00385 00386 00387 00388 00389 00390 00391 00392 00393 00394 00395 00396 00397 00398 00399 00400 00401 00402 00403 00404 00405 00406 00407 00408 00409 00410 00411 00412 00413 00414 00415 00416 00417 00418 00419 00420 00421 00422 00423 00424 00425 00426 00427 00428 00429 00430 00431 00432 00433 00434 00435 00436 00437 00438 00439 00440 00441 00442 00443 00444 00445 00446 00447 00448 00449 00450 00451 00452 00453 00454 00455 00456 00457 00458 00459 00460 00461 00462 00463 00464 00465 00466 00467 00468 00469 00470 00471 00472 00473 00474 00475 00476 00477 00478 00479 00480 00481 00482 00483 00484 00485 00486 00487 00488 00489 00490 00491 00492 00493 00494 00495 00496 00497 00498 00499 00500 00501 00502 00503 00504 00505 00506 00507 00508 00509 00510 00511 00512 00513 00514 00515 00516 00517 00518 00519 00520 00521 00522 00523 00524 00525 00526 00527 00528 00529 00530 00531 00532 00533 00534 00535 00536 00537 00538 00539 00540 00541 00542 00543 00544 00545 00546 00547 00548 00549 00550 00551 00552 00553 00554 00555 00556 00557 00558 00559 00560 00561 00562 00563 00564 00565 00566 00567 00568 00569 00570 00571 00572 00573 00574 00575 00576 00577 00578 00579 00580 00581 00582 00583 00584 00585 00586 00587 00588 00589 00590 00591 00592 00593 00594 00595 00596 00597 00598 00599 00600 00601 00602 00603 00604 00605 00606 00607 00608 00609 00610 00611 00612 00613 00614 00615 00616 00617 00618 00619 00620 00621 00622 00623 00624 00625 00626 00627 00628 00629 00630 00631 00632 00633 00634 00635 00636 00637 00638 00639 00640 00641 00642 00643 00644 00645 00646 00647 00648 00649 00650 00651 00652 00653 00654 00655 00656 00657 00658 00659 00660 00661 00662 00663 00664 00665 00666 00667 00668 00669 00670 00671 00672 00673 00674 00675 00676 00677 00678 00679 00680 00681 00682 00683 00684 00685 00686 00687 00688 00689 00690 00691 00692 00693 00694 00695 00696 00697 00698 00699 00700 00701 00702 00703 00704 00705 00706 00707 00708 00709 00710 00711 00712 00713 00714 00715 00716 00717 00718 00719 00720 00721 00722 00723 00724 00725 00726 00727 00728 00729 00730 00731 00732 00733 00734 00735 00736 00737 00738 00739 00740 00741 00742 00743 00744 00745 00746 00747 00748 00749 00750 00751 00752 00753 00754 00755 00756 00757 00758 00759 00760 00761 00762 00763 00764 00765 00766 00767 00768 00769 00770 00771 00772 00773 00774 00775 00776 00777 00778 00779 00780 00781 00782 00783 00784 00785 00786 00787 00788 00789 00790 00791 00792 00793 00794 00795 00796 00797 00798 00799 00800 00801 00802 00803 00804 00805 00806 00807 00808 00809 00810 00811 00812 00813 00814 00815 00816 00817 00818 00819 00820 00821 00822 00823 00824 00825 00826 00827 00828 00829 00830 00831 |
//============================================================================= // NavigationHandle // // Component that encapsulates navigation behavior. Attach this to your actor of choice to // enable that actor to pathfind // // Copyright 1998-2011 Epic Games, Inc. All Rights Reserved. //============================================================================= class NavigationHandle extends Object within Actor native(AI); struct native PolySegmentSpan { var native pointer Poly{FNavMeshPolyBase}; var Vector P1, P2; structcpptext { explicit FPolySegmentSpan( struct FNavMeshPolyBase* inPoly, FVector inP1, FVector inP2 ) { Poly = inPoly; P1 = inP1; P2 = inP2; } } }; /** Current pylon AI is anchored to */ var Pylon AnchorPylon; var native pointer AnchorPoly{FNavMeshPolyBase}; /** dummy struct used to match alignment in pathcache array */ struct {FNavMeshEdgeBase*} EdgePointer { var native const pointer Dummy{FNavMeshEdgeBase}; }; // struct containing the patchcache aray. Used so that // pathcaches can easily be stored and copied around in script struct native PathStore { structcpptext { FORCEINLINE FNavMeshEdgeBase*& operator()( INT i ) { return EdgeList(i); } FORCEINLINE INT Num() { return EdgeList.Num(); } FNavMeshEdgeBase*& Last( INT c=0 ) { return EdgeList.Last(c); } FNavMeshEdgeBase*& Top() { return Last(); } } var const native array<EdgePointer> EdgeList; }; var PathStore PathCache; /** * This points to the BestUnfinishedPathPoint. Which will usually be set by some EvaluateGoal or DetermineFinalGoal function/ * In some cases it is not possible to get a full path, but having the best unfinished path is good enough (e.g. ai on top * of a crevice, or on a navmesh island disconnected from everyone else) **/ var transient native pointer BestUnfinishedPathPoint{FNavMeshPolyBase}; /** List of polys to move through */ var const native pointer CurrentEdge{FNavMeshEdgeBase}; /** the poly we're currently trying to get inside */ var const native pointer SubGoal_DestPoly{FNavMeshPolyBase}; /** Final destination */ var BasedPosition FinalDestination; /** AI should not update route cache - flag to prevent cache from being changed when pathing is used to evaluate squad location */ var bool bSkipRouteCacheUpdates; const LINECHECK_GRANULARITY = 768.f; /** List of search constraints for pathing */ var NavMeshPathConstraint PathConstraintList; var NavMeshPathGoalEvaluator PathGoalList; /** when this is TRUE the goal evaluator chain will be treated as an OR chain instead of an AND chain */ var bool bUseORforEvaluateGoal; /** this is a handy way of ensuring everyone is setting the necessary parameters.. this should always reflect the number of * parameters in the NavMeshPathParams struct, and then in SetupPathingParams a check will be inserted with the * number of params in existence at the time of writing the function, so if the number of params changes and the implementations * are not updated an assert will fire */ const NUM_PATHFINDING_PARAMS = 9; // this struct is where all the non-volatile pathing params are cached at the beginning of a path search. // Populated from Interface_NavigationHandle::SetupPathfindingParams() struct native NavMeshPathParams { /** the navhandle interface for the pathing entity */ var native pointer Interface{IInterface_NavigationHandle}; /** can this entity use mantle edges? */ var bool bCanMantle; /** do we need to perform extra checks when determining if an edge supports the entiy? */ var bool bNeedsMantleValidityTest; /** is this entity valid to pathfind (does it have a pawn, etc..) */ var bool bAbleToSearch; /** the size of the entity looking for a path */ /* @NOTE: this will use the LARGEST of the X/Y dimensions. Pathfinding extents must be symmetrical, so if the extent is not, it will be made to be symmetric. (for long train-like objects path with the extent of the leader, and the rest will follow) @see FNavMeshEdgeBase::Supports() */ var Vector SearchExtent; var float SearchLaneMultiplier; /** the starting location for the path search */ var vector SearchStart; /** the maximum valid height for this entity to 'drop down' (e.g. max height to use on dropdown edges) */ var float MaxDropHeight; /** the minimum value for the Z component of walkable surfaces */ var float MinWalkableZ; /** max hover distance -- the maximum distance this entity can hover above the surface of a polygon. (-1 means arbitrarily high) */ var float MaxHoverDistance; }; // the cached path params for the current search var NavMeshPathParams CachedPathParams; /** when this bool is TRUE, statistics about which constraints are doing what will be printed following * path searches */ var(PathDebug) bool bDebugConstraintsAndGoalEvals; /** * when true TONS of information will be printed to the log, as well as a bunch of stuff drawn to the screen. * debug lines will be drawn indicating the progress of the path traversal, and whenever a log message is printed related * to an edge on the navmesh a number will be printed to the screen above it indexing into the log messages to tell you * what that message is. * RED lines indicate expansion was stopped at that step, other colors will change depending on the expansion generation * (e.g. all edges traversed in the first step will be of the same color, second step a different color etc.. */ var(PathDebug) bool bUltraVerbosePathDebugging; /** * Relevant error code set by FindPath when a path search fails. * Allows decision on how to resolve a failed search by providing more information on the failure cause . * Only valid if FindPath returns FALSE. Safe to ignore otherwise. * This value is not updated until the next search fails. */ var(PathDebug) EPathFindingError LastPathError; var(PathDebug) float LastPathFailTime; cpptext { public: UNavigationHandle() { if(!IsTemplate()) { FNavMeshWorld::RegisterActiveHandle(this); } } // use this in SetupPathingParams and pass the number of params you have populated to ensure when new properties // are added to the struct that you are setting them all #define VERIFY_NAVMESH_PARAMS(NUM) \ typedef char ERROR_Missing_NavMesh_param_please_Set_all_Params[( NUM != UCONST_NUM_PATHFINDING_PARAMS ) ? 0 : 1]; // returns TRUE if the pylon and poly associated with the interface's current location can be found static UBOOL GetPylonAndPolyFromActorPos( AActor* Actor, APylon*& out_Pylon, struct FNavMeshPolyBase*& out_Poly); /** * GetPylonANdPolyFromPos * - will search for the pylon and polygon that contain this point * @param Pos - position to get pylon and poly from * @param out_Pylon - output var for pylon this position is within * @param out_Poly - output var for poly this position is within * @return - TRUE if the pylon and poly were found succesfully */ static UBOOL GetPylonAndPolyFromPos(const FVector& Pos, FLOAT MinWalkableFloorZ, APylon*& out_Pylon, struct FNavMeshPolyBase*& out_Poly); /** * GetAllPylonsFromPos * - will populate a list of all pylons which are valid (in terms of can a pawn walk from the possible pylon) for the given position * @param Pos - position to test * @param out_Pylons - list of pylons to be populated with results * @param bWalkable - whether or not this pylon's polys need to be "walkable" FALSE for looking for disconnected pylons * @return TRUE if any pylons were found */ static UBOOL GetAllPylonsFromPos(const FVector& Pos, const FVector& Extent, TArray<APylon*>& out_Pylons, UBOOL bWalkable = TRUE ); /** * GetPylonAndPolyFromBox * - will search for the pylon and polygon that contain this box * @param Box - the box to use to find a poly for * @param out_Pylon - output var for pylon this position is within * @param out_Poly - output var for poly this position is within * @return - TRUE if the pylon and poly were found succesfully */ static UBOOL GetPylonAndPolyFromBox(const FBox& Box, FLOAT MinWalkableZ, APylon*& out_Pylon, struct FNavMeshPolyBase*& out_Poly); /** * GetAnchorPoly * - will find a suitable anchor (start) poly for this handle * @return - the suitable poly (if any) */ FNavMeshPolyBase* GetAnchorPoly(); /** * GetAllPolysFromPos * will return all polys in any mesh which are within the passed extent * @param Pos - Center of extent to check * @param Extent - extent of box to check * @param out_PolyList - output array of polys to check * @param bIgnoreDynamic - if TRUE, dynamically created submeshes will be ignored * @param bReturnBothDynamicAndStatic - if TRUE, BOTH dynamic and static polys will be returned.. using this is *DANGEROUS*! most of the time you should use dynamic polys if they exist * as they are the 'correct' representation of the mesh at that point * @return TRUE if polys were found */ static UBOOL GetAllPolysFromPos( const FVector& Pos, const FVector& Extent, TArray<struct FNavMeshPolyBase*>& out_PolyList, UBOOL bIgnoreDynamic, UBOOL bReturnBothDynamicAndStatic=FALSE ); /** * GetAllObstaclePolysFromPos * will return all obstacle polys in any mesh which are within the passed extent * @param Pos - Center of extent to check * @param Extent - extent of box to check * @param out_PolyList - output array of polys to check * @param PylonsToCheck - OPTIONAL param indicating the lsit of pylons we should check instead of hitting the pylon octree * @return TRUE if polys were found */ static void GetAllObstaclePolysFromPos( const FVector& Pos, const FVector& Extent, TArray<struct FNavMeshPolyBase*>& out_PolyList, const TArray<APylon*>* PylonsToCheck=NULL); // returns TRUE if the AABB provided intersects a loaded portion of the mesh static UBOOL BoxIntersectsMesh( const FVector& Center, const FVector& Extent, APylon*& out_Pylon, struct FNavMeshPolyBase*& out_Poly); /** * returns TRUE if the poly described by the passed list of vectors intersects a loaded portion of the mesh * @param Poly - vertexlist representing the poly we want to query against the mesh * @param out_Pylon - pylon we collided with * @param out_Poly - poly we collided with * @arapm ExclusionPolys - optional list of polys we want to exclude from the search * @param bIgnoreImportedMeshes - when TRUE meshes which unwalkable surfaces will be ignored for overlap testing * @param IgnorePylons - optional pylons to ignore collisions from * @return TRUE if poly intersects */ static UBOOL PolyIntersectsMesh( TArray<FVector>& Poly, APylon*& out_Pylon, struct FNavMeshPolyBase*& out_Poly, TArray<FNavMeshPolyBase*>* ExclusionPolys=NULL, UBOOL bIgnoreImportedMeshes=FALSE, TArray<APylon*>* IgnorePylons=NULL); // queries the pylon octree and returns a list of pylons that intersect the given AABB static void GetIntersectingPylons(const FVector& Loc, const FVector& Extent, TArray<APylon*>& out_Pylons); /** * Given a line segment, walks along the segment returning all polys that it crosses as entry and exit points of that segment * (will find spans from any navmesh in the world) * @param Start - Start point of span to check * @param End - end point of span * @Param out_Spans - out array of spans found and the polys they link to */ static void GetPolySegmentSpanList( FVector& Start, FVector& End, TArray<struct FPolySegmentSpan>& out_Spans ); /** * static function that will do an obstacle line check against any pylon's meshes colliding with the line passed * @param InOuter - The Outer which owns this NavHandle. Can be used for debugging * @param Hit - Hitresult struct for line check * @param Start - start of line check * @param End - end of line check * @param Extent - extent of box to sweep * @param bIgnoreNormalMesh - OPTIONAL - default:FALSE - when TRUE no checks against the walkable mesh will be performed * @param out_HitPoly - optional output param stuffed with the poly we collided with (if any) * @param PylonsToCheck - OPTIONAL, if present only these pylons' meshes will be linecheck'd * @param TraceFlags - bitfield to control tracing options * @return TRUE if nothing hit */ static UBOOL StaticObstacleLineCheck( const UObject* const InOuter, FCheckResult& Hit, FVector Start, FVector End, FVector Extent, UBOOL bIgnoreNormalMesh=FALSE, FNavMeshPolyBase** out_HitPoly=NULL, const TArray<APylon*>* PylonsToCheck=NULL, DWORD TraceFlags=0); /** * static function that will do a point check agains the obstacle mesh * @param Hit - hitresult struct for point check * @param Pt - centroid of extent box to point check * @param Extent - extent of box to point check * @param out_HitPoly - optional output param stuffed with the poly we collided with (if any) * @param PylonsToCheck - OPTIONAL, if present only these pylons' meshes will be linecheck'd * @param bSkipPointInMeshCheck - OPTIONAL, if TRUE ONLY a pointcheck against the obstacle mesh will be done, no verification that the point is on the mesh somewhere will be done (be careful with this one!) * @return TRUE if nothing hit */ static UBOOL StaticObstaclePointCheck(FCheckResult& Hit,FVector Pt,FVector Extent, FNavMeshPolyBase** out_HitPoly=NULL, const TArray<APylon*>* PylonsToCheck=NULL, UBOOL bSkipPointInMeshCheck=FALSE); /** * static function that will do a line check against any pylon's (walkable) meshes colliding with the line passed * @param Hit - Hitresult struct for line check * @param Start - start of line check * @param End - end of line check * @param Extent - extent of box to sweep * @param out_HitPoly - OPTIONAL, output param for hit poly * @param PylonsToCheck - OPTIONAL, if present only these pylons' meshes will be linecheck'd * @param TraceFlags - bitfield to control tracing options * @return TRUE if nothing hit */ static UBOOL StaticLineCheck(FCheckResult& Hit, FVector Start,FVector End,FVector Extent, FNavMeshPolyBase** out_HitPoly=NULL, const TArray<APylon*>* PylonsToCheck=NULL, DWORD TraceFlags=0); /** * static function that will do a point check agains the walkable * @param Hit - hitresult struct for point check * @param Pt - centroid of extent box to point check * @param Extent - extent of box to point check * @param out_HitPoly - OPTIONAL, poly the pointcheck hit * @param PylonsToCheck - OPTIONAL, if present only these pylons' meshes will be linecheck'd * @return TRUE of nothing hit */ static UBOOL StaticPointCheck(FCheckResult& Hit,FVector Pt,FVector Extent, FNavMeshPolyBase** out_HitPoly=NULL, const TArray<APylon*>* PylonsToCheck=NULL); static APylon* StaticGetPylonFromPos( FVector Position ); UBOOL PathCache_Empty( FPathStore* PCache ); UBOOL PathCache_AddEdge( FNavMeshEdgeBase* Edge, FPathStore* PCache = NULL ); UBOOL PathCache_InsertEdge( FNavMeshEdgeBase* Edge, int Idx=0, FPathStore* PCache = NULL ); UBOOL PathCache_RemoveEdge( FNavMeshEdgeBase* Edge, FPathStore* PCache = NULL ); UBOOL PathCache_RemoveIndex( int InIdx, int Count, FPathStore* PCache ); FVector PathCache_GetGoalPoint( FPathStore* PCache ); // Pathing functions /** * internal function which does the heavy lifting for A* searches (typically called from FindPath() * @param out_DestActor - output param goal evals can set if a particular actor was the result of the search * @param out_DestItem - output param goal evans can set if they need an index into something (e.g. cover slot) * @return - TRUE If search found a goal */ virtual UBOOL GeneratePath( class AActor** out_DestActor, INT* out_DestItem ); /** * Adds successor edges from the given poly to the A* search * @param CurPoly - poly to add sucessor edges for * @param PathParams - path params being used to search currently * @param PredecessorEdge - edge we got to this poly from * @param PathSessionID - SessionID for this pathfind * @param OpenList - first edge on the open list */ void AddSuccessorEdgesForPoly(FNavMeshPolyBase* CurPoly, const FNavMeshPathParams& PathParams, FNavMeshEdgeBase* PredecessorEdge, INT PathSessionID, PathOpenList& OpenList, INT OverrideVisitedCost=-1, INT OverrideHeuristicCost=-1); /** * finds the best node in the list, and pulls it out and returns it * (assumes list is sorted) * @param OpenList - list to find best node from * @return the best node in the list */ PathCardinalType PopBestNode( PathOpenList& OpenList ); /** * InsertSorted * inserts the passed node into the passed list at the proper spot to maintain sort order * @param NodeForInsertion - node to insert into the list * @param OpenList - list ot insert into * @return TRUE if succesful */ UBOOL InsertSorted( PathCardinalType NodeForInsertion, PathOpenList& OpenList ); UBOOL AddNodeToOpen( PathOpenList& OpenList, PathCardinalType NodeToAdd, INT EdgeCost, INT HeuristicCost, PathCardinalType Predecessor, const FVector& PrevPos, FNavMeshPolyBase* DestinationPolyForEdge); void RemoveNodeFromOpen( PathCardinalType NodeToRemove, PathOpenList& OpenList ); /** * will loop through all constraints in the constraint list and let them have their say on the current cost of the edge being considered * @param Edge - the edge being considered * @param SrcPoly - the poly we're coming from * @param DestPoly - the poly we're going to! * @param EdgeCost - output param with current edge cost, and should be updated cost after this function is called * @param HeuristicCost - output param with current heuristiccost, and should be updated heuristic cost (h) after this function is called * @param EdgePoint - the point on the edge being used for cost calculations ( a good place to do heuristic weighting ) * @return TRUE if this edge is fit at all, FALSE if it should be skipped */ UBOOL ApplyConstraints( FNavMeshEdgeBase* Edge, FNavMeshPolyBase* SrcPoly, FNavMeshPolyBase* DestPoly, INT& EdgeCost, INT& HeuristicCost, const FVector& EdgePoint ); /** * EvaluateGoal handles composition of goal evaluators, and will loop through the goaleval list * calling EvaluateGoal on each one to determine if the possibleGoal is the node we're looking for * @param PossibleGoal - the goal to be evaluated! * @param out_GeneratedGoal - the poly that we have chosen as our successful goal (if any) * @NOTE: this will be NULL'd if the collective goals say no to PossibleGOal * @return TRUE if PossibleGoal is a valid node to stop on (search stops once this happens) */ UBOOL EvaluateGoal( PathCardinalType PossibleGoal, PathCardinalType& out_GeneratedGoal ); void ClearCrossLevelRefs(ULevel* Level); /** * will clear all references to any navmeshes */ void ClearAllMeshRefs(); /** * PostEdgeCleanup * this function is called after an edge has been cleaned up, but before it has been deleted. Whatever triggerd * the edge deletion is finished, so it's safe to call other code that might affect the mesh * @param Edge - the edge that is being cleaned up */ void PostEdgeCleanup(FNavMeshEdgeBase* Edge); // UObject Interface - overidden to clear pathcache on destruction virtual void BeginDestroy(); /** * will operate on the pathcache to generate a set of points to run through.. this is based on the edges in the path * and a 'stringpull' method applied to the edges to find the best route through the edges * @param Interface - the interface of the entity we're computing for * @param PathIdx - the index of the edge we are computing * @param out_EdgePos - the output of the computation * @param ArrivalDist - the radius around points which the entity will consider itself arrived (used to offset points to make sure the bot moves far enough forward) * @param bConstrainedToCurrentEdge - skip compensating if the edge requires special movement, rely solely upon GetEdgeDestination() * @param out_EdgePoints - optional pointer to an array to fill with all the computed edge movement points */ void ComputeOptimalEdgePosition(INT PathIdx, FVector& out_EdgePos, FLOAT ArrivalDistance, UBOOL bConstrainedToCurrentEdge = FALSE, TArray<FVector>* out_EdgePoints=NULL); /** * This function will generate a move point which will get the bot into the next polygon * by compensating for early-arrival if needed * @param PathIdx - the index of the pathedge position we're trying to resolve (usually 0) * @param out_movePosition - the position we determined to be best to move to (should be set with the current desired location to move to) * @param NextMovePoitn - the next move point in the path * @param HandleExtent - the extent of the handle we're resolving for * @param CurHandlePos - the current world position of the handle we're resolving for * @param ArrivalDistance - how close to a point we have ot be before moveto() will return */ void CompensateForEarlyArrivals(INT PathIdx, FVector& out_MovePosition, const FVector& NextMovePoint, const FVector& CurHandlePos, FLOAT ArrivalDistance); /** * This function is called from GetNextMoveLocation when it is detected that the entity is not within its path * and it tries to recover from this happening * @param Interface - the handle interface that's walking this path * @param SearchStart - the location of the entity searching (saves on interface vf calls) * @param Extent - extent of the entity searching (saves on interface vf calls) * @param ArrivalDistance - how clsoe to a point we have to get before moveto() will return * @param out_Dest - out_param dictating what our destination should be * @return - whether we were succesful in finding a valid point to move to */ UBOOL HandleNotOnPath(FLOAT ArrivalDistance, FVector& out_Dest ); /** * This function is called to give the Handle a chance to handled the adjustment instead of the controller fallback. * @param HitNoraml - Normal of the wall at point of collision * @param HitActor - Actor that we hit * @return - TRUE if we handled the adjustment, FALSE means allow Outer (usually the AIController) */ UBOOL HandleWallAdjust( FVector HitNormal, AActor* HitActor ); /** * This function is called after an adjust to the wall is complete (usually from execPollMoveTo/ward) * @return - TRUE if we handled the adjustment and no other move should occur, FALSE means allow regular movement to continue */ UBOOL HandleFinishedAdjustMove(); /** * This function is called by APawn::ReachedDestination and is used to coordinate when to stop moving to a point during * path following (e.g. once we are inside the next poly, stop moving rather than trying to hit an exact point) * @param Destination - destination we're trying to move to * @param out_bReached - whether or not we have reached this destination * @param HandleOuterActor - the actor which implements the navhandle interface for this test * @param ArrivalTreshold - the radius within which code elsewhere is going to be doing arrival checks, so we can match in this function without breaking parity * @return - returns TRUE If this function was able to determien if we've arrived (FALSE means keep checking elsewhere) */ UBOOL ReachedDestination(const FVector& Destination, AActor* HandleOuterActor, FLOAT ArrivalThreshold, UBOOL& out_bReached); // don't let navmeshes whose edges we are reffing be deleted before we are void AddReferencedObjects( TArray<UObject*>& ObjectArray ); void Serialize( FArchive& Ar ); /** * do an octree check and return all pylons whose bounds overlap the passed center/extent * @param Ctr - center of box to check for overlap * @param Extent - extent of box to check for overlap * @param out_OverlappingPylons - out param stuffed with pylons */ static void GetAllOverlappingPylonsFromBox(const FVector& Ctr, const FVector& Extent, TArray<APylon*>& out_OverlappingPylons); /** * called from PointReachable, and is recursive to split the cast into several that conform to the mesh * @param InOuter - The Outer which owns this NavHandle. Can be used for debugging * @param Hit - Hitresult struct for line check * @param Start - start of line check * @param End - end of line check * @param Extent - extent of box to sweep * @param bIgnoreNormalMesh - OPTIONAL - default:FALSE - when TRUE no checks against the walkable mesh will be performed * @param out_HitPoly - optional output param stuffed with the poly we collided with (if any) * @param bComparePolyNormalZs - optional bool dictating whether this function should return a collision when any two polys found along * the way have very different Normal.Z values * @param TraceFlags - bitfield to control tracing options * @return TRUE of nothing hit */ static UBOOL PointReachableLineCheck( const UObject* const InOuter, FCheckResult& Hit, FVector Start, FVector End, FVector Extent, UBOOL bIgnoreNormalMesh=FALSE, FNavMeshPolyBase** out_HitPoly=NULL, UBOOL bComparePolyNormalZs=FALSE, DWORD TraceFlags=0); /** * called when a path is searched for and not found * sets the lastpatherror and saves off the time of the failure * @param ErrorType - the type of path error that just occurred */ void SetPathError(EPathFindingError ErrorType); // typedef for getvalidpositionsforbox acceptability function pointer typedef UBOOL (*ValidBoxPositionFunc)(UNavigationHandle* AskingHandle, const FVector& Point, FNavMeshPolyBase* PolyContainingPoint); /** * will return a list of valid spots on the mesh which fit the passed extent and are within radius to Pos * @param Pos - Center of bounds to check for polys * @param Radius - radius from Pos to find valid positions within * @param Extent - Extent of entity we're finding a spot for * @param bMustBeReachableFromStartPos - if TRUE, only positions which are directly reachable from the starting position will be returned * @param ValidPositions - out var of valid positions for the passed entity size * @param MaxPositions - the maximum positions needed (e.g. the search for valid positions will stop after this many have been found) * @param MinRadius - minimum distance from center position to potential spots (default 0) * @param ValidBoxAroundStartPos - when bMustBeReachableFromStartPos is TRUE, all hits that are within this AABB of the start pos will be considered valid * @param ValidBoxPositionFunc - function pointer which can be supplied to filter out potential points from the result list */ void GetValidPositionsForBoxEx(FVector pos, FLOAT Radius, FVector Extent, UBOOL bMustBeReachableFromStartPos, TArray<FVector>& out_ValidPositions, INT MaxPositions=-1, FLOAT MinRadius=0, FVector ValidBoxAroundStartPos=FVector(0.000000,0.000000,0.000000), ValidBoxPositionFunc FitnessFunction=NULL); // macros to support debuglog, should call these instead of debuglog directly so that it gets compiled out in release builds #if !DO_AI_LOGGING #define NAVHANDLE_DEBUG_LOG(TXT){} #else #define NAVHANDLE_DEBUG_LOG(TXT){\ if(RUNTIME_DO_AI_LOGGING)\ {\ IInterface_NavigationHandle* Interface = InterfaceCast<IInterface_NavigationHandle>(GetOuter());\ if(Interface != NULL)\ {\ Interface->DebugLogInternal(TXT);\ }\ }\ } #endif }; /** * Path constraint operations * Allows the user to push a list of constraints which affect pathing heuristics, as well as determine when the path traversal is finished */ native function ClearConstraints(); native function AddPathConstraint( NavMeshPathConstraint Constraint ); native function AddGoalEvaluator( NavMeshPathGoalEvaluator Evaluator ); /** * Path shaping creation functions... * these functions by default will just new the class, but this offers a handy * interface to override for to do things like pool the constraints */ function NavMeshPathConstraint CreatePathConstraint( class<NavMeshPathConstraint> ConstraintClass ) { return WorldInfo.GetNavMeshPathConstraintFromCache(ConstraintClass,self); } function NavMeshPathGoalEvaluator CreatePathGoalEvaluator( class<NavMeshPathGoalEvaluator> GoalEvalClass ) { return WorldInfo.GetNavMeshPathGoalEvaluatorFromCache(GoalEvalClass,self); } function int GetPathCacheLength() { return PathCache.EdgeList.Length; } /** Path Cache Operations * Allows operations on nodes in the route while modifying route (ie before emptying the cache) * Should override in subclasses as needed */ native function bool PathCache_Empty(); /** * After FindPath has been called this will return the location in the world that the pathfind found based on the NavMeshGoals * the FindPath used. **/ native function vector PathCache_GetGoalPoint(); native function bool PathCache_RemoveIndex(int InIdx, int Count = 1); /** * This will return the best "unfinished path". We need this for things where we are using the navmesh to find locations which * are not connected (pathable) to the originating NavHandle but are still valid world positions. **/ native function vector GetBestUnfinishedPathPoint() const; // finds the the pylon the AI attached to this handle is within native function bool FindPylon(); // finds the pylon (if any) assoicated with the position passed native static function Pylon GetPylonFromPos( vector Position ); /** * will return the actual point that we should move to right now to walk along our path * this will usually be a point along our current edge, but sometimes will * be something else in special situations (e.g. right on top of the edge) * @param out_MoveDest - output movement destination we have determined * @param ArrivalDistance - this tells getnextmovelocation how close to a point we have to be before MoveTo() returns * necessary so we can compesnate for early arrivals in some situations */ native function bool GetNextMoveLocation( out Vector out_MoveDest, float ArrivalDistance ); /** * lets the navigation handle know what the ultimate goal of the current move is * @param FinalDest - the destination desired * @return - whether or not the final destination is reachable */ native function bool SetFinalDestination(Vector FinalDest); /** * ComputeValidFinalDestination * will find a valid, pathable point near the passed desired destination */ native function bool ComputeValidFinalDestination(out vector out_ComputedPosition); /** * this will set up a path search, and ultimately call GeneratePath to do the A* path search * Note: it's up to your constraints to determine what it is you're doing.. if you're trying to * path to a particular point you probably want to add a NavmeshGoal_At goal evaluator * and supply it with the position you're pathing toward so the goal evaluator can stop the path search * once the destination is found. You also need a path constraint to provide a heuristic for the search, * which typically is going to consist of at least a NavMeshPath_Toward which will weight based on * euclidian distance to the goal. * @param out_DestActor - output variable which goal evaluators can use to supply the 'found' actor at path finish * @param out_DestItem - output variable which goal evaluators can use to supply extra data to path search clients * @return - whether the path search was successful or not */ native function bool FindPath( optional out Actor out_DestActor, optional out int out_DestItem ); /** * this will notify our curretn edge we're about to traverse it, and allow that edge to perform custom actions for traversal * @param MovePt - the point we're about to move to * @param C - controller we're suggesting move prep for * @return TRUE if the edge is handling getting the bot to the proper position for the move, FALSE if * calling code is responsible for getting th bot to movept */ native function bool SuggestMovePreparation( out Vector MovePt, Controller C ); /** * does a line check against the obstacle mesh * @param Start - start of the line segment to check * @param End - end position of the line segment to check * @param Extent - extent of box to be swept along line segment * @param out_HitLoc - hit location of obstacle line check (if any) * @param out_hitNorm - hit normal of surface we hit during obstacle line check (if any) * @return - TRUE if nothing was hit (note: only collides against the obstacle mesh, not the normal mesh) */ static native final function bool ObstacleLineCheck( vector Start, vector End, vector Extent, optional out vector out_HitLoc, optional out vector out_HitNorm ); /** * Does a point check against the obstacle mesh * @param Pt - centroid of box to check aginast obstacle mesh * @param Extent - Extent of box to check against obstacl mesh * @return - TRUE if didn't hit anything */ static native final function bool ObstaclePointCheck(vector Pt, vector Extent); /** * does a line check against the Walkable mesh * @param Start - start of the line segment to check * @param End - end position of the line segment to check * @param Extent - extent of box to be swept along line segment * @return - TRUE if nothing was hit */ native function bool LineCheck( vector Start, vector End, vector Extent, optional out vector out_HitLocation, optional out vector out_HitNormal ); /** * Does a point check against the Walkable mesh * @param Pt - centroid of box to check against obstacle mesh * @param Extent - Extent of box to check against obstacle mesh * @return - TRUE if didn't hit anything */ native function bool PointCheck( vector Pt, vector Extent ); /** * returns TRUE if Point/Actor is directly reachable * @param Point - point we want to test to * @param OverrideStartPoint (optional) - optional override for starting position of AI (default uses bot location) * @param bAllowHitsInEndCollisionBox (optional) - optional.. (defaults to ON) if this is true and a hit is detected that falls within the collision cylinder of the entity, let the hit pass * @return TRUE if the point is reachable */ native function bool PointReachable( Vector Point, optional Vector OverrideStartPoint, optional bool bAllowHitsInEndCollisionBox=true); native function bool ActorReachable( Actor A ); // debug function for drawing cache polys native function DrawPathCache(optional Vector DrawOffset, optional bool bPersistent, optional color DrawColor); // debug function which prints out info about the current path cache native function String GetPathCacheDebugText(); /** * for debugging.. will return descriptive text about the current edge */ native function string GetCurrentEdgeDebugText(); /** * NULLs the currentedge reference */ native function ClearCurrentEdge(); /** * @returns the edge type for the current edge (if any) */ native function ENavMeshEdgeType GetCurrentEdgeType(); /** * returns the center points of all polys within the specefied area * @param Pos - Center of bounds to check for polys * @param Extent - Extent of area to return * @param out_PolyCtrs - out var of poly centers within the specefied area */ native static function GetAllPolyCentersWithinBounds(Vector Pos, Vector Extent, out Array<Vector> out_PolyCtrs); /** * will return a list of valid spots on the mesh which fit the passed extent and are within radius to Pos * @param Pos - Center of bounds to check for polys * @param Radius - radius from Pos to find valid positions within * @param Extent - Extent of entity we're finding a spot for * @param bMustBeReachableFromStartPos - if TRUE, only positions which are directly reachable from the starting position will be returned * @param ValidPositions - out var of valid positions for the passed entity size * @param MaxPositions - the maximum positions needed (e.g. the search for valid positions will stop after this many have been found) * @param MinRadius - minimum distance from center position to potential spots (default 0) * @param ValidBoxAroundStartPos - when bMustBeReachableFromStartPos is TRUE, all hits that are within this AABB of the start pos will be considered valid */ native static function GetValidPositionsForBox(Vector Pos, float Radius, Vector Extent, bool bMustBeReachableFromStartPos, out Array<Vector> out_ValidPositions, optional int MaxPositions=-1, optional float MinRadius, optional vector ValidBoxAroundStartPos=vect(0,0,0)); /** * will clip off edges from the pathcache which are greater than the specified distance from the start of the path * @param MaxDist - the maximum distance for the path */ native function LimitPathCacheDistance(float MaxDist); /** * this function will determine if the poly this entity is currently in is inescapable by that entity * @return TRUE If the poly this handle is in isn't escapable */ native function bool IsAnchorInescapable(); /** * this will a good point on the first edge in the pathcache (or the finaldest if there is no pathcache) */ native function vector GetFirstMoveLocation(); /** * this will calculate the optimal edge positions along the pathcache, and add up the distances * to generate an accurate distance that will be travelled along the current path * Note: includes distance to final destination * @param FinalDest - optional finaldest override (if not passed will use NavigationHandle.FinalDestination) * @return - the path distance calculated */ native function float CalculatePathDistance(optional Vector FinalDest); /** * this will take the given position and attempt to move it the passed height above the poly that point is in (along a cardinal axis) * @param Point - point to adjust * @param Height - height above mesh you would like * @return Adjusted point */ static native function Vector MoveToDesiredHeightAboveMesh(vector Point, float Height); /** * This will attempt to grab an interface_navigationhandle from outer, and have that interface populate * our cached pathing params. * @return TRUE if cache population was succesful */ native final function bool PopulatePathfindingParamCache(); /** * Gather all cover slot info within radius of the given point * @param FromLoc - location at center of sphere to check * @param Radius - radius of sphere within which to gather cover * @param out_CoverList - out array filled with cover infos within radius * @return TRUE if found any cover */ static native final function bool GetAllCoverSlotsInRadius( Vector FromLoc, FLOAT Radius, out array<CoverInfo> out_CoverList ); /** * will get a point nearby which is in a poly that has edges outbound that support this AI * @param out_NewAnchorLoc - * @param OverrideStartLoc - optional param to override the starting location for this query (if none is given this AI's searchstart will be used) */ native final function bool GetValidatedAnchorPosition(out vector out_NewAnchorLoc, optional vector OverrideStartLoc ); defaultproperties { bDebugConstraintsAndGoalEvals=FALSE } |
Overview | Package | Class | Source | Class tree | Glossary | UnrealScript Documentation |
previous class next class | frames no frames |