简体   繁体   中英

Rotate object around parent object in Unity

I am new to unity and am trying to understand how the code works but am having a problem with my simple project.

I have a Star and a Planet. The planet is a child of the Star like so:

Star¬
   Planet

I added a component C# script to Planet that is meant to make it rotate around the Star. But when i press play the planet is not moving.

This is my script:

using UnityEngine;
using System.Collections;

public class Orbit : MonoBehaviour {

    public float rotateSpeed = 5.0f;
    public float orbitSpeed  = 1.0f;

    private Vector3 pos;

    void Start(){
        //get parent object position
        pos = transform.root.gameOject;
    }

    void Update() {
        // planet to spin on it's own axis
        transform.Rotate (transform.up * rotateSpeed * Time.deltaTime);

        // planet to travel along a path that rotates around the sun
        transform.RotateAround (pos, Vector3.up, orbitSpeed * Time.deltaTime);
    }
}

I am not sure what my mistake is. And am hoping some one can help.

Side question, given i want to eventually have more than one planet, is it efficient to have a component script for every individual planet to rotate or is there a more automative way to do it such as iterate through all the planets in one go?

Unit Version 5.3.2f1

You should consider oscillation. Whether you use sin or cos does not really matter somehow. You will get the same shape but one will start at 0 as sin(0) = 0 and the other starts at 1 as cos(0) = 1.

One nice feature of sin and cos is that the result is lerping and clamped between -1 and 1. We can get a variable that will constantly go from 1 to -1 and back to 1 and so on.

The following is entirely based on basic trigonometry and unit circle

void Update () 
{
        transform.localPosition= new Vector3(Mathf.Cos (Time.time ),0,Mathf.Sin (Time.time));
}

this is based on the trig equation:

x = cos(2 * pi * k + t)
y = sin(2 * pi * k + t)

The 2 * PI * k part is shorten to Time.time, result is the same, you would only need those for extra precision if you were to reproduce a real situation.

Other case you want to use the full equation is if you need to control the time it takes for a revolution:

 private float twoPi = Mathf.PI * 2f;
 void Update () 
{
        transform.localPosition= new Vector3(Mathf.Cos (twoPi * Time.time ),0,Mathf.Sin (twoPi * Time.time));
}

This will take 1sec to do the full revolution.

When you use Cos for one, you have to use Sin for the other or your object will not spin around the parent.

You can add distance to spread the planet apart from the star:

private float twoPi = Mathf.PI * 2f;
[SerializeField]private float amplitude = 2.0f;
void Update()
{
    float x = amplitude * Mathf.Cos (twoPi * Time.time );
    float z = amplitude * Mathf.Sin (twoPi * Time.time );
    transform.localPosition= new Vector3(x,0,z);
}

All spinning items will rotate at the same frequency of 1 so you should be able to provide different frequencies to each planet:

private float twoPi = Mathf.PI * 2f;
[SerializeField]private float amplitude = 2.0f;
[SerializeField]private float frequency = 2.0f;
void Update()
{
    float x = amplitude * Mathf.Cos (twoPi * Time.time * frequency);
    float z = amplitude * Mathf.Sin (twoPi * Time.time * frequency);
    transform.localPosition= new Vector3(x,0,z);
}

if you give different frequencies to x and z within the same object, the child will not spin entirely around but will have a horseshoe shape. Frequency could be assimilated to speed as it will define how fast one full revolution is performed.

You can then fully control the period (this is the math term for speed), a period is the time between two peaks on the sinusoidal (the movement can be flattened to a sinusoidal, two actually, x and z). The relation between frequency and period is

frequency = 1 / period;

So the greater the frequency, the shorter the period. If you want your revolution to take 2sec => frequency = 1 / 2 => 0.5. If you need 2 minutes, frequency is always in seconds so 120sec => frequency = 1 / 120 = 0.0083f;

All your planet will rotate at the same position around the star, that is they will all start from left or right so you can apply a phase. This is the k from the initial equation and it is not multiplied but added:

private float twoPi = Mathf.PI * 2f;
[SerializeField] private float amplitude = 2.0f;
[SerializeField] private float periodInSec = 120;
private float frequency = 2.0f;
[SerializeField] private float phase = 0.5f;

void Start()
{
    frequency = 1 / periodInSec;
}
void Update()
{
    float x = amplitude * Mathf.Cos (twoPi * Time.time * frequency + phase);
    float z = amplitude * Mathf.Sin (twoPi * Time.time * frequency + phase);
    transform.localPosition= new Vector3(x,0,z);
}

And if you need to provide an elliptic shape (which is the case of most astres), you simply give a different amplitude to x and z:

[SerializeField]private float amplitudeX = 2.0f;
[SerializeField]private float amplitudeZ = 3.0f;
[SerializeField] private float periodInSec = 120;
private float frequency = 2.0f;
[SerializeField] private float phase = 0.5f;
void Start()
{
    frequency = 1 / periodInSec;
}
void Update()
{
    float x = amplitudeX * Mathf.Cos (twoPi * Time.time * frequency + phase);
    float z = amplitudeZ * Mathf.Sin (twoPi * Time.time * frequency + phase);
    transform.localPosition= new Vector3(x,0,z);
}

If you need to have many planets around one star and you want the planet to move on all three axis. That is, one spin "flat" while another one spin with a rotation, the easiest is to make the planet a child of a star child.

-Star
    -Container
        -Earth
    -Container
        -March

The containers are at (0,0,0) and you can give each container a different rotation and the child planet will rotate on its own ellipse around the star. Just make sure they don't collide, billions of lives at stake.

public Vector3 pos and then Drag the Star in the Inspector. much easier.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM