Как установить 2 ограничения на вращение объекта? - PullRequest
0 голосов
/ 15 июня 2019

Мне нужно заставить объект вращаться по оси z, удерживая D, чтобы подняться, и W, чтобы опустить, но ограничить вращение в обоих направлениях, с помощью приведенного ниже кода, мне удалось заставить объект вращаться при нажатии, но это происходит Не прекращайте вращаться при достижении любого из 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);
    }

}

Ответы [ 2 ]

2 голосов
/ 15 июня 2019

Прежде всего вы имеете дело с Quaternion.Quaternion имеет 4 компонентов x, y, z и w и не ведет себя так, как вы этого ожидаете - никогда не изменяйте и не проверяйте значение rotation.z напрямую.

Вторая ошибка: transform.Rotate по умолчанию выполняет вращение в локальное пространство .. поэтому проверка transform.rotation в любом случае неверна .. если что-то должно быть transform.localRotation.

Тогда значение, которое вы на самом деле хотели проверить, это transform.localEulerAngles или 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;
    }
}
1 голос
/ 15 июня 2019
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;
}
...