6
\$\begingroup\$

Is it possible to create a custom coordinate system (i.e the one using double for coordinates or the one dividing the world into 'chunks' of safe size) not constrained by the floating point precision limitations in Unity, and make systems using the built-in coordinate system use that one instead somehow?

Thanks!

\$\endgroup\$
8
\$\begingroup\$

If what you want is to bypass the floating inaccuracy caused by single point precision problem, for the sake of creating bigger environments for your game, then it depends on what you are willing to accept as a solution.

Let's start by making this clear: it is impossible to alter the coordinate system at the inner core of Unity. So, you can't use double-precision inherently for coordinates.

1) Depending on how you need it, however, it is possible to have custom classes in double-precision that might be of help. Of course it sill converts back to float so Unity system can work with, which is not a solution, but in many cases it might be of help even if for implementing other solutions. By the way, someone has already implemented that for Unity: a fake Vector3d, i.e. a fake Vector3 with double precision: https://github.com/sldsmkd/vector3d

And for a discussion on that piece of code, please see: http://forum.unity3d.com/threads/double-precision-vector3.190713/

2) As for the second part of your question, yes, it is possible to divide the world in areas to bypasse the problem for having big environments. But that still uses Unity's usual single precision coordinate system. That trick was first implemented in the game Dungeon Siege. The guy behind that wrote a paper on it:

http://scottbilas.com/files/2003/gdc_san_jose/continuous_world_paper.pdf

And also gave lectures about it too, from which slides are here:

http://scottbilas.com/files/2003/gdc_san_jose/continuous_world_slides.pdf

There is a video from a couple of years ago, where people from Unity comment on that solution and even explain a modern implementation of the concept in Unity:

https://www.youtube.com/watch?v=VKWvAuTGVrQ

Also, there was already a similar question in Unity QA, with an user answer that might also enlighten you on the small piece related to coord-conversion:

http://answers.unity3d.com/questions/355721/custom-world-coordinate-system-changing-spaceworld-1.html

3) Also, see this blog entry, with very interesting stuff on the problem and an idea on using multiple cameras to handle it

http://www.davenewson.com/dev/unity-notes-on-rendering-the-big-and-the-small

4) Lastly, there is also the now famous solution implemented by Kerbal Space Program, which was a game made with Unity. It is not a new solution and is sometimes refered to as "Futurma method", being related to a broader solution called "floating origin".

First of all, see this general discussion on your problem with a related idea using offsets from the player position:

http://www.udellgames.com/posts/size-matters-and-precision-too/

Specifically on Kerbal, you can see:

http://forum.kerbalspaceprogram.com/entries/54-Scaled-Space-Now-with-100-more-Floating-Origin

And also: https://www.youtube.com/watch?v=mXTxQko-JH0

For a good (although non-professional) tutorial on how to implement it:

https://www.youtube.com/watch?v=VdkkTHV_5H8

And for a script implementing Floating Origin in Unity, see:

http://wiki.unity3d.com/index.php/Floating_Origin


Lastly, a definitive must-read is the following paper, which proposed the Float Origin years ago and even describes and compares it to the other solutions such as dividing space into chunks with their own coordinates:

http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.471.7201&rep=rep1&type=pdf

\$\endgroup\$
4
\$\begingroup\$

I doubt that there's a way to change the coordinate system Unity uses internally for its transforms/physics/etc. Not without recompiling the engine source at least. But that may not be necessary to get both the precision and scales you need.

Kerbal Space Program is made with Unity, and plays out over interplanetary scales. The developers have been great about sharing their process for dealing with these issues:

The basic idea is that the player characters/vehicles are kept near the origin, so that Unity's physics system remains well-behaved for interactions between vehicle parts, characters, and terrain. Similarly, when the player zooms their camera around in the map, the displayed objects are shifted around to keep the camera near the world origin to avoid visible jitter.

All the positioning & movement on planetary and interplanetary scales is done in their own code using double-precision values. Then scaled representations can be arranged in the single-precision scene for display. Since the area closest to the camera has high precision even in the single-precision scene, this downgrade doesn't produce visible errors. More distant content can have rounding errors, but this is hidden by the fact that it's far from the player's view, and is only being used for rendering.

I infer from your other question that you may have multiple simultaneous players or active regions, so you can't rely on a recentering around a single viewpoint. This complicates the floating origin solution, but doesn't rule it out. What you can do is have multiple active chunks each re-centering independently, using Unity's layers to keep them from interfering with each other's rendering or physics. When one chunk's contents are visible from a camera in another, you'll position proxy objects in the viewing chunk's layer, with their positions calculated from their position in their parent chunk and the offset of that chunk from the viewing chunk. This will handle something on the order of tens of simultaneous chunks, depending on how many distinct layers you need within each.

This will break down if you need more like hundreds of chunks actively simulating, but by that point you're well past the bleeding edge of Unity games and closer to theoretical physics simulations. Either aggressive simplification/approximation or a custom engine may be needed to handle fine-scale gameplay so widely distributed.

\$\endgroup\$
1
\$\begingroup\$

While I hate one word answers I think this one is a "no". Unity is designed to only use floats as far as I can tell. You'll have to convert doubles to floats yourself when using unity functions which likely defeats the purpose of using doubles to begin with.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.