Unity3D中的对象不以直角看其他对象

Posted

技术标签:

【中文标题】Unity3D中的对象不以直角看其他对象【英文标题】:Object Not Looking at Other Object at Right Angle in Unity3D 【发布时间】:2019-04-05 20:00:46 【问题描述】:

我正在开发一个塔防游戏的原型,我遇到了炮塔旋转的问题。我这样做是为了让每个炮塔都必须有一个旋转器部分,它可以水平旋转并用大炮支撑炮塔主体 strong> 垂直旋转。我为此想出了一个简单的脚本,但它似乎只适用于 rotator 而不适用于 cannon,至少不是它应该的方式。

这是脚本中的代码

void Update () 
    if (target != null) 

        Vector3 tempRotatorRotation = rotator.transform.localEulerAngles;
        rotator.transform.LookAt (target.transform);
        rotator.transform.localEulerAngles = new Vector3 (tempRotatorRotation.x, rotator.transform.localEulerAngles.y, tempRotatorRotation.z);

        Vector3 tempCannonRotation = cannon.transform.localEulerAngles;
        cannon.transform.LookAt (target.transform);
        cannon.transform.localEulerAngles = new Vector3 (cannon.transform.localEulerAngles.x, tempCannonRotation.y, tempCannonRotation.z);
    

这是结果的图片。 rotator 完美旋转,但正如您所见,cannon 出于某种原因正在向下看。 (蓝色是不动的底座。绿色是旋转器。红色是炮塔身。浅蓝色是大炮)

大炮 3D模型的起源几乎是在它的开始处设置的。 这是所选佳能的屏幕截图,显示了它的轴和变换数据

【问题讨论】:

问题中没有足够的信息来正确回答。在提供更多信息之前,它应该被搁置。 这就是所有的信息。你还需要什么? 请统一添加炮轴截图。 【参考方案1】:

forward 统一是蓝线,在您的图表中朝上。试试这个

空箱子,连接到炮塔使其旋转,确保蓝线(z 轴)朝向您的前进方向,您可以通过旋转手动执行此操作。然后将您的枪管作为该对象的子对象,并将该对象指向目标。

我不得不用搅拌机模型多次这样做,因为搅拌机使用 z 轴作为它的垂直轴,而不是它的深度轴,就像 unity 一样。

-turret_test
    -turret_test_pedestal
    -turret_test_rotater
          -turret_test_turret
               -AIM(new empty, orient the proper direction then add child)
                       -turret_test_cannon

【讨论】:

阅读我的 cmets 关于 Foggzie 的回答。这不是问题 Unity 知道大多数人使用 Blender for Unity,因此它可以补偿轴上的差异 @veran fors 真的吗?因为我的不是你用的是什么型号的fbx?就此而言,这只是一个圆柱体,为什么不使用内置的统一圆柱体并重新映射您的材料并省去麻烦。哈哈 它转动对象但不改变轴标签。这实际上更令人迷惑......【参考方案2】:

你的大炮枪管指向它的forward 方向,所以你只需要使用cannon.transform.LookAt (target.transform, cannon.transform.up);

void Update () 
    if (target != null) 

        /* rotator code here */

        // Remember which way the top of the cannon faces.
        Vector3 cannonUpDirection = cannon.transform.up;

        // point the cannon directly at the target
        cannon.transform.LookAt (target.transform, cannonUpDirection);
    

如果旋转器没有指向/高于/低于目标,那么你必须弄清楚从水平方向向上/向下旋转多少,然后将其指向与旋转器相同的方向,然后执行那:

void Update () 
    if (target != null) 

        /* rotator code here */

        // Remember which way the top of the cannon faces.
        Vector3 cannonUpDirection = cannon.transform.up;

        // point the cannon directly at the target
        cannon.transform.LookAt (target.transform, cannonUpDirection);

        // Find global direction for looking straight ahead above/below the target
        Vector3 sameYDirection  = Vector3.Scale(
                cannon.transform.forward, 
                new Vector3(1f,0f,1f)
                );

        // Convert that to local
        Vector3 sameYDirectionLocal = cannon.transform
                .InverseTransformDirection(sameYDirection);  

        // get rotation for moving from looking ahead to looking direct
        Quaternion lookTowards = Quaternion.FromToRotation(
                sameYDirectionLocal, 
                Vector3.forward
                );

        // lookTowards is a locally-vertical rotation from horizontal to the target, 
        // given some top side of the cannon. 
        // Clamp lookTowards here if you have a max rotation speed.

        // Face cannon in same direction of rotator;
        cannon.transform.rotation = Quaternion.LookRotation(
                rotator.forward, cannonUpDirection);

        // Use lookTowards to look down from that position.
        cannon.transform.rotation *= lookTowards;
    

【讨论】:

这不知怎的让事情变得更糟了。您删除的部分代码是为了使方程更精确,而不是以其他方式改变佳能的旋转。也许它也有一个不能改变的 Z 旋转,所以它必须以某种方式记住它。我显然需要在方程式中添加或更改某些内容,而不是删除。 请比“使情况更糟”更具描述性。 从偏离 ~50 度到 ~90 度 基本上不是向下看 Z+ 轴,而是向下看 Z- 轴 不是正确地沿着 Z+ 轴看,而是沿着 Z- 轴在相反方向看 180º?是否有其他代码更改大炮或其父对象的旋转?它可能会在渲染之间进一步修改。如果它偏离 180º,则大炮可能指向 back 而不是 forward。这段代码运行后在 Unity 中的大炮轴的屏幕截图会让事情更清晰。【参考方案3】:

原来 Unity 坏了,当我重新导入模型时,所有轴都发生了变化,而不是佳能在 X 轴上上下转动,现在它在 Y 轴上,而其他一切都在 Y 轴上水平旋转。

在计算中,我还必须在两个方程中加上 + 90。现在这没有任何意义,因为它显示两者都在 Y 轴上发生变化,但一个在水平旋转,另一个在垂直旋转。

if (target != null) 

    Vector3 tempRotatorRotation = rotator.transform.localEulerAngles;
    rotator.transform.LookAt (target.transform);
    rotator.transform.localEulerAngles = new Vector3 (tempRotatorRotation.x, rotator.transform.localEulerAngles.y + 90, tempRotatorRotation.z);

    Vector3 tempCanonRotation = canon.transform.localEulerAngles;
    canon.transform.LookAt (target.transform);
    canon.transform.localEulerAngles = new Vector3 (tempCanonRotation.x, canon.transform.localEulerAngles.y + 90, tempCanonRotation.z);

【讨论】:

您应该使用transform.Rotate 而不是添加到localEulerAngles。如果超过 360,这将无法正常工作。

以上是关于Unity3D中的对象不以直角看其他对象的主要内容,如果未能解决你的问题,请参考以下文章

Unity3D:如何确定游戏对象的角以便根据它定位其他游戏对象?

unity3d中如何用脚本创建对象或者类

为啥unity3d中的游戏对象不显示出来了呢,是否点到哪一项设置了?

[Unity3D] GameObject and MonoBehaviour

Unity3D动态对象优化代码分享

如何使相机跟随unity3d C#中的对象?