Unity Rigidbody movement jitter

Started by
11 comments, last by ptietz 5 years, 7 months ago

Hi everyone!

So, I have this rather complex Unity project, I've been working on for the past months.
So I will try to narrow it down to only the most relevant parts.

The game's core is pretty much your standard space sim,
meaning you're flying your spacecraft through open space.

To do that, I have a "Player" GameObject in the scene's root.
The Player has a Rigidbody (3D) attached, and a simple box collider.
And it has two child objects: One is the actual ship (incl. meshes, etc.) to be used for the simulation and outside camera views. The other is the cockpit (also containing meshes) to be rendered on top of the main camera's image by another camera.
The ship is then moved by applying force (and torque) to the Rigidbody.

So far, everything seemed to work smoothly. But I discovered, that if a coordinate exceeds about 20k on any axis, I get a very visible stutter/jitter in the cockpit. Will I really have to re-scale my whole game into miniature wonderland or did I overlook something?

It might be important to note, that as soon as I get the jitter, I can make it worse by changing course in any direction. Also, returning to my starting point (thus, putting coords into "working parameters" again) won't cancel the jitter. Neither flying back nor setting the coords by script will help.

Any idea will be much appreciated.
Thank you very much :)

 

Advertisement

I'll ask a few questions while you're waiting for replies.

Can you describe the camera/cockpit setup in more detail? (Maybe it was clear from your post, and I just didn't understand it.) It sounds like the cockpit mesh is attached to the player object. Is the camera that renders the cockpit mesh also attached to the player object? How exactly is the cockpit camera set up?

Yes, my setup is as follows:


- Player [RigidBody]
  - Ship [Mesh,BoxCollider]
    - Camera
  - Cockpit [Mesh]
    - Camera

There are no physics components attached to the cockpit.
And there's a third camera involved that renders the skydome. This one's not attached to the player object, however.

Thanks for your reply :)

What you describe sounds like you are hitting the limits of floating point precision, which is a common problem in space games.

We can think of 32 bit floats being able to represent only 6 digits, so with 20,000 units, there won't be much precision left for fractions below a single unit (20,000.01 == 20,000.02).

If you scale your world down it probably won't help much, because  20.00001 may still give the same number as 20.00002.

So there are 2 options:

Using doubles,

or representing your world with the player close to the origin (move the world instead the player, or scroll the world if the player extends some max distance). This way you have good precision around the player, and bad precision only very far away.

 

 

 

Thanks for the reply. Sounds like a reasonable explanation.

Unfortunately, I can't seem to use doubles here as Unity's Vector3 class used by the Transport components is working with floats.

Also the second approach won't work for me, either, because one of the main features of the game is that the whole space is a live simulation. Furthermore, the player is able to immediately jump into any of their ships at any time. So, I can't have jitters on ANY ship.

What I call "space" here is separated into different "sectors", each composed of its own unity scene. After the calculation of their respective dimensions, a script will organize the scenes into a three dimensional grid, putting them ViewDistance/2 apart from one another. So I did another test on this as well. Eventhough, the ship's local coordinates remain around 0,0,0 with respect to the current sector, if that sector's too far off, I still get the jitter.

This starts to feel like a dead end to me, yelling "go find a more suitable engine" - which would not only have me abandon tons of work (almost a year) but would also break my heart.

Please, if anyone has another idea... :(

21 minutes ago, ptietz said:

Also the second approach won't work for me, either, because one of the main features of the game is that the whole space is a live simulation. Furthermore, the player is able to immediately jump into any of their ships at any time.

It can still work, and usually it is preferred over using slow doubles anyways. If the player would beam from one ship to another in an instant, you would just transform the whole universe so the target ship is at the origin. If there are multiple players over a network, each client could do it's own local simulation. If you have a NPC on a distant ship, the NPC could even use some logic instead full physics simulation (kind of a Level Of Detail system for game logics not just for graphics) and so forth.

Your current approach of using sectors sounds already good. Let's assume you create a sector (or 'world') for each ship: You would just leave each ship in its own 'world' but all of them at the origin, and you would display a distant illusion of ships for the player. If two ships come close to each other and interact, you could move them both to a common world with the origin between them. (This can eventually cause minor problems for example with cached contacts: Stacks of boxes could suddenly tip over in the worst case.)

I don't know how you can use multiple physics worlds with Unity, probably there are many options for this... anyone else? (If not ask on Unity forum...)

But believe me this is no dead end. Really everyone faces this problem with space (or even open world) games. It requires some work but it's no show stopper.

 

Just out of curiosity, when you say jitter 'in the cockpit', do you mean that the cockpit mesh itself is jittering, or that the environment outside the cockpit is jittering? Another way to ask the question would be, if you turn off the cockpit mesh, does whatever effect you're seeing still manifest? (It may be that JoeJ has already supplied the answer you need, but in the interest of being thorough it might still be useful to clarify the behavior you're seeing.)

So, I did a few more tests and got very close to my monitor xD

@JoeJ What you propose sounds like a major undertaking but also like a plan. I will have to make sure that floats really are the cause and carefully think this through before I start. But it seems, you're right. I took it to the extreme this time and now even Unity says "Due to floating-point precision limitations, it is recommended to bring the world coordinates of the GameObject within a smaller range.". Thank you so much for your input!

@Zakwayda Very good question! A bit surprisingly, it, indeed, seems to be the case that only the cockpit itself is affect, not the outer world (only tested with stationary objects). This suggests, that it's not a problem with the camera. But it may still have to do with the floating values.

Here's something to consider if you haven't already. If the cockpit is just a cosmetic first-person effect, it doesn't necessarily need to be associated with the player ship at all. Both the cockpit mesh and camera could be entirely separate and always have a transform of identity. Although you might still have to address the precision issue for other reasons, that would certainly solve the cockpit jitter problem :)

true, thank you very much :)

This topic is closed to new replies.

Advertisement