Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
2
Question by captainkrisu · Oct 17, 2015 at 06:19 PM · unity 5movinglargestarsuniverse

Huge scale solar system.

Hello!

I need assistance on a problem, I'm playing with huge scale scenes, and in this case a Solar System.

Currently there is 1 planet and 1 yellow star. The thing is, that due to the floating point limitations, I cannot just move a planet or player over 100000 Unity Units without getting loss in precision.

I've been searching, and found this: "You don't move in the universe, the universe moves around you." Also I watched Unite 2013 where KSP dev told the same thing.

The player's ship has a simple rigidbody and a controller to move it around. But It cannot move up or down in space.

So, I have all GameObject's (Except the Player) in a parent GameObject, called Universe, now I need to keep the player in the middle of the scene, and make the Universe GameObject move making it look the player would be moving.

First thought is to have triggerboxes all around player, and make universe move to the other direction the triggerbox hit was. But its pretty inaccurate.

Second thought is doing everything in a universe mover script, and make the player reset its position with FixedUpdate function. But how do I get where I am going? The ship controller script is just adding force to the rigidbody when button was pressed.

Third thought is multiple scenes, having an trigger around the edges, and then loading the new scene. Problem is that the planet's have orbits, and rotations.

I like the Second one most, I know how to keep player in the middle, but what about moving? And what if there are NPC's or Asteroid moving at high speed, how are they going to look?

Help.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

3 Replies

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by Bunny83 · Oct 18, 2015 at 11:36 AM

Having the whole universe in one gameobject will result in the same problem after some time. Your universe gameobject would be far away from you and the float calculations will get imprecise. You have to cut down the actual distance. The best approach in terms of performance is to let the player move in a small area around the origin and when he goes beyond a certain limit in one direction you simply move everything so the player is again close to the center.

The best way to move such a universe is to use two gameobjects which are located at the origin. One is empty the other contains everything. When you want to move the univers you simply move the gameobject that contains everything and then move all objects over to the empty gameobject. That way everything is again relative to the origin. You should group things that belong together into intermediate gameobjects so it's easier to move them and it reduces the relative error due to parenting / unparenting at high distances.

Your can use a UniverseOffset script like this:

 // UniverseOffset.cs
 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 using System.Linq;
 
 public class UniverseOffset : MonoBehaviour
 {
     public Transform player;
     public Transform universe;
     public int xSector = 0;
     public int zSector = 0;
     public float sectorSize = 1000f;
     private Transform tempUniverse;
 
     void Awake()
     {
         tempUniverse = new GameObject(universe.name + "_2").transform;
         tempUniverse.position = tempUniverse.eulerAngles = Vector3.zero;
     }
     void Update()
     {
         Vector3 pos = player.position;
         int xMove = 0;
         int zMove = 0;
         if (Mathf.Abs(pos.x) > sectorSize)
             xMove = Mathf.FloorToInt(Mathf.Abs(pos.x) / sectorSize) * ((pos.x > 0) ? 1 : -1);
         if (Mathf.Abs(pos.z) > sectorSize)
             zMove = Mathf.FloorToInt(Mathf.Abs(pos.z) / sectorSize) * ((pos.z > 0) ? 1 : -1);
         if (xMove != 0 || zMove != 0)
         {
             xSector += xMove;
             zSector += zMove;
             Vector3 offset = new Vector3(-xMove * sectorSize, 0, -zMove * sectorSize);
 
             universe.position += offset;
             Transform tmp = tempUniverse;
             List<Transform> childs = universe.OfType<Transform>().ToList();
             for (int i = 0; i < childs.Count; i++)
             {
                 childs[i].parent = tmp;
             }
             tempUniverse = universe;
             universe = tmp;
             tempUniverse.position = Vector3.zero;
             // only needed when the player is not inside the universe gameobject itself
             //player.position += offset;
         }
     }
 }


Keep in mind that all coordinates inside the universe need to be offset by

 pos +=new Vector3(xSector, 0, zSector)*sectorSize

to get the actual "absolute" position. However relative distances stay the same.

Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · Oct 18, 2015 at 11:58 AM 0
Share

$$anonymous$$eep in $$anonymous$$d that using this approach the individual objects inside the universe still have huge errors at large distances from the origin. You don't see them since the origin is always close to the player, but for example if you have two cubes next to each other so the touch perfectly. If those are "moved" far away and come back they are most likely offset to each other by a slight amount.

One solution for that could be to use actual "sector" gameobject. So all objects are childs of the sector they're in. Sector gameobject would be created on demand. All objects would be relative to their parent sector. The local coordinates should stay correct. However the sector position can still be "corrupted" by the floating point error at large distances. However those can simply be corrected since a sector location is always a multiple of the sector size.

Also keep in $$anonymous$$d that physics is calculated in worldspace. So moving physics objects at a a far distance won't work out. There are solutions to that as well, by placing sectors which need physics updates also near the origin but temporarily put them on a seperate layer so it's not rendered by the camera. However this quickly becomes a mess when you think about the housekeeping of all offsets and relations between objects and sectors.

It all depends on what you actually need. Simple planetary gravity can be calculated manually with doubles.

avatar image captainkrisu · Oct 18, 2015 at 02:17 PM 0
Share

This actually works, the sector changed and everything worked, did not notice any transition weirdness.

I could check if player is in certain Sector, and then enable physics and events there. Thank you for the help, learned something new.

I have to look at celestial orbiting script now, it does not seem to take the new positions in, and makes the planet remain at same position.

avatar image Honour-Demon · Aug 06, 2017 at 08:18 PM 0
Share
           Vector3 offset = new Vector3(-x$$anonymous$$ove * sectorSize, 0, -z$$anonymous$$ove * sectorSize);

@Bunny83 . Wount it be better to do this ins$$anonymous$$d:?

  public float sectorSize = 500f;
 ....
 ....
  Vector3 offset = new Vector3(-x$$anonymous$$ove * (sectorSize*2), 0, -z$$anonymous$$ove * (sectorSize*2));

this way you are representing 1 sector ins$$anonymous$$d of 8 at a time around VectorX.zero.

$$anonymous$$y solar manager is pretty advance at the moment and just wonderring if your method is more practical in the long run.

Please note Im converting global possition from a double vector3 data set.

avatar image Bunny83 Honour-Demon · Aug 07, 2017 at 02:26 AM 0
Share

I'm not sure what you mean by "8 sectors"? This solution currently uses a "flat" universe and only divides into sections on the x and z axis but not on y.

The point of my code is when the player moves more than 1000 units from the scene origin he will be translated to the origin on that axis. This has the advantage that the player can now move in both directions another 1000 units before a new shift happens.

Your solution has the problem that if the player goes beyond "+500" you translate him to -500. This would work when the player continues moving in the same direction. However if the player just moves around such a border you would constantly shift left and right.

so if the player is at x=501 shift left so he's at "-499". But when he does a tiny step back to "-501" you would need to immediately shift back so he's at "+499".

In my case when the player reaches 1000 on x he is moved to "0". However moving backwards is not a problem because the player is actually at the center.

So my implementation prevents frequent universe shifts when the player is close to a section border.

Note that this is not ment to deter$$anonymous$$e in which logical sector an object or the player is. It's just a way to shift the world in a way the player is always close to the center. Imagine at no shift (universe pos [0, 0] ) the player is located at (245, 0, 800). When the universe is shifted to lets say [1, 0] the same player pos would be (-755, 0, 800). At a shift of [2, 0] the same position would be (-1755, 0, 800). However since the absolute value of "-1755" is larger than 1000 the universe would shift back to [1,0]

In electronics such a behaviour is called a Schmitt trigger.

avatar image Bunny83 Bunny83 · Aug 07, 2017 at 02:43 AM 1
Share

Just to make that clear: If you want to deter$$anonymous$$e the logical sector the player is in you use the current world shift and adjust it when the local player position has a negative number. So sector (0,0) would start at the absolute position (0,0,0) and end at (1000, 0, 1000). That means at a world shift of [1, 0] and a player position of (-200, 0, 350) the actual sector is (0,0) and the player position inside the sector is (800, 0, 350)

So to get the sector of the player you would do

 int pSectorX = xSector - ((player.position.x<0)?1:0);
 int pSectorZ = zSector - ((player.position.z<0)?1:0);

This will always give you the sector the player is in where the player has always positibe local coordinates. The player sector relative coordinates can be deter$$anonymous$$es pretty much the same way:

 var pos = player.position;
 pos.x = (pos.x < 0)?sectorSize+pos.x:pos.x;
 pos.z = (pos.z < 0)?sectorSize+pos.z:pos.z;

Or if the tenary operator looks confusing:

 var pos = player.position;
 if (pos.x < 0)
     pos.x += sectorSize;
 if (pos.z < 0)
     pos.z += sectorSize;
Show more comments
avatar image
0

Answer by DireDoesGames · Oct 18, 2015 at 09:13 AM

Simpler Question?

Please explain what you are trying to do.

Moving the Universe

If I think I understand from the title why don't you just add a controller to the GameObject "Universe"

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image captainkrisu · Oct 18, 2015 at 10:31 AM 0
Share

Everytime I try to ask something it goes too complex..

Ok, I'm trying to move the Universe back, when the player moves forwards, keeping player in middle of the scene all the time. The Futurama thing.

Now, the Universe controller, moves the universe backward when the player moves forward, and moves it forward when player moves backward. How do I get where the player is going? The rotation thing.

avatar image
0

Answer by meat5000 · Oct 18, 2015 at 12:44 PM

Use the "Serious Sam" approach.

Simulate distance by keeping position the same and modifying scale.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

39 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

2D endless scrolling game - Which method is best for moving objects without lags? 2 Answers

How to make my ball not moving on a curved platform? 2 Answers

How can I collect playerprefs values? 0 Answers

Changing GameObject value before instantiating, no error but not working :/ 2 Answers

Why my animation doesn't load from blender? 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges