Download

Creating a game with a point gravity in a planet

We’re trying to make a character walk around a spherical planet. We disabled the world gravity and are attracting the Character in it’s Tick function. The attract function adds a force to the character toward the planet’s center and also orients him according to his position on the planet. We’re facing a weird issue when the character reaches the planet’s equator. The FindBetween function keeps returning rotation values and the character’s forward vector keeps rotating along the Z axis. So if the “forward” button is held, the character keeps moving in circles.

The attract function of the PlanetGravity class is as below:

void APlanetGravity::Attract(ACharacter* characterToAttract)
{
FVector gravityUp = (this->GetActorLocation() - characterToAttract->GetActorLocation());

  //if successfully normalized, attract the body
  if (gravityUp.Normalize())
  {
        FVector bodyUp = characterToAttract->GetActorUpVector();
        characterToAttract->GetCapsuleComponent()->AddForce(gravityUp*GravityForce);

        //find how much we have to rotate the character to align it with it's position on the planet
        FQuat findBetween = FQuat::FindBetween(bodyUp, gravityUp);
        FQuat targetRotation = findBetween*characterToAttract->GetActorRotation().Quaternion();

        characterToAttract->SetActorRotation(targetRotation.Rotator());
  }

}

Can someone help?

I have also experienced the weirdness of actors’ local vectors flipping at certain angles. The code for this unit was based on using the actors orientation vectors, I tried using Cross Products to generate the vectors myself but still had issues.

Here’s the way I fixed it, I’m not sure how helpful the entire code is for you, but might give you an idea of where to start. I’m not sure if this is a bug in Unreal with the way it gets these vectors, or if it’s some fundamental math issue, either way some clarification would be spectacular…

Here’s the above in code. ‘InputStates.Normal’ is the surface normal underneath the unit.



	/* Get the Z-UnRotated Cross Product of The Actors Right Vector and the Normal */
	FVector UnrotatedRCrossN = FRotator(FRotationMatrix::MakeFromZX(InputStates.Normal, FVector::CrossProduct(UpdatedComponent->GetRightVector(), InputStates.Normal)).Rotator()).UnrotateVector(UpdatedComponent->GetRightVector());
	///* Get the Z-Orientated Rotation Of the Cross Product Of the Z-Unrotated Vector, and the Normal */
	FRotator FinalRotation = FRotationMatrix::MakeFromZX(InputStates.Normal, FVector::CrossProduct(UnrotatedRCrossN, InputStates.Normal)).Rotator();
	///* Get the Right and Front Axis Vectors of the Rotation */
	FVector Right = FRotationMatrix(FinalRotation).GetScaledAxis(EAxis::Y);
	FVector Front = FRotationMatrix(FinalRotation).GetScaledAxis(EAxis::X);




	/* Get the Z-UnRotated Cross Product of The Actors Right Vector and the Normal */
	FVector UnrotatedRCrossN = FRotator(FRotationMatrix::MakeFromZX(InputStates.Normal, FVector::CrossProduct(UpdatedComponent->GetRightVector(), InputStates.Normal)).Rotator()).UnrotateVector(UpdatedComponent->GetRightVector());
	///* Get the Z-Orientated Rotation Of the Cross Product Of the Z-Unrotated Vector, and the Normal */
	FRotator FinalRotation = FRotationMatrix::MakeFromZX(InputStates.Normal, FVector::CrossProduct(UnrotatedRCrossN, InputStates.Normal)).Rotator();
	///* Get the Right and Front Axis Vectors of the Rotation */
	FVector Right = FRotationMatrix(FinalRotation).GetScaledAxis(EAxis::Y);
	FVector Front = FRotationMatrix(FinalRotation).GetScaledAxis(EAxis::X);


[/QUOTE]

Do you then set the Right and Front vectors as the Actor’s right and front vectors?

I think what I do from there forward is DotProduct those vectors with the crafts vectors to see what the difference is between them, and apply rotation based on that. (I’ll have to double check)

FTC (Free Time Coder) implemented it in his adventure kit. His explanation is a couple of posts down.

Rama’s method in UDK

Kindly do let me know what was it you did. Im kinda lost.

Camron’s post might have a better solution. Mine was only ever designed to work on upward-facing surfaces, and I modify angular velocity directly in mine (so your actor would have to simulate physics).

I got it to work!

The issue was with the Character’s movement component. When the rotation around Y axis reached 90 or -90 the character would go into the fall state and the rotation would go haywire. I fixed it by using just a pawn and writing all its physics and just using FTransform and Quats.