2
\$\begingroup\$

I am developing a solar system animation in Unity3D. Planets rotates around sun. But ı have an issue simulating satellites like Moon. Moon should be rotating around world normally and moon should be rotating around World. Since World is rotating around Sun , i am having trouble about calculating true rotation for moon. I don't want to use rotateAround() since it is deprecated. I need to make this done using Rotate().

this is my planetScript

public class planetScript : MonoBehaviour {

    public GameObject target;//target is Sun for World, World for Moon etc

    public float rotateRatioCenter;//1 degree for World
    private float rotateSpeedTarget;

    public float rotateRatioAround;//365 for World
    private float rotateSpeedAround;

    public float counter = 0;
    void Start () {
    }

    // Update is called once per frame
    void Update () {

     rotateSpeedTarget = rotateRatioCenter * gameMasterScript.rotateAroundCenterRatio;//  rotateRatioCenter * 1 , 
     rotateSpeedAround = rotateSpeedTarget * rotateRatioAround;
     float yRotate = transform.eulerAngles.y;

     transform.Rotate(Vector3.up, rotateSpeedAround);

     rotateAroundTarget();
    }

    void rotateAroundTarget()//this is the method should be optimized
    {
        Quaternion quaRot = Quaternion.Euler(0, rotateSpeedTarget, 0);
        transform.position = quaRot * (transform.position - target.transform.position) + target.transform.position;
    }
}

gameView enter image description here

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

The easiest way to have one GameObject "orbit" around another (without Transform.RotateAround() would be to utilize the hierarchy. Each planet can have an empty GameObject as its parent that's a child of its target like so

> Sun
   > Rotator (empty GameObject)
      > Planet
         > Rotator
            > Moon
   > Rotator
      > Planet
   > Rotator
      > Planet

Here's how you can accomplish that with your script:

public class planetScript : MonoBehaviour {
    public GameObject target;

    void Start() {
        m_rotator = new GameObject("rotator");
        m_rotator.transform.parent = target.transform;
        m_rotator.transform.localPosition = Vector3.zero; // Might not need this

        this.gameObject.transform.parent = m_rotator.transform;
        this.gameObject.transform.localPosition = new Vector3(radius, 0, 0);
    }

    void Update() {
        // Rotate m_rotator
        m_rotator.Rotate(Vector3.up * Time.deltaTime);
    }

    private GameObject m_rotator;
}

Also, as a note, this makes sense if you're using Transform.Rotate() but Transform.RotateAround() is not deprecated and you're free to use it. Not sure where you got that info from but it's supported in the latest release of Unity.

\$\endgroup\$
  • \$\begingroup\$ Thank you. I tried this. World->rotater->moon. Since World is rotating around sun this situation makes rotater rotate unexpected. If i had 2 level hierarchy this would probably work. I had the same issue with my script .I solved the issue assigning satellite object to my planet script. But your idea looks very practical and logical. \$\endgroup\$ – Burak Karasoy Dec 5 '15 at 0:44

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.