Calculating rigidbody trajectory and rotation amount.

Hi hows it going,

I have not been using Unity for over a year and I finally decided to come back and do some work.

I have been working on a Geometry Dash-esque game and I was trying to find a way to rotate the cube mid air when the character jumps OR goes off of a ledge. I was trying to think about a solution to this and I thought maybe if I calculated the trajectory and did some maths based off of gravity as to where the character will land and rotated the character a certain amount of times based on how long it would take to get there.

Basically, I want the character which is a cube, to rotate to land on a side perfectly each time it goes of a ledge or jumps.

Here is my movement code:

public Rigidbody rigidBody;
	public float moveSpeed = 5f;
	public float jumpForce = 2f;
	public float jumpForceMultiplier = 30f;
	public float jumpDelay = 1;
	public bool canJump = true;
	Collider thisCollider;
	public GameObject groundCheck;



	bool jump = false;



	// Use this for initialization
	void Start () {
		rigidBody = gameObject.GetComponent<Rigidbody>();
	
		thisCollider = gameObject.GetComponent<Collider>();
	}
	
	// Update is called once per frame
	void Update () {
		canJump = GroundCheck();
		if(jump == false && canJump ){
			jump = Input.GetKeyDown(KeyCode.Space);
		
		}
	
	
	}
	
	void FixedUpdate () {
		if(jump){
			rigidBody.velocity = new Vector3(rigidBody.velocity.x,jumpForce*jumpForceMultiplier,moveSpeed);
			StartCoroutine(freezeRotation());
			jump = false;


		}else{
			rigidBody.velocity = new Vector3(rigidBody.velocity.x,rigidBody.velocity.y,moveSpeed);

		}
	}



	bool GroundCheck(){
		return Physics.Raycast(transform.position, -Vector3.up, thisCollider.bounds.extents.y + 0.1f);
	}

	IEnumerator freezeRotation(){
		rigidBody.constraints = RigidbodyConstraints.FreezeRotationY | RigidbodyConstraints.FreezeRotationZ;
		rigidBody.AddTorque(20f,0,0);
		yield return new WaitForSeconds(0.1f);
		yield return new WaitUntil(GroundCheck);

		rigidBody.constraints = RigidbodyConstraints.FreezeRotation;

		yield break;

	}


}

Cheers!

Incidentally, I’ve yet to have any specific need to update a few functions I’ve used in the past, so I keep referring trajectory calculation-related questions to one of my previous answers. This isn’t about being a cheapskate on the answer (well, not entirely, anyway), but instead knowing when not to restate the exact same thing verbatim.

That said, I placed a specific emphasis on the general formulas and application to calculate reaching a specified destination under predetermined circumstances. With that in mind, as long as you know how the object is traveling at any given moment, you’ll be able to know how long it will take to hit the ground at any location. If the player can adjust their trajectory in the air, the same principles still apply in general. As long as the current/starting position, the ending position, and the velocity vectors are known, you’ll be able to determine when it will reach the ground.

With this in mind, you can then determine how many revolutions you want to perform per second and round that down, in the case of a square/cube, to the next 1/4-second interval.

// C#
// dr: Divided Rotations -- For any specific shape
// ss: Shape Sides -- For specifying the number of equilateral sides (A square/cube would be 4)
// ttd: Time to Destination -- The total time airborne until hitting the ground.
// rps: Revolutions per Second -- Maximum rotation rate, full rotations
int dr = (int)(ttd * rps * ss);
float newRotationSpeed = (dr * (360.0f / ss)) / ttd;

While it may appear a bit convoluted (especially with all the variable name shortening I never typically do), the rate of rotation (in degrees per second) is calculated by:

1) Determine how far the object will rotate. If a cube spins at 1 revolution per second for 1.8 seconds, it will rotate

(int)(1.8f * 1.0f * 4) = (int)(7.2f) = 7 times

2) Use that value to determine how quickly you need to rotate in order to stop with that timing.

7 * (360.0f / 4) = 7 * 90.0f = 630.0f degrees
630.0f / 1.8f = 350.0f degrees per second