2017-06-30 4 views
1

Ich habe eine Kamera, die ich um einen Punkt (0,0,0) in alle Richtungen drehen möchte, aber ich möchte so eine Klemme aufstellen dass es nicht zu weit über oder unter den Punkt gehen kann. Ich habe diese Frage schon vorher für die linke und rechte Richtung beantwortet, aber nie für die vertikale.Wie zu begrenzen (Klemme) Y-Achse Rotation für Transform.Umdrehung Unity

Ich habe versucht, den Code aus diesen beiden Fragen (die im Grunde sagen die gleiche Sache) zu arbeiten in der vertikalen Richtung, aber es Bugs out an einigen Punkten entlang der Rotation, und ich kann nicht herausfinden, warum.

First Question, Second Question

Und das ist, wie ich versuchte, es zu konvertieren:

//how much we want to rotate by this frame 
float rotX = Input.GetAxis("Mouse X") * rotSpeed; 
float rotY = Input.GetAxis("Mouse Y") * rotSpeed; //(before clamping) 

//find current direction 
Vector3 currentDirection = transform.position - Vector3.zero; 

//find current angle between basis for clamp & where we are now 
float angle = Vector3.Angle(Vector3.forward, currentDirection); 

//finds out if it's up or down 
if (Vector3.Cross(Vector3.forward, currentDirection).x < 0) angle = -angle; 

//find out how much you can move without violating limits 
float newAngle = Mathf.Clamp(angle + rotY, yMinLimit, yMaxLimit); 

//grabs how much you are allowed to move the angle from the current angle 
rotY = newAngle - angle; 

//spinning the garden 
transform.RotateAround(Vector3.zero, Vector3.up, rotX); 
transform.RotateAround(Vector3.zero, transform.TransformDirection(Vector3.right), -rotY); //vertical rotation 

Wenn jemand von der richtigen Art und Weise kennt diese Arbeit für die Y-Achse zu machen, oder eine andere Art und Weise zu klemmen die vertikale Rotation, ich wäre super aufgeregt, es zu hören! Ty!

Antwort

0

Ich habe eine Klasse hier, die genau das tun, was Sie wollen. Es dreht eine Kamera um ein Ziel und klemmt die Y-Rotation. Es verwendet die linke Taste zum Drehen und die Scroll-Taste, um das Ziel zu übersetzen. Sie können es bearbeiten, um es an Ihre speziellen Bedürfnisse anzupassen - Sie können das Ziel beispielsweise in ein Vector3 ändern, sodass Sie es (0,0,0) ohne ein Objekt einstellen können. Ich hoffe es hilft.

using UnityEngine; 


public class RotateAroundCamera : MonoBehaviour 
{ 
    Camera cam; 
    public bool isControlable; 
    private Vector3 screenPoint; 
    private Vector3 offset; 
    public Transform target; 
    public float distance = 5.0f; 
    public float xSpeed = 50.0f; 
    public float ySpeed = 50.0f; 

    public float yMinLimit = -80f; 
    public float yMaxLimit = 80f; 

    public float distanceMin = .5f; 
    public float distanceMax = 15f; 

    public float smoothTime = 2f; 

    public float rotationYAxis = 0.0f; 
    float rotationXAxis = 0.0f; 

    float velocityX = 0.0f; 
    float velocityY = 0.0f; 
    float moveDirection = -1; 

    public void SetControllable(bool value) 
    { 
     isControlable = value; 
    } 

    // Use this for initialization 
    void Start() 
    { 
     cam = GetComponentInChildren<Camera>(); 
     Vector3 angles = transform.eulerAngles; 
     rotationYAxis = (rotationYAxis == 0) ? angles.y : rotationYAxis; 
     rotationXAxis = angles.x; 

     Rigidbody rigidbody = GetComponent<Rigidbody>(); 

     // Make the rigid body not change rotation 
     if (rigidbody) 
     { 
      rigidbody.freezeRotation = true; 
     } 
    } 

    void LateUpdate() 
    { 
     if (target) 
     { 
      if (Input.GetMouseButton(1) && isControlable) 
      { 
       velocityX += xSpeed * Input.GetAxis("Mouse X") * 0.02f; 
       velocityY += ySpeed * Input.GetAxis("Mouse Y") * 0.02f; 
      } 


      if (Input.GetMouseButton(2) && isControlable) 
      { 
       Vector3 curScreenPoint = new Vector3(moveDirection*Input.mousePosition.x, moveDirection*Input.mousePosition.y, screenPoint.z); 

       Vector3 curPosition = cam.ScreenToWorldPoint(curScreenPoint) + offset; 
       target.transform.position = curPosition; 
      } 

      if (Input.GetKeyDown(KeyCode.R) && isControlable) 
      { 
       target.transform.position = Vector3.zero; 
      } 

      if (Input.GetKeyDown(KeyCode.T) && isControlable) 
      { 
       moveDirection *= -1; 
      } 

      if (isControlable) 
      { 
       distance -= Input.GetAxis("Mouse ScrollWheel"); 

       if (distance > distanceMax) 
       { 
        distance = distanceMax; 
       } 
       else if (distance < distanceMin) 
       { 
        distance = distanceMin; 
       } 
      } 

      rotationYAxis += velocityX; 
      rotationXAxis -= velocityY; 

      rotationXAxis = ClampAngle(rotationXAxis, yMinLimit, yMaxLimit); 

      Quaternion fromRotation = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, 0); 
      Quaternion toRotation = Quaternion.Euler(rotationXAxis, rotationYAxis, 0); 
      Quaternion rotation = toRotation; 

      Vector3 negDistance = new Vector3(0.0f, 0.0f, -distance); 
      Vector3 position = rotation * negDistance + target.position; 

      transform.rotation = rotation; 
      transform.position = position; 

      velocityX = Mathf.Lerp(velocityX, 0, Time.deltaTime * smoothTime); 
      velocityY = Mathf.Lerp(velocityY, 0, Time.deltaTime * smoothTime); 

      screenPoint = cam.WorldToScreenPoint(target.transform.position); 
      offset = target.transform.position - cam.ScreenToWorldPoint(new Vector3(moveDirection*Input.mousePosition.x, moveDirection*Input.mousePosition.y, screenPoint.z)); 
     } 

    } 

    public static float ClampAngle(float angle, float min, float max) 
    { 
     if (angle < -360F) 
      angle += 360F; 
     if (angle > 360F) 
      angle -= 360F; 
     return Mathf.Clamp(angle, min, max); 
    } 
} 
+0

Entschuldigung, es dauerte ein paar Tage bis ich antwortete! Endlich Zeit um es zu testen und es funktioniert perfekt! Bei meiner Suche nach einer Antwort habe ich einen anderen Post zu Unity Answers mit der gleichen Frage gefunden, stört es Sie, wenn ich einen Link zu diesem Post weitergebe? –

+0

Es stört mich überhaupt nicht. In der Tat bin ich froh zu wissen, dass diese Antwort mehr Menschen helfen wird. :-) (Entschuldigung für die verspätete Antwort auf Ihren Kommentar) – Fenixrw