Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How to rotate an object around another object rotating?

Discussion in 'Scripting' started by alvaromorales_unity, Aug 16, 2019.

  1. alvaromorales_unity

    alvaromorales_unity

    Joined:
    Aug 14, 2019
    Posts:
    9
    I want to rotate the Moon around the Earth at the same time the Earth is rotating around the Sun.
    I have tried with this:
    Earth:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Tierra : MonoBehaviour
    6. {
    7.     public GameObject sol;
    8.     public int speed;
    9.     private Vector3 axis = Vector3.up;
    10.     void Update()
    11.     {
    12.         transform.RotateAround(sol.transform.position, axis, speed * Time.deltaTime);
    13.     }
    14. }
    Moon:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Luna : MonoBehaviour
    6. {
    7.     public GameObject tierra;
    8.     public int speed;
    9.     private Vector3 axis = Vector3.up;
    10.        // Update is called once per frame
    11.     void Update()
    12.     {
    13.         transform.RotateAround(tierra.transform.position, axis, speed * Time.deltaTime);
    14.     }
    15. }
    But the moon makes weird movements that doesn't make sense how can i make it right.
     
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,773
    My guess is that, while each movement in itself is fine, the Earth is moving on its own (without bring the Moon with it) when it rotates are the sun. Presumably this makes the Moon spiral inward or outward as it goes?
    You can try making the Moon a child of the Earth; then Earth would move the Moon when it moves.

    Fixing it any better than that would get very complicated quickly.
     
  3. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    You could consider changing your approach so the moon you have now is a child object of a parent which is placed at the same position as the earth, and which updates its position to the current position of the earth in LateUpdate. Then you just rotate the moon's parent object without even needing to use RotateAround. Do the same thing with the earth to the sun, making sure you update the position of the earth before the moon.
     
    alexeu likes this.
  4. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,605
    First and foremost: your two classes do basically the same. Unless they are going to do different things in the future, you should use a single script and call it "RotateAround" or something, which gets a GameObject to rotate around and a speed at which it is supposed to do so.

    Other than that, it's as StarManta said: make the moon a child object of earth and your problem is gone (tested it for you with some cubes). Here is a bit more detailed explanation for what's going wrong, so you understand it and may be able to prevent issues like these in the future:
    When earth rotates around the sun, that obviously changes the position of earth. RotateAround() takes a position to rotate around, which in case of the moon is the constantly changing position of earth. Since the earth moves away from the moon, the distance between the two increases, which in turn changes the size of the circle the moon is supposed to orbit around the earth, resulting in this "weird movement" you see, as if it was dragged behind by some rope, or spirals outward or inward, based on the relative rotation speeds.
    In order to fix this, you need to apply the same movement that happens to earth to the moon as well, before the moon itself is rotated around the earth. As it happens, that's exactly what you get by simply adding the moon as a child object to earth.
     
  5. Errorsatz

    Errorsatz

    Joined:
    Aug 8, 2012
    Posts:
    555
    The general setup I would use is to let the Transform hierarchy do the work:

    SunLocation (fixed, no movement or rotation)
    --Sun (local pos = 0,0,0; rotates at ... I don't remember if/how fast the sun itself spins)
    --EarthOrbit (local pos = 0,0,0; rotates at year speed)
    ----Earth (local pos = ED,0,0; rotates at day speed; ED = distance from sun to earth)
    ----MoonOrbit (local pos = ED,0,0; rotates at moon orbit speed)
    ------Moon (local pos = MD,0,0; doesn't rotate because it's tidally locked; MD = distance from moon to earth)

    Of course to be more precise, the center of rotation isn't the center of the Sun/Earth, but rather the center of gravity between the two bodies. Although for the Sun especially the difference won't really be visible.
     
    Last edited: Aug 17, 2019
  6. alexeu

    alexeu

    Joined:
    Jan 24, 2016
    Posts:
    257
    alvaromorales_unity i can't say why your scripts doesn't work. It works here in the 2 enumerated cases :
    Moon as child of earth & moon as independant object..

    Try this : In the inspector, give the 3 objects the same value on the X and Y axis.

    Note that if you do nothing else you can directly use Transform instead of GameObject. but its a detail...



    Code (CSharp):
    1. using UnityEngine;
    2.  
    3.  
    4. public class OnOrbit : MonoBehaviour // Attached to Earth
    5. {
    6.     public Transform target; //Sun's Transform
    7.     public float rotationSpeed = 20f;
    8.  
    9.     void Update()
    10.     {
    11.         transform.RotateAround(target.position, -Vector3.up, rotationSpeed * Time.deltaTime);
    12.     }
    13. }
    14.  
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class SatOrbite : MonoBehaviour // Attached to Moon
    4. {
    5.     public Transform target;// Earth's Transform
    6.     public float rotationSpeed = 20;
    7.  
    8.     void Update()
    9.     {
    10.         transform.RotateAround(target.position, Vector3.up, rotationSpeed * Time.deltaTime);
    11.     }
    12. }
    13.  
    Edit:
    Joe-Censored suggestion also works like a charm (Not surprised...)


     
    Last edited: Aug 17, 2019
  7. anhaltvr

    anhaltvr

    Joined:
    Nov 10, 2019
    Posts:
    1
    just increase the speed of the moon. relative to speed of the earth.