How to calculate and use new direction angle as a new forward direction.
My player is a cube tumbling forward/backward and sideways.
This script calculates the edges of my cube and make it rotate around its edge.
void FixedUpdate()
{
bound = GetComponent<BoxCollider>().bounds;
left = new Vector3(-bound.size.x / 2, -bound.size.y / 2, 0);
right = new Vector3(bound.size.x / 2, -bound.size.y / 2, 0);
up = new Vector3(0, -bound.size.y / 2, bound.size.z / 2);
down = new Vector3(0, -bound.size.y / 2, -bound.size.z / 2);
//These are the 'positionToRotations' when pressed by arrows) }
IEnumerator Roll(Vector3 positionToRotation)
{
isRolling = true;
float angle = 0.0f;
Vector3 point = transform.position + positionToRotation;
Vector3 axis = Vector3.Cross(Vector3.up, positionToRotation);
while (angle < 90f)
{
float angleSpeed = Time.deltaTime + rotationSpeed;
transform.RotateAround(point, axis, angleSpeed);
angle += angleSpeed;
yield return null;
}
transform.RotateAround(point, axis, 90 - angle);
isRolling = false;
}
(What I like about this function is that I can change the size of the cube and make it a rectangle too)
But when my cube is randomly rotated (Y axis) in the world space, it tries the find the wrong 'point' and 'axis'. So I need to calculate where these are and (even more complicated for me) write a line how to use them. This picture illustrates what I'm stuck at.
I have no idea how this works in the mathematical way. I tried a lot of Quaternion.AngleAxis stuff, but I don't fully understand the math behind it.
Answer by ngerbens · Jul 02, 2021 at 11:16 AM
Well, since I figured out how this works, I'd just answer it myself for everyone who might encounter this post in the future....
This is how it works
IEnumerator Roll(Vector3 positionToRotation)
{
isRolling = true;
//GroundLevel
RaycastHit hit;
Physics.Raycast(thisRigidBody.position, Vector3.down, out hit);
//RB gravity
thisRigidBody.useGravity = false;
Vector3 cam = Camera.main.transform.forward; cam.y = 0;
float angle = 0.0f;
//This calculates the perpendicular of the cam forward
float angleNeeded = Mathf.Atan2(Vector3.Dot(Vector3.up, Vector3.Cross(newUp, cam)), Vector3.Dot(newUp, cam)) * Mathf.Rad2Deg;
Vector3 point = transform.position + positionToRotation;
Vector3 groundPoint = new Vector3(point.x, hit.point.y, point.z);
Vector3 axis = Vector3.Cross(Vector3.up, positionToRotation);
Vector3 camAxis = Quaternion.AngleAxis(angleNeeded, Vector3.up) * axis;
while (angle < 90f)
{
float angleSpeed = Time.deltaTime + rotationSpeed;
transform.RotateAround(groundPoint, camAxis, angleSpeed);
angle += angleSpeed;
yield return null;
}
transform.RotateAround(groundPoint, camAxis, 90 - angle);
thisRigidBody.useGravity = true;
isRolling = false;
}
'newUp' is equivalent to 'up' in the FixedUpdate. But I turn up into newUp depending on the rotation of the camera in another section.
This Answer is only one part of the answer: I still need to figure out how the 'point' is replaced in the right position.