Hello, I’m trying to make a clone of an android game called “Sky Rolling Ball Run 3D”, link: https://play.google.com/store/apps/details?id=com.sa.sky.rolling.ball&hl=en.
In the game, the ball only rolls on X-axis and steers through Y-axis rotations. Z-axis is constricted so that the ball doesn’t roll in a cross pattern/uncontrollably. I have a script written in which the ball is rolling fine on the x-axis and steering on the y-axis on straight planes. But when the ball approaches a slope, it starts to rotate backward at the start of the slope, it stops rotating mid-slope and starts rotating in the correct direction at the end of the slope. This is my function to keep the ball up-right. I’m calling it in FixedUpdate() method.
private void AdjustChildRotation()
{
float speed = rb.velocity.magnitude;
// Only adjust the rotation when the ball is moving
if (speed > 0.01f)
{
Vector3 movementDirection = rb.velocity.normalized;
// Lock the rotation on the Y-axis only for ballDirection, to face the movement direction
Quaternion lookRotation = Quaternion.LookRotation(movementDirection, Vector3.up);
ballDirection.rotation = Quaternion.Euler(0, lookRotation.eulerAngles.y, 0);
ballChild.rotation = Quaternion.Euler(0, lookRotation.eulerAngles.y, 0);
// Calculate rolling amount based on movement speed
float rollAmount = speed * rollMultiplier * (360f / (2 * Mathf.PI * ballChild.GetComponent<SphereCollider>().radius));
// Apply the roll rotation only along the x-axis, allow physics to handle other axes
ballChild.Rotate(Vector3.right, -rollAmount * Time.fixedDeltaTime * rollSmoothness);
Debug.Log("DIrection: " + movementDirection);
}
//Debug.Log("Speed: " + speed);
}
I’ve searched a lot and found out that the line “ballChild.rotation = Quaternion.Euler(0, lookRotation.eulerAngles.y, 0);”, is the cause of the problem.
I commented out the line and the ball rolled correctly on the slope, granted that it wasn’t restricted to one axis only. What can I do to keep the ball rolling correctly, regardless of the terrain.
For the forward movement, I’m using “rb.AddForce(moveDirection * (forwardForce + speedIncreament) * Time.deltaTime);”, in another function.
My hierarchy: ballChild → ballParent. Rigidbody, sphere collider and the script is on parent, while the child has only the mesh.