The question would be, how are you moving your flipper?
Is your flipper being controlled by physics or by math.
The disclaimer would be that if you are using math (transform.Rotate or something similar) you are bypassing the physics updates. This would result in horrid results when trying to do a physics driven game. Pinball would fall into that category.
here is a trick.
On the flipper. First, make sure that you constrain it’s position. so it does not move. Next, freeze it’s X and Z rotation. (this really depends on how you set up your flipper) This will make sure that it doesnt turn in odd directions.
Now, you will need to build a custom “watcher” that makes sure that the flipper is maintained between two angles. This watcher will also watch the keys. So lets say that the left shift (KeyCode.LeftShift) and right shift (KeyCode.RightShift) control your flippers. In the FixedUpdate, you will see if either of those keys are active (Input.GetKey()) and apply torsion in the correct direction on the flipper. (since the other angles and the position is locked it wont move). To do this, simply add something like this:
// force the angular velocity
rigidbody.angularVelocity = transform.up * 100;
To Limit the angle, you will need to use a perfect euler angle. (I will post that later) You need to make sure that the angle that you are working with is between -180 and 180 degrees, clamp it, then set it back to that angle. The next part is that you will need to stop the angularVelocity when it reaches its limit.
// make sure the euler we get is between -180 and 180
euler = transform.localEulerAngles;
euler.y = euler.y > 180 ? euler.y - 360 : euler.y;
// clamp your angles so that you dont overshoot.
euler.y = maxAngle > 0 ? Mathf.Clamp(euler.y, 0, maxAngle) : Mathf.Clamp(euler.y, maxAngle, 0);
// if we hit the max angle, stop the velocity change.
if(euler.y == maxAngle) rigidbody.angularVelocity = Vector3.zero;
// set the euler back to the transform
transform.localEulerAngles = euler;
So in this case, I am checking to see if the angle has reached maxAngle. If so, I simply set the angularVelocity back to Zero.
Now, the deal with “perfect” euler angles is that you need to get the localEulerAngles from your object. This gets angular values from the difference from it, to it’s parent. If you don’t have a parent, it gets it from the difference to the global world. This is usually bad. Any time you get a “difference” it will tend to mess up an EulerAngle badly. To fix this you “cheat”. Simply add a parent object to your flipper, that is in the same place and has the same rotation. When you get the euler, it will then give you numbers offset from it’s original rotation. This is good.
So your start will look something like this:
function Start(){
// make sure we have a rigidbody
if(!rigidbody)gameObject.AddComponent(Rigidbody);
rigidbody.mass = mass;
rigidbody.useGravity = false;
// lock the rigidbody in place
rigidbody.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationZ | RigidbodyConstraints.FreezePosition;
// hold the object so that you can get proper angles
var obj:Transform = new GameObject("dummy holder").transform;
obj.parent = transform.parent;
obj.position = transform.position;
obj.rotation = transform.rotation;
transform.parent = obj.transform;
}
Notice, that I also gave the locks, and stopped gravity from affecting the flipper. I also put mass in.
OK, yes, I wrote the whole thing, (mostly cos I wanted to check for dumb errors) It should work just fine (but I didnt test it) See what you can come up with from that, and post your script back. If you run into big problems, just ask.