- Home /
Trying to mix physics and direct movement without jitter
So here is the thing I am wanting to accomplish. I have a flying ship that I want to apply forces to and have bounce off various objects. If it flies by something and a wing clips the obstacle, I want it to go spining. If it gets hit by a small fast moving object, I want to lurch a little bit. The game is 3D, but takes place entirely on a 2D plane, so I don't want the ship to get bounced up or down.
Here is the tricky bit. I want to have the thing "bank", even though it doesn't make a lot of real physical sense (for design and artistic reasons, I want it to bank a little when it turns. If it is turning and hits or grazes an object, I still want it to bounce and spin around the Y axis (world), but I want to leave the rotation about the Z axis(local) unchaged. i.e. I wish to retain the "bank" amount.
I have tried a number of methods and none of them are really satisfying me.
My first approach was to constaint x and z rotation, apply torque to turn and then adjust the transform's rotation directly. This, however, gets a little jittery do to conflicting update times, motion methods and interpolation methods.
The most basic form looks like this
public class CleanPhysicsShipController : MonoBehaviour
{
void Update ()
{
transform.rotation = Quaternion.Euler ( transform.rotation.eulerAngles.x, rigidbody.rotation.eulerAngles.y, Mathf.Sin( Time.time ) * -10f );
}
void FixedUpdate()
{
if ( Input.GetKey( KeyCode.W ) )
{
rigidbody.AddForce (transform.forward * 2.0f , ForceMode.Impulse);
}
if ( Input.GetKey( KeyCode.S ) )
{
rigidbody.AddForce (transform.forward * -2.0f , ForceMode.Impulse);
}
if ( Input.GetKey( KeyCode.D ) )
{
rigidbody.AddTorque( Vector3.up * 10.0f, ForceMode.Impulse );
}
if ( Input.GetKey( KeyCode.A ) )
{
rigidbody.AddTorque( Vector3.up * -10.0f , ForceMode.Impulse );
}
}
}
If I just let it rock back and forth, it looks smooth, but when I try to turn with the keyboard, it starts looking a little twitchy (I have my camera directly childed to the object, so the object appears static on my screen, but the surroundings jitter). I have tried moving the "roll" line into FixedUpdate and using Time.fixedTime or other time values. I haven't found a combination or calls, times and orders that works yet.
I have also tried using AddTorque and AddRelativeTorque (with X and Z unconstrained) to accomplish the independent roll/bank, but the yaw torque and the bank torque compose into some random twist that I don't desire. I want local Z rotation and world Y rotation and nothing else.
I toyed around with various hinges but that seems to really complicate things. Especially if I do this with a lot of different objects that I need to maintain and iterate on.
Is there any way to manually update the rotation of a gameObject that has a rigidbody so that it somehow acts in harmony with the physics system? Hypothetically, my physics portion only affects Y ( due to constraints on the ridigbody ) and my direct portion only affects X and Z.
Thanks!
Edit: Forgot to mention.I have tried using all three interpolation methods. None makes the sin wave rolling smooth, but the yaw torque choppy. Interpolate makes the yaw torque smooth but the sin wave roll choppy. Extrapolate is just kind of worse.
Could you please "TIC$$anonymous$$" an answer to keep the site tidy.
Answer by Fattie · Jul 17, 2012 at 08:55 AM
I was only able to read your title: "Trying to mix physics and direct movement without jitter"
The answer is, you'll have to get in to "combined rigs"
This is at the very heart of rigging and making physics in Today's Game Industry.
Unfortunately I was not able to read your question (I am dyslexic) (to long-form writing) (or any manuals) but generally you will have to enter the magic world of taking a kinematic body and attaching a physical body underneath it, and other similar combinations.
In a simple version, you might have a totally "normal" PhysX model that bounces around, OK?
But make inside that essentially you can think of it as "a sprite", just a static 3D model, which, YOU rotate by hand as a separate cognitive process. (Quite possibly, using some sort of input from the physics layer.)
Another very common thing is you'll have an invisible "go to" target that behaves exactly "normally" using physX like in a hello world program for Unity3D. But then your real object in fact is always hunting after that go-to target, and doing so with behaviour of it's own (perhaps maintaining spin or whatever).
I hope this general comment helps in some way!
You need to make a "combined" rig to achieve your aims!
What's that great line from Star Wars, you'll take a step in to a broader world...
Answer by Vigeous · Jul 17, 2012 at 11:26 AM
Well. Now I feel kinda dumb. I tried this sort of child-parent thing with hinges, but that was overcomplicating it.
Now I have
Anchor -rigidbody with x and z rotation locked and interpolation set to "Interpolate" -Script that adds forces
And childed to that: Ship -Collider -Script that directly messes with transform]
I was all worried that if I did this, the parent object wouldn't have the right collider, but I forgot colliders can exist anywhere in the object hierarchy.
<--Really dumb and really happy to have an answer.