Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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
0
Question by LeftRight92 · Mar 15, 2015 at 08:00 PM · transformrounding

Advice on reducing rounding errors with transform

Hi,

I've recently started a project that involves orbiting planets suns, moons around planets etc. However, I've run into a problem (that I assume is rounding/calculation error) that causes orbiting bodies to very slowly increase the distance between itself and the body it is orbiting.

Below is the code that all orbiting bodies use. The call stack is started from a simple base case in a separate script that calls CalcOrbit() on anything registered to it once per Update().

 public class Orbit : MonoBehaviour, IOrbit {
 
     public static float artificialBias = 500f;
 
     public GameObject influence;
     public float orbitalSpeed, mass, rotationSpeed, distance; //rotationSpeed and distance are public for debugging (inspector) purposes
 
     private float orbitalAngle;
     private ArrayList objectsInInfluence;
     private Vector3 deltaPosition;
 
     void Awake(){
         objectsInInfluence = new ArrayList();
     }
 
     // Use this for initialization
     void Start () {
         influence.GetComponent<IOrbit>().Register(gameObject);
     }
     
     // Update is called once per frame
     void Update () {
 
     }
 
     public void Register(GameObject toRegister){
         objectsInInfluence.Add(toRegister);
     }
 
     public void CalcOrbit(Vector3 influencePosition, float massOfInfluence, Vector3 influenceDeltaPosition){
         //Orbit Planet
         //-Speed
         distance = Vector3.Distance(transform.position, influencePosition);
         if(orbitalSpeed == 0) orbitalSpeed = Mathf.Sqrt(massOfInfluence/Vector3.Distance(transform.position, influencePosition)) * artificialBias;
         
         //-Angle
         if(transform.position.x > influencePosition.x){
             orbitalAngle = 360 - Vector3.Angle(Vector3.forward, influencePosition - transform.position) - 90;
         }else{
             orbitalAngle = Vector3.Angle(Vector3.forward, influencePosition - transform.position) - 90;
         }
         if(orbitalAngle < 0) orbitalAngle += 360;
         
         //-Resultant Vector
         deltaPosition.x = Mathf.Sin (orbitalAngle * Mathf.Deg2Rad);
         deltaPosition.z = Mathf.Cos (orbitalAngle * Mathf.Deg2Rad);
         deltaPosition += influenceDeltaPosition;
 
         //Perform Translation
         transform.position += deltaPosition * Time.deltaTime;
 
         //Rotate Planet
         transform.Rotate (Vector3.up * rotationSpeed * Time.deltaTime);
 
         //Do for Children
         foreach(GameObject obj in objectsInInfluence){
             obj.GetComponent<Orbit>().CalcOrbit(transform.position, mass, deltaPosition);
         }
     }
 }

I have not made use of Transform.RotateAround() as it causes suborbitals (moons and lower) to behave erratically.

One option that has occurred to me is to create a parent transform for the orbital as a child of and at the orbited body and rotate that, however, I'd rather avoid that unless no other option makes itself apparent. eg

 Sun
     Graphics & Other Bits
     Planet1 Centre of Orbit
         Planet1
             Graphics & Other Bits
             Moon1 Centre of Orbit
                 Moon1
                     Graphics & Other Bits
                     ...etc
     Planet2 Centre of Orbit
         ...etc


So, ultimately, my question is how can I reduce rounding and calculation errors to prevent my orbitals drifting outward on their orbits?

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

1 Reply

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

Answer by dethtoll · Mar 16, 2015 at 08:26 AM

I wouldn't call this 'rounding errors'. The approach you're using has general stability problems.

You are effectively applying forces inside Update(). If you want to use a force-based approach to update your orbits, then you should apply them in FixedUpdate(). Further, you might as well use Unity's physics engine at that point.

But I wouldn't recommend it. Since you're dealing with nested transforms, the simulation will drift eventually.

If the planets have stable orbits, you're better off computing the local position of each planet (i.e. relative to its parent) directly. In other words, don't use velocities (values multipled by delta time and then added to position). Instead, compute the location of the elliptical (or circular in your case) orbit and then transform into world space.

You should really consider using the transform hierarchy you're trying to resist (nested transforms). If you're just dealing with stable orbits, then I would go as far as calling that the 'right' thing to do.

If you're resisting that approach because you find it confusing to deal with local transforms, then treat this as a learning exercise. In graphics and games, understanding transform hierarchies is critical.

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 LeftRight92 · Mar 16, 2015 at 01:52 PM 0
Share

I don't really see how moving this into FixedUpdate would have much of an impact, as the only thing you're changing is the update interval.

Similar to the above, I don't see how calculating in local and converting to world would have any difference (as a matter of fact, during testing my sun has been at origin and therefore world == local). I can't see how you would calculate the next local position without making use of velocities, further explanation would be appreciated.

The reason I'm resistant to using Unity's nesting is it because it struck me as an inappropriate use of the tool initially, however the more I think about it the more it makes sense. I have no problem with working in local space.

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

21 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

Related Questions

Rounding transform.position? With parents 0 Answers

Rounding not working? 2 Answers

Can't jump in diagonal 1 Answer

I need help ! = Tranform.position ? 1 Answer

"Lerp" back to original position after animation. 0 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