void UCrowdFollowingComponent::DescribeSelfToVisLog(FVisualLogEntry* Snapshot) const { if (!bEnableCrowdSimulation) { Super::DescribeSelfToVisLog(Snapshot); return; } FVisualLogStatusCategory Category; Category.Category = TEXT("Path following"); if (DestinationActor.IsValid()) { Category.Add(TEXT("Goal"), GetNameSafe(DestinationActor.Get())); } FString StatusDesc = GetStatusDesc(); FNavMeshPath* NavMeshPath = Path.IsValid() ? Path->CastPath<FNavMeshPath>() : NULL; FAbstractNavigationPath* DirectPath = Path.IsValid() ? Path->CastPath<FAbstractNavigationPath>() : NULL; if (Status == EPathFollowingStatus::Moving) { StatusDesc += FString::Printf(TEXT(" [path:%d, visited:%d]"), PathStartIndex, LastPathPolyIndex); } Category.Add(TEXT("Status"), StatusDesc); Category.Add(TEXT("Path"), !Path.IsValid() ? TEXT("none") : NavMeshPath ? TEXT("navmesh") : DirectPath ? TEXT("direct") : TEXT("unknown")); UObject* CustomLinkOb = GetCurrentCustomLinkOb(); if (CustomLinkOb) { Category.Add(TEXT("SmartLink"), CustomLinkOb->GetName()); } UCrowdManager* Manager = UCrowdManager::GetCurrent(GetWorld()); if (Manager && !Manager->IsAgentValid(this)) { Category.Add(TEXT("Simulation"), TEXT("unable to register!")); } Snapshot->Status.Add(Category); }
void UCrowdFollowingComponent::GetDebugStringTokens(TArray<FString>& Tokens, TArray<EPathFollowingDebugTokens::Type>& Flags) const { if (!bEnableCrowdSimulation) { Super::GetDebugStringTokens(Tokens, Flags); return; } Tokens.Add(GetStatusDesc()); Flags.Add(EPathFollowingDebugTokens::Description); UCrowdManager* Manager = UCrowdManager::GetCurrent(GetWorld()); if (Manager && !Manager->IsAgentValid(this)) { Tokens.Add(TEXT("simulation")); Flags.Add(EPathFollowingDebugTokens::ParamName); Tokens.Add(TEXT("NOT ACTIVE")); Flags.Add(EPathFollowingDebugTokens::FailedValue); } if (Status != EPathFollowingStatus::Moving) { return; } FString& StatusDesc = Tokens[0]; if (Path.IsValid()) { FNavMeshPath* NavMeshPath = Path->CastPath<FNavMeshPath>(); if (NavMeshPath) { StatusDesc += FString::Printf(TEXT(" (path:%d, visited:%d)"), PathStartIndex, LastPathPolyIndex); } else if (Path->CastPath<FAbstractNavigationPath>()) { StatusDesc += TEXT(" (direct)"); } else { StatusDesc += TEXT(" (unknown path)"); } } // get cylinder of moving agent float AgentRadius = 0.0f; float AgentHalfHeight = 0.0f; AActor* MovingAgent = MovementComp->GetOwner(); MovingAgent->GetSimpleCollisionCylinder(AgentRadius, AgentHalfHeight); if (bFinalPathPart) { float CurrentDot = 0.0f, CurrentDistance = 0.0f, CurrentHeight = 0.0f; uint8 bFailedDot = 0, bFailedDistance = 0, bFailedHeight = 0; DebugReachTest(CurrentDot, CurrentDistance, CurrentHeight, bFailedHeight, bFailedDistance, bFailedHeight); Tokens.Add(TEXT("dist2D")); Flags.Add(EPathFollowingDebugTokens::ParamName); Tokens.Add(FString::Printf(TEXT("%.0f"), CurrentDistance)); Flags.Add(bFailedDistance ? EPathFollowingDebugTokens::FailedValue : EPathFollowingDebugTokens::PassedValue); Tokens.Add(TEXT("distZ")); Flags.Add(EPathFollowingDebugTokens::ParamName); Tokens.Add(FString::Printf(TEXT("%.0f"), CurrentHeight)); Flags.Add(bFailedHeight ? EPathFollowingDebugTokens::FailedValue : EPathFollowingDebugTokens::PassedValue); } else { const FVector CurrentLocation = MovementComp->GetActorFeetLocation(); // make sure we're not too close to end of path part (poly count can always fail when AI goes off path) const float DistSq = (GetCurrentTargetLocation() - CurrentLocation).SizeSquared(); const float PathSwitchThresSq = FMath::Square(AgentRadius * 5.0f); Tokens.Add(TEXT("distance")); Flags.Add(EPathFollowingDebugTokens::ParamName); Tokens.Add(FString::Printf(TEXT("%.0f"), FMath::Sqrt(DistSq))); Flags.Add((DistSq < PathSwitchThresSq) ? EPathFollowingDebugTokens::PassedValue : EPathFollowingDebugTokens::FailedValue); } }