Hello, I’ve been playing with the top-down template and have been trying to make the character more reactive to nearby clicks, I tried to work through a couple solutions, such as messing with the movement component, and the navmesh setting, however, from what I’ve tried the problem is that the LineTrace is hitting the character’s Root Capsule Component and when that happens the character ignores the move request because it’s on him. You can fix this by reducing the size of the capsule and you will see that suddenly the character responds much more readily to the clicks near where he is located.
However, I would like to avoid messing with the capsule component because then his hit-box (capsule?), won’t be properly adjusted to the character’s mesh. So I walked through the source code and found in the PlayerController.cpp that the Top-Down Template player controller is using the function GetWorld()->LiveTraceSingle(*) this function provides the ability to specify a FCollisionQueryParams object and this object provides the ability to ignore a specific actor in its LineTrace, so I added the pawn as the ignore actor in the constructor of the FCollisionQueryParams and I thought that would solve the problem however, the character still won’t respond to nearby movement requests, as if the ignore pawn section isn’t including the root component as something to ignore.
Here is the line I modified in the code in each of the overloads of GetHitResultAtScreenPosition, which is called by the TopDownCharacterController:
return GetWorld()->LineTraceSingle(HitResult, WorldOrigin, WorldOrigin + WorldDirection * 100000.f, ECC_Visibility, FCollisionQueryParams("ClickableTrace", bTraceComplex, GetPawn()));
And here are the three GetHitResultAtScreenPosition sections of code that I modified in the PlayerController.cpp file, hoping they would allow me to request that the linetrace ignore the player’s selected pawn:
bool APlayerController::GetHitResultAtScreenPosition(const FVector2D ScreenPosition, const ECollisionChannel TraceChannel, bool bTraceComplex, FHitResult& HitResult) const
{
// Early out if we clicked on a HUD hitbox
if( GetHUD() != NULL && GetHUD()->GetHitBoxAtCoordinates(ScreenPosition, true) )
{
return false;
}
ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player);
if (LocalPlayer != NULL && LocalPlayer->ViewportClient != NULL && LocalPlayer->ViewportClient->Viewport != NULL)
{
// Create a view family for the game viewport
FSceneViewFamilyContext ViewFamily( FSceneViewFamily::ConstructionValues(
LocalPlayer->ViewportClient->Viewport,
GetWorld()->Scene,
LocalPlayer->ViewportClient->EngineShowFlags )
.SetRealtimeUpdate(true) );
// Calculate a view where the player is to update the streaming from the players start location
FVector ViewLocation;
FRotator ViewRotation;
FSceneView* SceneView = LocalPlayer->CalcSceneView( &ViewFamily, /*out*/ ViewLocation, /*out*/ ViewRotation, LocalPlayer->ViewportClient->Viewport );
if (SceneView)
{
FVector WorldOrigin;
FVector WorldDirection;
SceneView->DeprojectFVector2D(ScreenPosition, WorldOrigin, WorldDirection);
return GetWorld()->LineTraceSingle(HitResult, WorldOrigin, WorldOrigin + WorldDirection * 100000.f, TraceChannel, FCollisionQueryParams ("ClickableTrace", bTraceComplex, GetPawn()));
}
}
return false;
}
bool APlayerController::GetHitResultAtScreenPosition(const FVector2D ScreenPosition, const ETraceTypeQuery TraceChannel, bool bTraceComplex, FHitResult& HitResult) const
{
// Early out if we clicked on a HUD hitbox
if (GetHUD() != NULL && GetHUD()->GetHitBoxAtCoordinates(ScreenPosition, true))
{
return false;
}
ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player);
if (LocalPlayer != NULL && LocalPlayer->ViewportClient != NULL && LocalPlayer->ViewportClient->Viewport != NULL)
{
// Create a view family for the game viewport
FSceneViewFamilyContext ViewFamily( FSceneViewFamily::ConstructionValues(
LocalPlayer->ViewportClient->Viewport,
GetWorld()->Scene,
LocalPlayer->ViewportClient->EngineShowFlags )
.SetRealtimeUpdate(true) );
// Calculate a view where the player is to update the streaming from the players start location
FVector ViewLocation;
FRotator ViewRotation;
FSceneView* SceneView = LocalPlayer->CalcSceneView( &ViewFamily, /*out*/ ViewLocation, /*out*/ ViewRotation, LocalPlayer->ViewportClient->Viewport );
if (SceneView)
{
FVector WorldOrigin;
FVector WorldDirection;
SceneView->DeprojectFVector2D(ScreenPosition, WorldOrigin, WorldDirection);
return GetWorld()->LineTraceSingle(HitResult, WorldOrigin, WorldOrigin + WorldDirection * 100000.f, UEngineTypes::ConvertToCollisionChannel(TraceChannel), FCollisionQueryParams("ClickableTrace", bTraceComplex, GetPawn()));
}
}
return false;
}
bool APlayerController::GetHitResultAtScreenPosition(const FVector2D ScreenPosition, const TArray<TEnumAsByte<EObjectTypeQuery> > & ObjectTypes, bool bTraceComplex, FHitResult& HitResult) const
{
// Early out if we clicked on a HUD hitbox
if (GetHUD() != NULL && GetHUD()->GetHitBoxAtCoordinates(ScreenPosition, true))
{
return false;
}
ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player);
if (LocalPlayer != NULL && LocalPlayer->ViewportClient != NULL && LocalPlayer->ViewportClient->Viewport != NULL)
{
// Create a view family for the game viewport
FSceneViewFamilyContext ViewFamily( FSceneViewFamily::ConstructionValues(
LocalPlayer->ViewportClient->Viewport,
GetWorld()->Scene,
LocalPlayer->ViewportClient->EngineShowFlags )
.SetRealtimeUpdate(true) );
// Calculate a view where the player is to update the streaming from the players start location
FVector ViewLocation;
FRotator ViewRotation;
FSceneView* SceneView = LocalPlayer->CalcSceneView( &ViewFamily, /*out*/ ViewLocation, /*out*/ ViewRotation, LocalPlayer->ViewportClient->Viewport );
if (SceneView)
{
FVector WorldOrigin;
FVector WorldDirection;
SceneView->DeprojectFVector2D(ScreenPosition, WorldOrigin, WorldDirection);
/*FCollisionObjectQueryParams ObjParam(ObjectTypes);*/
/*FCollisionObjectQueryParams ObjParam();*/
/*return GetWorld()->LineTraceSingle(HitResult, WorldOrigin, WorldOrigin + WorldDirection * 100000.f, FCollisionQueryParams("ClickableTrace", bTraceComplex, GetPawn()), ObjParam);*/
return GetWorld()->LineTraceSingle(HitResult, WorldOrigin, WorldOrigin + WorldDirection * 100000.f, ECC_Visibility, FCollisionQueryParams("ClickableTrace", bTraceComplex, GetPawn()));
}
}
return false;
}