2016-03-09 8 views
0

Я новичок в единстве и пытаюсь понять, как работает код, но у меня проблема с моим простым проектом.Поворот объекта вокруг родительского объекта в Unity

У меня есть звезда и планета. Планета является потомком звезды, как так:

Star¬ 
    Planet 

Я добавил # сценарий компонент C к Планете, который предназначен, чтобы сделать его вращаться вокруг звезды. Но когда я нажимаю игру, планета не движется.

Это мой сценарий:

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); 
    } 
} 

Я не уверен, что моя ошибка есть. И я надеюсь, что кто-то может помочь.

Боковой вопрос, учитывая, что я хочу, чтобы в конечном итоге было более одной планеты, эффективно ли иметь сценарий компонента для каждой отдельной планеты, чтобы вращаться или существует более автоматический способ сделать это, например, перебирать все планеты в один идет?

Unit Версия 5.3.2f1

+0

просто поверните звезду ничего не делайте с дочерью планеты. он будет двигаться. , если вы хотите, чтобы звезда была неподвижной ... Просто у вас есть невидимый маркер, называемый «CenterOfTheSolarSystem», и сделайте планету ребенком этого. то просто поверните CenterOfTheSolarSystem, и планета будет хорошо оправляться. относительно Солнца, просто не делайте это дочерним элементом CenterOfTheSolarSystem, если вы хотите, чтобы он не вращался. вот и все, что с ним связано – Fattie

+0

Это полезно только для идеальных кругов, далеких от реалистической орбиты вокруг звезды – WDUK

+0

в масштабе экрана компьютера планетарная орбита точно круглая. как я уже объяснил вам, если вы также хотите, чтобы он входил и выходил (чтобы показать нереалистично преувеличенное эллиптическое движение в этом масштабе) просто добавьте для этого другое преобразование. или, конечно, просто вычислить положение и сделать это кинематически, не используя встроенные кватернионы единства. – Fattie

ответ

4

Вы должны учитывать колебания. Независимо от того, используете ли вы грех или cos, на самом деле это не имеет никакого значения. Вы получите ту же форму, но один будет начинаться с 0 как sin (0) = 0, а другой начинается с 1, поскольку cos (0) = 1.

Одна из приятных особенностей sin и cos заключается в том, что результат и зажаты между -1 и 1. Мы можем получить переменную, которая будет постоянно переходить от 1 до -1 и обратно в 1 и так далее.

Следующая полностью основан на базовой тригонометрии и unit circle

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

это основано на уравнении тригов:

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

2-* PI * K часть укоротить до Time.time, результат тот же, вам понадобятся только те, которые необходимы для дополнительной точности, если вы должны воспроизвести реальную ситуацию.

Другой случай, если вы хотите использовать полное уравнение, если вам нужно контролировать время, необходимое для революции:

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

Это займет 1 сек, чтобы сделать полный оборот.

Когда вы используете Cos для одного, вы должны использовать Sin для другого или ваш объект не будет вращаться вокруг родителя.

Вы можете добавить расстояние для распространения на планете, кроме звезды:

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); 
} 

Все вращающиеся детали будут вращаться с той же частотой 1, так что вы должны быть в состоянии предоставить различные частоты для каждой планеты:

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); 
} 

Если вы даете разные частоты х и z внутри одного и того же объекта, ребенок не будет вращаться полностью вокруг, но будет иметь форму подковы.Частоту можно было бы ассимилировать до скорости, поскольку она будет определять, как быстро выполняется один полный оборот.

Вы можете полностью контролировать период (это математический термин для скорости), период - это время между двумя пиками на синусоидальном (движение может быть сплющено до синусоидального, два фактически, x и z). Соотношение между частотой и периодом составляет

frequency = 1/period; 

Таким образом, чем больше частота, тем короче период. Если вы хотите, чтобы ваша революция принимала 2сек => частота = 1/2 => 0,5. Если вам нужно 2 минуты, частота всегда в секундах, поэтому 120сек => частота = 1/120 = 0,0083f;

Вся ваша планета будет вращаться в одном и том же положении вокруг звезды, то есть все они будут начинаться слева или справа, чтобы вы могли применить фазу. Это к из исходного уравнения и не умножаются, но добавил:

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); 
} 

И если вам нужно, чтобы обеспечить эллиптическую форму (что касается большинства Astres), вы просто дать различную амплитуду для х и г:

[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); 
} 

Если вам нужно иметь много планет вокруг одной звезды, и вы хотите, чтобы планета двигаться по всем три оси. То есть, один спин «плоский», а другой вращается с поворотом, проще всего сделать планету ребенком звездного ребенка.

-Star 
    -Container 
     -Earth 
    -Container 
     -March 

Контейнеры находятся в (0,0,0), и вы можете дать каждому контейнеру различное вращение и ребенок планета будет вращаться вокруг своей собственной эллипсу вокруг звезды. Просто убедитесь, что они не сталкиваются, на карту поставлены миллиарды жизней.

+0

Спасибо за это, это займет некоторое время, чтобы переварить. Мне любопытно, хотя если бы я хотел систему, в которой вы установили время для 1 полной орбиты, скажите, что мне нужен объект, чтобы он мог занять 2 минуты, чтобы это можно было учитывать в вашем подходе? – WDUK

+0

Я бы предложил прочитать его снова, я добавил подробности по вашей проблеме. – Everts

+0

Спасибо, я испытаю это с единством и посмотрю, как это происходит! :) – WDUK

-1

public Vector3 pos, а затем перетащить звезду в инспекторе. намного проще.

+0

Что это делает? – WDUK

Смежные вопросы