【问题标题】:How to set 2 limits to the rotation of an object?如何为对象的旋转设置 2 个限制?
【发布时间】:2019-10-29 14:48:41
【问题描述】:

当按住 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);
    }

}

【问题讨论】:

标签: c# unity3d rotation limit


【解决方案1】:

首先你正在处理QuaternionQuaternion4 个组件 xyzw,并且在此处的行为不像您期望的那样 - 永远不要直接更改或检查 rotation.z 值。

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

那么您实际要检查的值是transform.localEulerAngleseulerAngles


一个简单的替代方法是存储已经旋转的值并对其进行钳制:

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

【讨论】:

    【解决方案2】:
    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;
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多