Clamp RotateAround не работает на камере в Unity3D

#android #unity3d #camera #clamp

#Android #unity3d #камера #зажим

Вопрос:

Мой код не работает, я пытаюсь зажать камеру, но она не работает. Он мгновенно переключается на 45. Как я могу зажать камеру?

Вот мой код.

 using UnityEngine;
using System.Collections;

 public class MoveCamera : MonoBehaviour 
 {

     public float sensitivity = 4.0f;        
     private Vector3 mouseOrigin;
     private bool isRotating;

     private float minX = -45.0f;
     private float maxX = 45.0f;

     private float minY = -10.0f;
     private float maxY = 10.0f;

     float rotationY = 0.0f;
     float rotationX = 0.0f;

     void Start()
     {

     }

     void Update () 
     {

         if (Input.GetMouseButtonDown (0)) {

             mouseOrigin = Input.mousePosition;
             isRotating = true;
         }

         if (!Input.GetMouseButton (0))
             isRotating = false;

         if (isRotating) {

             Vector3 pos = Camera.main.ScreenToViewportPoint (Input.mousePosition - mouseOrigin);
             transform.RotateAround (transform.position, transform.right, -pos.y * sensitivity);
             transform.RotateAround (transform.position, Vector3.up, pos.x * sensitivity);

             rotationY = Mathf.Clamp (transform.localEulerAngles.y, minY, maxY);
             rotationX = Mathf.Clamp (transform.localEulerAngles.x, minX, maxX);
             transform.localEulerAngles = new Vector3 (-rotationY, rotationX, 0);
         }
     }
 }
  

Комментарии:

1. transform.RotateAround фактически поворачивает преобразование, поэтому при каждом обновлении вы поворачиваете, а затем снова поворачиваете с помощью transform.localEulerAngles. Что вы хотите, чтобы камера делала?

2. я хочу, чтобы камера фиксировала ось Y на 10 и -10, а ось X — на 45 и -45

3. если я удалю последние 3 строки, они будут вращаться так, как я хотел. но я хочу зажать, поэтому я добавил последние 3 строки, но они не зажимаются.

4. Хорошо, поэтому вместо того, чтобы использовать transform.RotateAround, сначала рассчитайте свои углы, закрепите их, а затем используйте transform.rotation = что угодно. Существуют различные методы, которые вы можете использовать в классах Quaternion и Vector3, чтобы помочь вам с углами

5. На самом деле, я новичок в этом, можете ли вы исправить код и опубликовать в качестве ответа? Я приму ответ. Кстати, спасибо за быстрый ответ 🙂 @Absinthe

Ответ №1:

Вот пример ограничения поворота оси Y, вы можете адаптировать его и для X. Вы не указали, на чем должен основываться лимит, поэтому здесь он основан на вращении другого объекта (общедоступной цели преобразования), это может быть ваш плеер или что-то еще.

 public float sensitivity = 16.0f;
public Transform target;

void Update()
{

    if (Input.GetMouseButton(0))
    {
        //Debug.Log(Quaternion.Angle(transform.rotation, target.rotation));
        float angle = Quaternion.Angle(transform.rotation, target.rotation);
        if(angle < 45 || angle > 315)
        {
            Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition);
            transform.RotateAround(pos, Vector3.up, Time.deltaTime * sensitivity);
        }

    }
}
  

Если вместо этого вы хотите ограничить на основе мирового пространства, просто проверьте вращение камеры:

 public float sensitivity = 16.0f;
//public Transform target;

void Update()
{

    if (Input.GetMouseButton(0))
    {

        float angle = transform.eulerAngles.y;
        Debug.Log(angle);
        if (angle < 45 || angle > 315)
        {
            Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition);
            transform.RotateAround(pos, Vector3.up, Time.deltaTime * sensitivity);
        }

    }
}
  

Обратите внимание, что в обоих случаях используется Time.deltaTime, чтобы гарантировать, что вращение происходит с одинаковой скоростью, независимо от частоты кадров игроков.

Если вы хотите изменить вращение, инвертируйте аргумент оси RotateAround:

 transform.RotateAround(pos, -Vector3.up, Time.deltaTime * sensitivity);
  

Ответ №2:

Я это исправил. Вот полный код.

 using UnityEngine;
using System.Collections;

public class MoveCamera : MonoBehaviour 
{

    public float sensitivity = 4.0f;        
    private Vector3 mouseOrigin;
    private bool isRotating;
    public GameObject cam;

    void Start()
    {
    }

    protected float ClampAngle(float angle, float min, float max) {

        angle = NormalizeAngle(angle);
        if (angle > 180) {
            angle -= 360;
        } else if (angle < -180) {
            angle  = 360;
        }

        min = NormalizeAngle(min);
        if (min > 180) {
            min -= 360;
        } else if (min < -180) {
            min  = 360;
        }

        max = NormalizeAngle(max);
        if (max > 180) {
            max -= 360;
        } else if (max < -180) {
            max  = 360;
        }

        return Mathf.Clamp(angle, min, max);
    }

    protected float NormalizeAngle(float angle) {
        while (angle > 360)
            angle -= 360;
        while (angle < 0)
            angle  = 360;
        return angle;
    }


    void Update () 
    {

        if (Input.GetMouseButtonDown (0)) {

            mouseOrigin = Input.mousePosition;
            isRotating = true;
        }

        if (!Input.GetMouseButton (0))
            isRotating = false;

        if (isRotating) {

            cam.transform.localEulerAngles = new Vector3(0, ClampAngle(cam.transform.localEulerAngles.y, -45, 45), 0);
            Vector3 pos = Camera.main.ScreenToViewportPoint (Input.mousePosition - mouseOrigin);
            transform.RotateAround (transform.position, transform.right, -pos.y * sensitivity);
            transform.RotateAround (transform.position, Vector3.up, pos.x * sensitivity);
        }
    }
}