I have AStar navigation for my main navigation. This all works well. But I need fine precision movement for the final positioning (to pickup items, to go into buildings, etc.). These work well on flat ground, but on any kind of hill, the character just stops if I use sweep in SetActorLocation(). I’ve tried using the NavMesh navigation and give it a path. It didn’t work. I looked through the code and it only updates the direction the character travels every second. Most of my fine movement doesn’t last even a second.
Short of doing a manual line trace and setting the Z myself, is there a way to use SetActorLocation() and have it stay on the ground? This is an AI NPC character.
edit: Also, is there a way to change the capsule. I have a robot with a single wheel that touches the ground. So when he goes up an incline, the robot no longer touches the ground because the capsule does touch the ground.
edit2: I looked a little closer and the character never touches the ground. It’s 2.5cm too high. There is nothing colliding with the ground. Not the mesh, not the capsule, nothing. So I really don’t understand anything about how UE does collisions.
1 Like
I ran Simulate and modified the capsule height until the character was on the ground. This seems to have fixed the character staying on the ground even on inclines. I had to go back to the original asset and modify the capsule again for it to update permanently.
But my original problem remains. How do you move a character and have it remain on the ground?
Hi there, hope you’re fine
You can use the FindFloor
function in Unreal Engine to get the surface of the floor under the character and adjust the Z position of the character accordingly.
Here’s a code example:
FVector Location = ...; // The target location you want to move the character to
float TraceDistance = 100.0f; // The distance to trace downward to find the floor
FHitResult HitResult;
if (GetWorld()->LineTraceSingleByChannel(HitResult, Location, Location - FVector(0, 0, TraceDistance), ECC_Visibility))
{
FVector AdjustedLocation = HitResult.ImpactPoint + FVector(0, 0, GetCapsuleComponent()->GetScaledCapsuleHalfHeight());
SetActorLocation(AdjustedLocation, true, &HitResult);
}
1 Like
I already know how to do a line trace to find the floor. I was just wondering if there was an easier way. Also, as I just explained, the capsule half height is not the half height to the ground. I have a 2.5 cm difference between the capsule half height and the actual ground.
Seems like doing line traces on every tick for hundreds of characters would be a bit slow.
I tried the FindFloor method. It’s 2.5cm off. Likely because my capsule is placed 2.5cm off the ground. If I put the capsule at the correct height, FindFloor works correctly, but regular navigation puts the character 2.5cm above the ground.
I don’t understand why there’s a 2.5cm offset during regular navigation.
I had to leave the half height 2.5cm shorter than it should be. So the capsule doesn’t touch the ground, but the mesh does. It’s the only way I could get the character to actually stay on the ground. In my code to to the finer movements, I had to add an offset of 2.5cm to the floor distance to make up the difference. I hate doing hacks like this.
1 Like
I’m sorry about that, it’s really sad when we have to do this kind of hack.
In Brazil we have a word to this, it’s called Gambiarra hahaha