如何为对象的旋转设置 2 个限制?

How to set 2 limits to the rotation of an object?

当按住 D 向上和 W 向下但限制两个方向的旋转时,我需要使对象在 z 轴上旋转,使用下面提供的代码我设法使对象在按下时旋转但是当达到用我的变量设置的 2 个限制中的任何一个时,它不会停止旋转。

我是编码领域的新手,希望您能帮助我解决和理解我的问题。感谢您提前抽出时间。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GyroDiscControls : MonoBehaviour{

public GameObject AltNeedleBright;
public float MaxAltNeedleRotation = -65f;
public float MinAltNeedleRotation = 135f ;
public void update (){

if (Input.GetAxisRaw("Vertical") > 0 & 
AltNeedleBright.transform.rotation.z > MaxAltNeedleRotation)
    {
        AltNeedleBright.transform.Rotate(0f, 0f, +15f * Time.deltaTime);
    }
if (Input.GetAxisRaw("Vertical") < 0 & 
AltNeedleBright.transform.rotation.z < MinAltNeedleRotation)
    {
        AltNeedleBright.transform.Rotate(0f, 0f, -15f * Time.deltaTime);
    }

}

public GameObject AltNeedleBright;
float MaxAltNeedleRotation = 135f; //smaller than this
float MinAltNeedleRotation = -65f; // bigger than this
public void Update ()
{
    float zAxis = AltNeedleBright.transform.localRotation.eulerAngles.z;
    float input = Input.GetAxisRaw("Vertical"); //Returns -1 or 1
    if(input > 0 && WrapAngle(zAxis) < MaxAltNeedleRotation)
    {
        AltNeedleBright.transform.Rotate(0, 0, 15 * Time.deltaTime);
    }
    if(input < 0 && WrapAngle(zAxis) > MinAltNeedleRotation)
    {
        AltNeedleBright.transform.Rotate(0, 0, -15 * Time.deltaTime);
    }
}

private static float WrapAngle(float angle)
{
    angle %= 360;
    if(angle > 180)
        return angle - 360;

    return angle;
}

首先你要处理QuaternionQuaternion4 个组件 xyzw,并且这里的行为与您预期的不同- 切勿直接更改或检查 rotation.z 值。

第二个错误:transform.Rotate 默认在 local Space 中旋转 .. 所以检查 transform.rotation 无论如何都是错误的 ..如果有的话应该是 transform.localRotation.

那么您实际要检查的值是 transform.localEulerAngles or eulerAngles.


一个简单的替代方法是存储已经旋转的值并取而代之:

// Your naming is very confusing ... Min should be the smaller value
public float MaxAltNeedleRotation = 135f;
public float MinAltNeedleRotation = -65f;

private float alreadyRotated = 0;

public void update ()
{ 
    var direction = 0;

    // use && here .. you don't want to do a bitwise & on bools
    if (Input.GetAxisRaw("Vertical") > 0 && alreadyRotated < MaxAltNeedleRotation)
    {
        direction = 1;
    }
    // use else if since anyway only one of the cases can be true
    else if (Input.GetAxisRaw("Vertical") < 0 && alreadyRotated > MinAltNeedleRotation)
    {
        direction = -1;
    }

    // use the rotation and riection
    // but clamp it so it can minimum be MinAltNeedleRotation - alreadyRotated
    // and maximum MaxAltNeedleRotation - alreadyRotated
    var rotation = Mathf.Clamp(direction * 15f * Time.deltaTime, MinAltNeedleRotation - alreadyRotated, MaxAltNeedleRotation - alreadyRotated);

    if(rotation != 0)
    {
        AltNeedleBright.transform.Rotate(Vector3.forward * rotation);

        // update the alreadyRotated value
        alreadyRotated += rotation;
    }
}