Greetings developers!
I have a simple goal in mind: control the pitch (x) and roll (z) of a circular platform (built using a sphere with scale 10, -0.1, 10) to balance a sphere on top of it.
However, I wish to limit the rotation both in the x and z axes (ideally the y axis is frozen), so that the platform cannot go beyond a certain tilt angle (50f) in any direction.
The code below works, but not exactly as desired: the moment the platform reaches the tilt angle, the ‘if’ statement no longer holds and the platform gets stuck, forcing me to release all keys to restore the original rotation of the platform (0, 0, 0).
My wish is that, once the platform has reached the tilt angle limit (or approached it), I may keep tilting the platform on the axis which has not reached the limit.
I hope the GIFs can better express what my desired result is. In the first one (above), I am showing the as-is behavior, in the second one, I am showing the desired behavior (I used a simple work-around setting the max tilt angle to 80 giving the impression that the platform does not get stuck at the 50 limit and I can keep rotating within my desired limit).
I have been stuck on this for days, can anyone help?
Thanks in advance, and please let me know if I can provide any additional info to make the question clearer. Cheers!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class KeyController : MonoBehaviour
{
Quaternion originalRotation;
Rigidbody m_Rigidbody;
bool restoreRotation = false;
[SerializeField] float tiltAngle = 50f;
float h;
float v;
private void Start()
{
originalRotation = transform.rotation;
m_Rigidbody = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
m_Rigidbody.constraints = RigidbodyConstraints.FreezeRotation;
m_Rigidbody.constraints = RigidbodyConstraints.FreezePosition;
if (!Input.GetKey(KeyCode.LeftArrow) & !Input.GetKey(KeyCode.RightArrow) & !Input.GetKey(KeyCode.UpArrow) & !Input.GetKey(KeyCode.DownArrow) & !restoreRotation)
{
restoreRotation = true;
}
// If I am not holding down any key, take me back to original rotation 0, 0, 0
if (restoreRotation & !Input.anyKey)
{
transform.rotation = Quaternion.Lerp(transform.rotation, originalRotation, Time.deltaTime * 2);
if (transform.rotation == originalRotation)
{
restoreRotation = false;
}
}
else if (restoreRotation & Input.anyKey)
{
restoreRotation = false;
}
// If I am holding down the left, right, up and/or down key
else if (!restoreRotation)
{
h = Input.GetAxis("Horizontal") * tiltAngle;
v = -Input.GetAxis("Vertical") * tiltAngle;
if (Quaternion.Angle(originalRotation, transform.localRotation) <= tiltAngle)
{
transform.localRotation *= Quaternion.AngleAxis(h * Time.deltaTime, new Vector3(0, 0, 1));
transform.localRotation *= Quaternion.AngleAxis(v * Time.deltaTime, new Vector3(1, 0, 0));
}
}
}
}