在Unity中围绕父对象旋转对象

时间:2016-03-09 03:15:33

标签: c# unity3d

我是团结的新手,我正在努力理解代码是如何工作的,但我的简单项目遇到了问题。

我有一个星星和一个星球。这星球就像是星星的孩子一样:

Star¬
   Planet

我向Planet添加了一个组件C#脚本,旨在让它围绕Star旋转。但是当我按下游戏时,这个星球并没有移动。

这是我的剧本:

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

我不确定我的错误是什么。我希望有人可以提供帮助。

附带问题,鉴于我想最终拥有一个以上的行星,为每个行星旋转都有一个组件脚本是否有效,或者是否有一种更自动化的方法来实现它,例如在一个行星中迭代所有行星去吗?

单位版本5.3.2f1

2 个答案:

答案 0 :(得分: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));
}

这是基于trig方程:

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

如果你给同一个物体中的x和z提供不同的频率,孩子将不会完全旋转,但会有马蹄形状。频率可以与速度同化,因为它将定义一次完整旋转的执行速度。

然后您可以完全控制周期(这是速度的数学术语),周期是正弦曲线上两个峰值之间的时间(运动可以展平为正弦曲线,实际上是两个,x和z)。频率和周期之间的关系是

frequency = 1 / period;

因此频率越高,周期越短。如果你想要你的革命需要2秒=>频率= 1/2 => 0.5。如果你需要2分钟,频率总是以秒为单位,所以120秒=>频率= 1/120 = 0.0083f;

你的星球将在恒星周围的相同位置旋转,也就是说它们都将从左侧或右侧开始,这样您就可以应用一个相位。这是初始等式中的k,它没有乘以但是加上:

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

如果您需要提供椭圆形状(大多数情况下都是如此),您只需为x和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);
}

如果你需要在一颗恒星周围有许多行星,你希望行星在所有三个轴上移动。也就是说,一个旋转“平坦”,而另一个旋转旋转,最简单的是让这个星球成为一个明星孩子的孩子。

-Star
    -Container
        -Earth
    -Container
        -March

容器位于(0,0,0)并且您可以为每个容器提供不同的旋转,并且子行星将围绕恒星在其自己的椭圆上旋转。只要确保它们不会碰撞,数十亿人的生命受到威胁。

答案 1 :(得分:-1)

public Vector3 pos然后在检查器中拖动星星。 更容易。