We need to teleport the character to the sky, if somehow the player entered a place no way out. Such as inside of a geometry, rooftop, or a big box / postbox.
I’ve tried cast many scene queries around different directions of player, like 32 sphere sweep on a sphere distribution. The problem is that some static mesh must enable “Double Sided Geometry” to be able to be traced from inside. Which means we have to enumerate all the mesh who has “closed area” if no to enable it for all meshes (which could impact physics memory consumption or performance?).
And tried use navi mesh path finding to help it, but only one type of navi mesh could exist in a game? The navi mesh data we use can’t meet the need for this. For example, it won’t have a navi-link from the postbox to the ground, because the AI character won’t allowed to be there. We want to generate some data only for the “escapee from jail” purpose, but don’t know how.
Any good ideas to solve this? [Image Removed]
[Image Removed]
[Attachment Removed]
Hi, can I check you have tried to do this by calling the UMovementComponent::SafeMoveUpdatedComponent, which is the standard way of solving this issue when moving a character?
Best
Geoff Stacey
Developer Relations
EPIC Games
[Attachment Removed]
Not a problem.
This may be either a setup issue or an asset one. Are you able to send across a minimal repro using a vanilla version of Unreal engine, and we can let you know the process to unblock?
Best
Geoff
[Attachment Removed]
Thank you for the repro project.
Can I check the criteria for the scenario you are looking at please? Are you interested in being able to detect if a character has been teleported _within_ an object so that they can then be moved out of that shape?
[Attachment Removed]
> Are you interested in being able to detect if a character has been teleported _within_ an object so that they can then be moved out of that shape?
Yes, but might not be teleported. Player might dropped into the shape by itself because of the collision was not finishing loading.
I want a reliable way to detect if the player is within a shape / space (a closed area) so that I could teleport them to some open space.
(In fact, that space doesn’t have to completely closed. If the holes or passages on them is too small for the minimum capsule of player to pass, I also want to teleport it out. I thought this could be detected with lots of sweeps.)
[Attachment Removed]
The issue won’t happen on geometries with simple collision, player can’t get into them.
[Attachment Removed]
You’ve pre-empted my question
- essentially that simple collisions have a ‘volume’ which means they can detect encompassing collisions.
Are these levels generated at runtime? Some of this could be curated by a Art/TechArt as opposed to trying to capture the generic case, which when adding in the concept of small areas could get pretty complex and still get an incorrect result.
I’m curious about the issue of loading - is this something you’ve encountered? That could be solved by increasing the loading distance if you are using a streaming system.
[Attachment Removed]
I’d be tempted to use collision volumes to create areas which aren’t valid to be spawned into in that case. This could be partially automated per asset (ie placing the asset will also place an exclusion volume), and use a collision channel to detect these cases when teleporting and maybe a timed trigger to check for the delayed spawning on the low end HDD cases?
You could use raycasting/shapecasting as you suggest, but I’d be concerned it would miss cases
Best
Geoff
[Attachment Removed]
Hi Sun,
I’d suggest using a system similar to the one in my response of Jan 6 - essentially have exclusion areas either built into the level, or perhaps easier linked to the placing of the assets themselves. Since this isn’t runtime generated you will be able to know if the player can get through the spaces at creation time and use that knowledge to create the answer (ie is it an exclusion zone or not). Trying to figure out sized based exclusion may not be very reliable which is why I’d suggest this is not done at runtime. (ie it depends on what angle the object is hit at in many cases)
Best
Geoff
[Attachment Removed]
No without risking creating more issues. A yes/no isn’t too difficult, but the idea of a sized based determination and the possible issues with the general case of this would only be worth it if there wasn’t a fairly simple alternate answer.
Could you show me an example of what you mean about chipped geometry please?
Double sided geometry just means that we detect collisions from both directions - in a sense for what you need, implicit (simple) geometry is better since there is a concept of in/out. The complex collision is a tri mesh, which means that any queries actually need to intersect some of the geometry in order to register a hit (ie something purely inside won’t actually trigger a collision) - scene queries as standard will use complex collision as well.
Best
Geoff
[Attachment Removed]
> Could you show me an example of what you mean about chipped geometry please?
Yes, by “chipped” I mean those holes/blank space in the collision:
[Image Removed]
while from outside, it’s intact:
[Image Removed]
[Attachment Removed]
Thanks Sun, I’m following now. It’s something on the render side with how the asset has been created. I’d suspect some of this is a full 3D shape like the lid which shows the lip from the outside, while in other cases (ie the ‘fins’ on the side it is not being backface culled because it isn’t the right angle). The sides are likely just planes so they do get culled. I wouldn’t say there is anything concerning with any of what I can see.
Best
Geoff
[Attachment Removed]
{
AActor* Actor = GetAvatarActorFromActorInfo();
UWorld* World = GetWorld();
const FVector ActorLocation = Actor->GetActorLocation();
const FVector ActorUpLocation = ActorLocation + FVector{0.0f, 0.0f, ZOffset};
const FVector ActorDownLocation = ActorLocation + FVector{0.0f, 0.0f, -ZOffset};
bool bAllBlocked = true;
// disable owner actor collision
const auto bCollisionEnabled = Actor->GetActorEnableCollision();
Actor->SetActorEnableCollision(false);
FActorSpawnParameters SpawnParams;
SpawnParams.Owner = Actor->GetOwner();
SpawnParams.Instigator = Actor->GetInstigator();
SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
auto* TracePawn = Cast<ACharacter>(World->SpawnActor(TraceCharacterClass, &Actor->GetActorTransform(), SpawnParams));
ON_SCOPE_EXIT
{
if (ensure(TracePawn))
{
TracePawn->Destroy();
}
if (ensure(Actor))
{
Actor->SetActorEnableCollision(bCollisionEnabled);
}
};
if (TracePawn && TracePawn->GetCharacterMovement())
{
// generate sphere dsitribution of delta move
TArray<FVector> SpherePoints = GenerateSpherePoints( NumberOfLineTraceForSphere, LineTraceLengthForSphere);
// try start moving from actor position with offset up and down
for (auto& Point : {ActorLocation, ActorUpLocation, ActorDownLocation})
{
for (auto& Delta : SpherePoints)
{
// reset TracePawn to start point
TracePawn->SetActorLocation(Point);
FHitResult OutHit;
// try move TracePawn
TracePawn->GetCharacterMovement()->SafeMoveUpdatedComponent(Delta, TracePawn->GetActorQuat(), true, OutHit);
bAllBlocked &= (OutHit.bStartPenetrating || OutHit.bBlockingHit);
#if UE_ENABLE_DEBUG_DRAWING
ON_SCOPE_EXIT
{
if (CVarDrawDebugCheckClosedAreaClient.GetValueOnAnyThread())
{
::DrawDebugCapsuleTraceSingle(World, Point, TracePawn->GetActorLocation(),
TracePawn->GetCapsuleComponent()->GetScaledCapsuleRadius(), TracePawn->GetCapsuleComponent()->GetScaledCapsuleHalfHeight(), EDrawDebugTrace::ForDuration, OutHit.bBlockingHit, OutHit,
FLinearColor::Green, FLinearColor::Red, 10.0f);
}
};
#endif
if (!bAllBlocked)
{
// found none blocking hit
break;
}
}
if (!bAllBlocked)
{
// found none blocking hit
break;
}
}
}
}
code snippet I used
The result didn’t get any better:
[Image Removed]
[Attachment Removed]
Hi, Geoff
I’ve prepared a reproducible project with 5.7.1. With the static mesh and it’s collision mesh imported.
I’m calling the "UDebugtatics::DebugTest" in level blueprint to run the code above every 2 seconds.
Regards,
Sun
[Attachment Removed]
> Are these levels generated at runtime
No, it’s just a hand crafted, streamed level.
> increasing the loading distance if you are using a streaming system.
Yes, we encountered this when running our game in some low end machine with slow HDD drive. So increasing it might make it worse.
[Attachment Removed]
Hi Geoff, is there any progress about the repro project?
[Attachment Removed]
Got it, so there is no better way on the engine side.
I got a few questions left:
- Why the collision looks chipped inside, while it’s complete when outside it? (Could be traced from inside out, not the other way around)
- How the “double sided geometry” help dealing with the issue?
Thanks for your time,
Sun
[Attachment Removed]