简体   繁体   中英

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

I need to make the object rotate in the z axis when holding D to go up and W to go down but limit the rotation in both directions, with the code provided below i managed to make the object rotate when pressed but it does´t stop rotating when hit any of the 2 limits set with my variables.

I am new in the world of coding, hopefully you can help me to solve and understand my problem. Thank you for your time in advance.

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

}

First of all you are dealing with Quaternion . Quaternion has 4 components x , y , z and w and does not behave like you expect it here - never change or check a rotation.z value directly.

The second mistake: transform.Rotate by default does the rotation in local Space .. so checking transform.rotation is wrong anywway .. if something it should be transform.localRotation .

Then the value you actually wanted to check is the transform.localEulerAngles or eulerAngles .


A simple alternative would be to store the already rotated value and clamp on that instead:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM