Limit rotation and return the initial angle of an object
My code below works perfectly. The code rotates an object around a pivor . However while press the button " JUMP" it rotates endlessly . I need this to be limited. When the button is not pressed, the object must return to its original angle. As a pinball game .
using UnityEngine;
public class MoveBarra : MonoBehaviour {
public Transform pivor;
bool restoreRotation = false;
void Update()
{
Vector3 temp = pivor.transform.position;
if (Input.GetAxis("Jump") == 1)
{
transform.RotateAround(temp, Vector3.forward, 500 * Time.deltaTime);
}
if (Input.GetAxis("Jump") == 0)
{
restoreRotation = true;
}
if (restoreRotation)
{
/* RETURN ROTATE HERE*/
}
}
}
Answer by aldonaletto · Feb 05, 2016 at 01:54 AM
Faking the flipper movement is somewhat easy - the big problem is how to simulate pinball physics, since the physics engine doesn't handle the flipper/ball collision correctly.
In order to fake the movement, you can store the initial rotation (and position) in member variables (variables declared outside any function) and measure the angle between the initial and current rotations with Quaternion.Angle, stopping when a maximum angle is reached.
Returning to the original position/rotation can be made by simply restoring the initial rotation and position (we need to restore rotation and position because RotateAround modifies both). That's an incorrect way to return the flipper to its initial position, since it returns immediately, but doesn't look so bad in practice.
public class MoveBarra : MonoBehaviour {
public Transform pivot;
public float rotSpeed = -720.;
public float maxAngle: = 90.;
Quaternion rot0;
Vector3 pos0;
void Start () {
rot0 = transform.rotation; // save initial rotation...
pos0 = transform.position; // and initial position
}
void Update () {
// copy button state in a bool variable - Input.GetButton is somewhat slow
bool button = Input.GetButton("Jump");
if (button && Quaternion.Angle(transform.rotation, rot0) < maxAngle){
// if button pressed and rotation not complete yet, rotate a little
transform.RotateAround(pivot.position, pivot.up, rotSpeed * Time.deltaTime);
}
if (!button){
// button released: return to initial position/rotation:
transform.position = pos0;
transform.rotation = rot0;
}
}
}
Returning the flipper gradually is risky: Quaternion.Angle returns an absolute angle, thus the flipper may pass back the initial rotation and continue rotating forever like a crazy clock hand: the angle returned is absolute, thus it falls to zero and then starts growing again.
Anyway, the second if could be replaced by a code like this:
if (!button && Quaternion.Angle(transform.rotation, rot0) > 3){
// if button released and angle greater than 3 degrees, rotate back a little
transform.RotateAround(pivot.position, pivot.up, -rotSpeed * Time.deltaTime);
}