8
\$\begingroup\$

As far as I know, going further than 1M units from the world origin in Unity is hardly possible due to floating point precision issues.

Making a world more than 1M units in radius would require either using double vars for coordinates or utilizing some space division technique to divide a massive scene into hierarchical chunks with the smallest of them being around 10 000 units, i.e. each world-space position would be expressed by the chunk hierarchy the object's in and a bunch of float vars representing its local position (and possibly rotation and scaling) inside the last chunk.

Either way, doing this would require implementing a completly new coordinate system, so I'd like to know whether or not that is possible in Unity, and if so, how may I make it work with existing Unity systems like physics and so on.

P.S I can't just move the world into origin as the player moves since I want to have things going on simultaneously around the planet.

Thanks!

\$\endgroup\$
5
\$\begingroup\$

You're thinking in very static terms.

Just because an object is half a world away doesn't necessitate any issues. If entity coordinates are stored relative to chunk rather than relative to world, this is trivial to achieve. Welcome to the way you'd have to do it if you were writing a voxel world in native code.

So let's assume a concept called locales. It's a set of chunks that are in close proximity to one another. What matters is the float space internal to a given locale never exceeds the safety limit. You need to determine what your discrete processing locales are, start by taking all chunks that fall within a radius of the position of entity n (could be the player or something else). In my current engine, I make sure that if even one chunk of two different locales is overlapping, that these locales merge into one locale / set of unique chunks. This ensures that you never process all the entities in any single chunk more than once, in a given frame.

Now that you have your locales/chunk-sets, you can perform game logic on them and their contents. And it doesn't matter how far they are away from the player or from origin. What matters is that you get a chunk that is roughly central to each set, treat that as the origin i.e. float [0.0,0.0,0.0], and work your way outward from there. Given typical view range in a game, I guarantee you that you will never need to see more than a few kms, which is very doable with float, without serious issues.

Aside from Unity, one option is to write an engine from scratch, I guess, and use something like libfixmath, where you can still use decimal points but because they do not float, they will never have these accuracy issues. But I guarantee you will need chunks and locales for other reasons, so it's probably not worth the effort.

\$\endgroup\$
  • \$\begingroup\$ You said that I'll never need to see more than a few kms away, but what about a planet-sized world, which I should be able to observe fully from space (see outerra)? \$\endgroup\$ – Maks Maisak Oct 26 '15 at 13:42
  • \$\begingroup\$ @MaksimMaisak Game logic requires numerical precision; rendering does not. You'll never need to see the detailed, precise world from outer space. There is a certain height at which you can switch from the accurate, on-the-ground system I've described above, to the less accurate, space-perspective, seamlessly (if you play your cards right). But bear in mind there is a difference between rendering and game logic. \$\endgroup\$ – Engineer Oct 26 '15 at 13:44
  • \$\begingroup\$ And how do you divide space into chunks? Do you start with chunks and group them into locales, or start with locales and divide into chunks? \$\endgroup\$ – Maks Maisak Oct 26 '15 at 13:44
  • \$\begingroup\$ You start with chunks. "Locales" here just means "neighbourhoods of chunks" so the chunk concept is the prerequisite. \$\endgroup\$ – Engineer Oct 26 '15 at 13:45
  • \$\begingroup\$ How can a chunk be 'overlapping' then? \$\endgroup\$ – Maks Maisak Oct 26 '15 at 13:46
6
\$\begingroup\$

That's a question that frequently pops up. I will take the liberty to forward you to another fairly detailed answer I already gave to the same issue, instead of just repeating it here: Is a custom coordinate system possible in Unity

From there, what I would suggest the most is that you read the amazing paper at: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.471.7201&rep=rep1&type=pdf. It compares some of the ways to tackle the problem you describe (including local coordinates, as described by Arcane Engineer in his answer) and go into details about the nowadays famous float-origin solution. Which is, in fact, what I would go for in most cases (in fact, that's what I'm using in my application).

Sure, you mentioned the float origin solution does not suit your needs. But that may not be the case even if you want things to keep happening in very distant parts of the world. You can have pretty much any AI happening wherever you want - you just shouldn't be doing collision checks or precise positioning too far from the player (i.e. beyond the float inaccuracy threshold). But anyway, frankly, in real applications you probably would never be able to have that many collision and positioning in a game due to processing limitations. And still, there might be solutions even to that limitation you see on the float origin solution, depending on the characteristics of your game. Again, I suggest you do not discard that solution before a more thorough reading about it.

Still, if you decide that you should try local coordinate systems (which can become quite a complex solution depending on where you go with it), then the second item in my linked answer is for you. The most important piece there is the paper wrote by the guy who first implemented that solution in the pioneering game Dungeon Siege: http://scottbilas.com/files/2003/gdc_san_jose/continuous_world_paper.pdf

There is also 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

Hope it helps.

\$\endgroup\$
3
\$\begingroup\$

Not sure if you have already settled for a solution, but I'd like to mention two other resources that might be useful to you and other readers in the future.

  • This recent CppCon talk: "Demystifying Floating Point", which is very relevant regardless of programming language. One very interesting point presented about precision is that the sweet-spot of float accuracy is between the [-1,+1] range. So normalized floats are the best way to go if you can use them.

  • Another place you might want to look into to get some ideas is in the classic Dungeon Siege game. The game used a continuous world system that was node/tile based and every position was relative to the current node. There's very detailed description of the system used by the game in this whitepaper. I also wrote a few paragraphs about it in my blog. This setup was novel at the time, but it is probably not as useful today, the paper linked above mentions a few of the issues they had. Nevertheless, it is interesting from a historic perspective and might still serve you as a source of ideas and inspiration.

\$\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.