C# 如何围绕另一个对象将对象旋转到特定位置?(基本上绕轨道运行到指定位置)

C# 如何围绕另一个对象将对象旋转到特定位置?(基本上绕轨道运行到指定位置),c#,unity3d,rotation,C#,Unity3d,Rotation,我有一颗行星和一个月亮。月球是位于行星中心的虚拟对象(基本上为0,0,0)的子对象。月球可以绕着地球自由旋转(到地球上的任何位置)。它应该与行星保持恒定的距离 我脑子里有一个特别的点,我想让月亮旋转,尽管它需要保持直立。也就是说,月球应该始终指向相对于行星表面的“上方”。基本上,这就像一个“移动到”脚本,只有在我的情况下,月球应该围绕行星“旋转”,直到它到达我要寻找的点 以下是迄今为止我所掌握的,尽管我无法找出正确的逻辑: Vector3 targetDir = moveToPos - moon

我有一颗行星和一个月亮。月球是位于行星中心的虚拟对象(基本上为0,0,0)的子对象。月球可以绕着地球自由旋转(到地球上的任何位置)。它应该与行星保持恒定的距离

我脑子里有一个特别的点,我想让月亮旋转,尽管它需要保持直立。也就是说,月球应该始终指向相对于行星表面的“上方”。基本上,这就像一个“移动到”脚本,只有在我的情况下,月球应该围绕行星“旋转”,直到它到达我要寻找的点

以下是迄今为止我所掌握的,尽管我无法找出正确的逻辑:

Vector3 targetDir = moveToPos - moon.transform.position;

float angle = Vector3.Angle( targetDir, moon.transform.up );

dummy.transform.RotateAround (moveToPos, moon.transform.up, angle);
我想得对吗?一旦我开始工作,我想给月球提供不同的
Vector3
位置,让月球在行星表面旋转。我找过类似的东西,但找不到我要找的东西

此屏幕截图中显示的标记应该是“在此处旋转”,但我的场景基本上就是这样的:


你已经把你的月亮放在一个空的变换里,让事情变得容易多了。如果设置正确*,这意味着您不必直接操纵月球的
变换
——只需旋转容器对象,直到它朝向目标位置

*我的意思是,容器对象相对于行星位于(0,0,0),而月球仅沿z轴局部平移,因此它与容器的
transform.forward
向量对齐

如果我们将问题分解为更小的步骤,则问题更容易解决:

  • 确定容器需要面对的目标方向。我们只需从目标位置减去容器的位置即可得到该方向
  • 计算容器朝向目标方向所需的旋转。这是一个很好的位置
  • 旋转容器,直到其方向与目标方向匹配。可用于实现此目的
以下是您可以如何实施这些步骤:

Quaternion targetRotation;
Quaternion startRotation;
float progress = 1;

void SetTargetPosition(Vector3 position)
{
    // Calculating the target direction
    Vector3 targetDir = position - dummy.transform.position;

    // Calculating the target rotation for the container, based on the target direction
    targetRotation = Quaternion.LookRotation(targetDir);
    startRotation = dummy.transform.rotation;

    // Signal the rotation to start
    progress = 0;
}

void Update()
{
    if (progress < 1)
    {
        // If a rotation is occurring, increment the progress according to time
        progress += Time.deltaTime;

        // Then, use the progress to determine the container's current rotation
        dummy.transform.rotation = Quaternion.Lerp(startRotation, targetRotation, progress);
    }
}
四元数目标;
四元数起始;
浮动进度=1;
无效设置目标位置(矢量3位置)
{
//计算目标方向
Vector3 targetDir=位置-dummy.transform.position;
//基于目标方向计算容器的目标旋转
targetRotation=四元数。LookRotation(targetDir);
startRotation=dummy.transform.rotation;
//发出旋转开始的信号
进度=0;
}
无效更新()
{
如果(进度<1)
{
//如果发生旋转,则根据时间增加进度
进度+=时间增量时间;
//然后,使用进度来确定容器的当前旋转
dummy.transform.rotation=Quaternion.Lerp(起始、目标、进度);
}
}
注意:如果月亮旋转太快(它目前将在~1秒内完成旋转),只需在每一帧的
进度中添加较少的内容,例如,将其除以一个因子

只要容器位于行星的中心,月球就应该始终与行星表面保持恒定的距离,通过这种方法,月球将始终保持相对行星表面的一致“向上”方向


希望这有帮助!如果您有任何问题,请告诉我。

您已经通过将您的月亮嵌套在一个空的变换中使事情变得容易多了。如果设置正确*,这意味着您不必直接操纵月球的
变换
——只需旋转容器对象,直到它朝向目标位置

*我的意思是,容器对象相对于行星位于(0,0,0),而月球仅沿z轴局部平移,因此它与容器的
transform.forward
向量对齐

如果我们将问题分解为更小的步骤,则问题更容易解决:

  • 确定容器需要面对的目标方向。我们只需从目标位置减去容器的位置即可得到该方向
  • 计算容器朝向目标方向所需的旋转。这是一个很好的位置
  • 旋转容器,直到其方向与目标方向匹配。可用于实现此目的
以下是您可以如何实施这些步骤:

Quaternion targetRotation;
Quaternion startRotation;
float progress = 1;

void SetTargetPosition(Vector3 position)
{
    // Calculating the target direction
    Vector3 targetDir = position - dummy.transform.position;

    // Calculating the target rotation for the container, based on the target direction
    targetRotation = Quaternion.LookRotation(targetDir);
    startRotation = dummy.transform.rotation;

    // Signal the rotation to start
    progress = 0;
}

void Update()
{
    if (progress < 1)
    {
        // If a rotation is occurring, increment the progress according to time
        progress += Time.deltaTime;

        // Then, use the progress to determine the container's current rotation
        dummy.transform.rotation = Quaternion.Lerp(startRotation, targetRotation, progress);
    }
}
四元数目标;
四元数起始;
浮动进度=1;
无效设置目标位置(矢量3位置)
{
//计算目标方向
Vector3 targetDir=位置-dummy.transform.position;
//基于目标方向计算容器的目标旋转
targetRotation=四元数。LookRotation(targetDir);
startRotation=dummy.transform.rotation;
//发出旋转开始的信号
进度=0;
}
无效更新()
{
如果(进度<1)
{
//如果发生旋转,则根据时间增加进度
进度+=时间增量时间;
//然后,使用进度来确定容器的当前旋转
dummy.transform.rotation=Quaternion.Lerp(起始、目标、进度);
}
}
注意:如果月亮旋转太快(它目前将在~1秒内完成旋转),只需在每一帧的
进度中添加较少的内容,例如,将其除以一个因子

只要容器位于行星的中心,月球就应该始终与行星表面保持恒定的距离,通过这种方法,月球将始终保持相对行星表面的一致“向上”方向

希望这有帮助!如果您有任何问题,请告诉我。

您能出示屏幕吗