When I place the character and the ground very far away (59697, 22, 248928), the camera and the character along with the materials shake a lot and don’t display properly.
The console keeps saying: Screen position out of view frustum (screen pos 881.000000, 181.000000) (Camera rect 0 0 1235 565)
UnityEngine.SendMouseEvents:smile:oSendMouseEvents (int)
Welcome to floating point precision, or lack there-of. Once you get far enough away from origin, regular floating numbers don’t have the precision to deal with such large numbers.
There are multiple solutions to this problem, and it’s well travelled ground. I would look into them to see which one suits your project best.
To elaborate further, decimal numbers in computers are represented using something called “floating point”. The reason is that you have a fixed amount of space to represent a number (usually 32 bits), and you can’t possibly represent an infinite amount of values using finite space.
So the way this is solved in computer science is by varying the amount of detail used to represent the part of the number before the decimal point and the part after the point. When you use more detail for one part, you sacrifice detail for the other. This is why it’s called floating point.
Exactly how much detail is used for each part depends on the magnitude of the number: to represent small numbers (eg 0.00001) you need more precision after the point, but to represent larger numbers (eg 10000) you need more precision before the point.
Now, to represent a number like the Z coordinate of your player (248928) you’re leaving very little precision after the point. So you can represent 248928.1, 248928.2, 248928.3, but probably not 248928.018325 since it has too may decimal positions. As a result, things shake around as their position can’t change smoothly and instead will “jump” to the closest representable decimal number. Note this is a fundamental part of computers, nothing specific to Unity.
There’s many solutions to this, all involving tricks to avoid such large numbers. You might choose a different one depending on which kind of game you’re making. A typical approach is to use a floating origin, that is, move all objects in your scene so that 0,0,0 is close to the character/camera.
That’s primed for a Star Wars quote but instead all I can give is this Minecraft “far lands” video showcasing all the odd glitches you’ll experience far, far away in any game engine:
I sincerely appreciate everyone’s support. I am still looking for the best solution to this problem, and all of your suggestions have been very helpful to me.
Yes but the origin shift isn‘t as easy as it sounds. A high number of (nested) objects can cause a lag spike, and Rigidbody objects may need to be updated separately. Still there is no alternative to origin shift but it‘s easier if the game was designed from the ground up to support this.
Also note that origin shift/floating origin isn’t a one-size-fits-all solution. For instance if you’re making an endless runner type of game, instead of making the character run over static scenery (which will quickly get him very far from the origin), a typical approach is to keep the character static and move the scenery in the opposite direction instead, kinda like a treadmill.
This allows the character to be at the origin at all times no matter how long he has been running for, so floating point precision isn’t an issue anymore.
That would make everything slower (since double arithmetic is more expensive) and still not solve the problem: just make it less likely to happen.
At its core, this is a design issue: computers are digital machines, not analog ones. They can’t perfectly represent continuous functions (as that would require infinite precision), so you must design your game in such a way it doesn’t need that.
I agree and one of the main reasons doubles are slower i that they use twice the bandwidth of floats. You will get lower bandwidth performance between CPU/cache memory, between GPU and memory and across the network.
As others have said, the coordinates for the player should be smaller otherwise you get jitter jitter examples. A summary of the reasons: howJitterHappens.
The general solution is to use real floating origin, not the origin-shifting (which is often mistaken for floating origin), others have suggested.