Download

How can I calculate a rejection force / velocity from 'SafeMoveUpdatedComponent()'

I’ve created a modified movement component based heavily on Character Movement, and it’s aim is to simulate physics without actually using the PhysX engine. I have four variables that contribute to movement.



Accel      - Linear World-Space Acceleration
Alpha      - Angular World-Space Acceleration
Velocity   - Linear Velocity (var comes from UMovementComponent)
Omega    - Angular Velocity


Now the problem with CharacterMovementComponent is it just calculates a collision rejection ‘Position’, it doesn’t actually apply any velocity, or angular velocity to the character. In my case I need to change this to get a kind of ‘bounce’ off of a surface during movement.

To make it slightly more complicated, I’m using a SkeletalMesh component with a single Convex Hull as the collision primitive. Accel and Alpha are calculated, then added to Velocity. Velocity is then applied like this:



		const FVector Delta = Velocity * DeltaSeconds;
		const FVector ScaledOmega = Omega * DeltaSeconds;
		const FQuat OmegaQuat = FQuat(FVector::ForwardVector, ScaledOmega.X) * FQuat(FVector::RightVector, ScaledOmega.Y) * FQuat(FVector::UpVector, ScaledOmega.Z);

		const FQuat FinalRotation = OmegaQuat * UpdatedComponent->GetComponentQuat();
		FHitResult MoveHit = FHitResult(1.f);

		SafelyMove(DeltaSeconds, Delta, FinalRotation, true, MoveHit);


‘SafelyMove’ is basically a copy of ‘SafeMoveUpdatedComponent’ so that i can change the behaviour. Unfortunately the movement doesn’t seem to return the impact normal the same way a physics collision does, so I can’t actually calculate a reflection vector to modify velocity.



	bool bMoveResult = MoveUpdatedComponent(Delta, NewRotation, bSweep, &OutHit, Teleport);

	// Resolve with Velocity
	if (OutHit.bStartPenetrating && UpdatedComponent)
	{
		// Calculate Reflection Vector
		const FVector Reflection = Velocity - 2.f * OutHit.Normal * (FVector::DotProduct(Velocity, OutHit.Normal));
		const FVector NewDelta = (Velocity + Reflection) * DeltaSeconds;

		GEngine->AddOnScreenDebugMessage(-1, DeltaSeconds, FColor::Red, Reflection.ToString());

		// Try Move
		bMoveResult = MoveUpdatedComponent(NewDelta, NewRotation, bSweep, &OutHit, Teleport);
	}


I’ve been back and forth with this component. If I simulate physics I get nice collision rejection and handling, but then I struggle to get the syncronisation to work over the network.

So… any ideas?