'Scaling rolling ball controls with it's size
I am editing the rollingball example map from Unreal (in Unreal Engine). I changed it so my ball you grow and melt (it's a snowball), gaining and losing size and mass.
My problem is the control of it. The example map moves the ball by adding torque. My problem is that my mass changes a lot, so I need a torque the changes depending on the size of my ball (not 1:1 as a bigger snowball should still moves slower).
My problem is that my ball seems to accumulate torque and spins a lot (I added a lot of friction to the ball, it did not helped, it just moved the problem a bit). As an example, if I press left for a while, it's gonna go left. Then if I press right, it goes right. But when I stop pressing right, it spins and goes left again.
This is my current code:
void ASnowballBall::MoveRight(float Val)
{
const FVector Torque = FVector(-1.f * getNewTorque(Val), 0.f, 0.f);
Ball->AddTorque(SpringArm->GetComponentRotation().RotateVector(Torque));
}
void ASnowballBall::MoveForward(float Val)
{
const FVector Torque = FVector(0.f, getNewTorque(Val), 0.f);
Ball->AddTorque(SpringArm->GetComponentRotation().RotateVector(Torque));
}
float ASnowballBall::getNewTorque(float Val)
{
return (Val * RollTorque * (log2(Ball->GetMass()))) / 10000;
}
Note: The log was a test to increase the torque slowly with the mass. It's not working well at all. Right now I am using return Val * RollTorque
instead, but it's almost as bad.
The control is horrible and I would like to get an idea on how to fix it. If removing the torque would be better, I will change it. I simply want a responsive control that is fun, and where the player still have a sense of the size of the ball (slower when big compared to small).
PS: My original mass is about 500 kg and can go up to 20 000 kg (it's a puzzle game). I did not set the original mass, it's set by Unreal relative to it's size. I could change the mass scale though.
Solution 1:[1]
You could try using AddForce
instead of AddTorque
.
So the speed of the ball is modified every tick like this:
void APlayerBallBearing::Tick(float deltaSeconds)
{
Super::Tick(deltaSeconds);
BallMesh->AddForce(FVector(InputLongitude, InputLatitude, 0.0f) * ControllerForce * BallMesh->GetMass());
}
InputLongitude
and InputLatitude
are the values that are put in by the user in the current frame for movement in cardinal directions, they correspond to your MoveForward
and MoveRight
values I reckon.
The controller force is something you need to tweak in order to find the right value for your ball movement. With a value of at least 600.0f I started getting "decent" behaviour.
I cannot help you with the mass though you would need to try that out yourself, the default mass of the ball mesh I used was ~110.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Tyler2P |