Capsule trace returned impact point with random height on flat vertical surface

I’m trying to make my own custom pawn movement component and I’m trying to make a step up functionality for it. But for some reason, when I’m using the SafeMoveUpdatedComponent, it ocassionally returns a random height for the impact point.

I know I can make multiple line tracing to get an accurate height of the floor but I would like it if there is another way that is more efficient or if someone can point out if something is wrong with my code.

void UHunter_MovementComponent::TickGroundMovement(float deltaTime, FVector inputVector, enum ELevelTick tickType, FActorComponentTickFunction* tickFunction)
{

	currentFloor.Clear(); // clear floor information

	FVector frameVelocity = Velocity;
	frameVelocity.Z = 0.0f;
	float frameSpeed = frameVelocity.Size();

	frameSpeed += !inputVector.IsNearlyZero() ? inputVector.Size() * baseWalkAcceleration * deltaTime : -1 * baseWalkAcceleration * deltaTime;

	frameSpeed = FMath::Clamp(frameSpeed, 0.0f, maxWalkVelocity);


	if (FindFloor(currentFloor, GetComponentWorldSpaceTransform(UpdatedComponent).GetTranslation(), maxStepHeight) && !frameVelocity.IsNearlyZero())
	{
		frameVelocity = CalculateFloorSlidingVector(currentFloor.hitResult.ImpactNormal, inputVector) * frameSpeed * deltaTime;

		FHitResult hit;
		SafeMoveUpdatedComponent(frameVelocity, UpdatedComponent->GetComponentQuat(), true, hit);

		if (hit.IsValidBlockingHit())
		{
			FHitResult temp;
			TraceLineSingleByProfile(hit.ImpactPoint, hit.ImpactPoint + (hit.ImpactNormal * 100.0f), temp, TEXT("Pawn"), TArray<AActor*>(), EDrawDebugTrace::ForDuration);

			SlideAlongSurface(frameVelocity, 1.0f - hit.Time, hit.Normal, hit);
		}
	}

	
	Velocity = inputVector * frameSpeed;
}

I have a TraceLineSingleByProfile() function which basically calls UKismetSystemLibrary::LineTraceSingleByProfile() to draw a line from the hit.ImpactPoint outwards from hit.ImpactNormal and the result is shown below.

289760-collision.png

289761-collision-2.png

Hi @ShienXIII, I don’t see anything inherently wrong with your code. Unfortunately, the behavior you are seeing makes absolute sense from the standpoint of collision detection.

It looks like (from the images) the collision capsule is exactly parallel to the wall. When this occurs, there are “technically” an infinite number of impact points between the surface of the wall face and the collision cylinder.

If you are to consider laying a pencil flat on your desk, there is one edge that contacts the surface all the way along the pencil. In these situations you have an edge to face collision. So all of the traces are valid impact points along the contacting edge.

If you are to move the verts on the bottom of the wall slightly in (such that the top corner of the wall protrudes) I would expect the resulting impact points to be more consistent.

I know this doesn’t necessarily resolve your problem, but hopefully it helps in some way.