如何在 Unity C# 中检查对象是不是面向某个方向

Posted

技术标签:

【中文标题】如何在 Unity C# 中检查对象是不是面向某个方向【英文标题】:How can I check if an object is facing a certain direction in Unity C#如何在 Unity C# 中检查对象是否面向某个方向 【发布时间】:2021-06-02 22:33:04 【问题描述】:

对于 Unity 和 C# 来说还是很新的。在设置/更改对象的位置时,我通常可以找到自己的方法,但在旋转方面,四元数、欧拉角等对我来说仍然令人难以置信。

我正在尝试检查一个对象(头部)是否面向某个方向,如果它不面向该方向,则需要将其设置为该方向,具体取决于它的走向(上、下、左或右) .这是针对我目前正在开发的蛇游戏(如旧的自上而下的诺基亚游戏)。

我试图查找它,但没有一个答案是针对我正在尝试做的事情。

截至目前,这是我用于玩家输入的内容(代码的 sn-p):

private int GetAxisRaw(Axis axis)
    
        if (axis == Axis.Horizontal)
        
            bool left = Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.A);
            bool right = Input.GetKeyDown(KeyCode.RightArrow) || Input.GetKeyDown(KeyCode.D);

            if (left)
            
                snakeHeadRotation.transform.Rotate(0, 180, 0); // Keeps rotating when left is pressed
                return -1;
            
            if (right)
            
                snakeHeadRotation.transform.Rotate(0, -180, 0);
                return 1;
            

            return 0;
        

如您所见,snakeHeadRotation.transform.Rotate(0, 180, 0);例如,每次玩家按下左键时都会调用它,因此即使蛇仍在向左移动,也会转动蛇的头部。

我的逻辑是将旋转值存储在某处(可能是四元数/布尔类型)并检查该旋转值是否与设置为左的当前旋转值匹配(即 snakeHeadRotation.transform.Rotate(0, 180 , 0);) 如果是这样,不要做任何事情。如果不是,请将其设置为 snakeHeadRotation.transform.Rotate(0, 180, 0);例如。

代码看起来像(写出来):

private int GetAxisRaw(Axis axis)

    if (axis == Axis.Horizontal)
    
        bool left = Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.A);
        bool right = Input.GetKeyDown(KeyCode.RightArrow) || Input.GetKeyDown(KeyCode.D);

        if (left && rotation is not equal to snakeHeadRotation.transform.Rotate(0, 180, 0))
        
            snakeHeadRotation.transform.Rotate(0, 180, 0); 
            return -1;
        
        if (right)
        
            snakeHeadRotation.transform.Rotate(0, -180, 0);
            return 1;
        

        return 0;
    

如前所述,我对设置或存储旋转值非常陌生。我怎样才能做到这一点?这甚至是正确的方法还是有更合乎逻辑的方法?这个我自己也想不出来。。

我希望我解释得对,我通常不善于解释。

【问题讨论】:

【参考方案1】:

使用Transform.Rotate(x) 将使您的头部相对于您当前的头部方向旋转x 度数。

我想你想要的是根据你按下的箭头键设置你头部的绝对旋转。因此,即使您多次按下同一个箭头键,头部也会保持正确的方向。

为此,您可以为每个头部方向创建 4 个旋转,然后根据需要使用它们。 例如,如果你的头默认朝向forward

// create your directions
private static Quaternion forwardDirection = Quaternion.Identity;
private static Quaternion rightDirection = Quaternion.FromToRotation(Vector3.forward, Vector3.right);
private static Quaternion leftDirection = Quaternion.FromToRotation(Vector3.forward, Vector3.left);
private static Quaternion backDirection = Quaternion.FromToRotation(Vector3.forward, Vector3.back);

...

private int GetAxisRaw(Axis axis)

    ...

    if (left)
    
        // set the absolute direction of your head to the left
        snakeHeadRotation.transform.rotation = leftDirection; 
        return -1;
    
    if (right)
    
        // set the absolute direction of your head to the right
        snakeHeadRotation.transform.rotation = rightDirection;
        return 1;
    

    ...

【讨论】:

谢谢本!我选择了private static Quaternion rightDirection = Quaternion.Euler(0, 0, 0); private static Quaternion leftDirection = Quaternion.Euler(0, -180, 0); private static Quaternion upDirection = Quaternion.Euler(0, -90, 0); private static Quaternion downDirection = Quaternion.Euler(0, -270, 0);【参考方案2】:

我将为每个方向创建 4 个四元数,并根据按下的键设置旋转(就像hear.rotation = leftQ)。这是最简单的方法。

我目前不在我的电脑旁,但我会尽力寻找其他解决方案

【讨论】:

感谢汤姆阅读我的问题和回复。这就是我的想法,但是我将如何存储该值,例如 Quaternion snakeLeft = snakeHeadRotation.transform.Rotate(0, 180, 0); ?慢慢来,当你回到你的电脑时告诉我:) 如果你只旋转 90 度,你可以对向量做同样的事情。 关闭,但更像Quaternion snakeLeft = new Quaternion(0, 180, 0, 1)。这些值当然与您的具体情况有关,因为它是自上而下的。左边不是-90,右边是90吗? (除非你从侧面看......?)【参考方案3】:

您可以将当前旋转与 4 个方向的已知旋转进行比较。 但不要那样做,这是不好的做法,原因如下:

如果以后你想添加动画怎么办,例如头在 0.5 秒内转动,而不是立即转动? 仅比较 4 个浮点数以检查 4 个可能方向之一是低效的。

改为创建一个枚举:

public enum Direction

    Up,
    Down,
    Left,
    Right

将这种类型的成员添加到您的行为中,以跟踪您的蛇头的去向。 比如:

    Direction direction;
...
private int GetAxisRaw(Axis axis)

    switch (direction)
    
        case Direction.Up:
            if (left && !right)
               direction = Direction.Left;
               ... turn snake left ...
            else if (right && !left)
               direction = Direction.Right;
               ... turn snake right ...
            // ignore inputs for up or down if going up
        break;
        ... repeat for the other directions and possible inputs ...
    
    ...

【讨论】:

以上是关于如何在 Unity C# 中检查对象是不是面向某个方向的主要内容,如果未能解决你的问题,请参考以下文章

Unity 2D C#如何在点击时制作面向对象的坐标

100个 Unity实用技能| C# 检查字典中是否存在某个Key的几种方法

100个 Unity实用技能| C# 检查字典中是否存在某个Key的几种方法

100个 Unity实用技能| C# 检查字典中是否存在某个Key的几种方法

100个 Unity实用技能☀️ | C# 检查字典中是否存在某个Key的几种方法

如何检查游戏对象是不是处于活动状态