2017-06-30 89 views
1

我有一個相機,我想圍繞一個點(0,0,0)在所有方向旋轉,但我想把一個鉗位,所以它不能太高或過低。我已經看到這個問題在前面的左側和右側的方向回答,但從來沒有爲垂直的方向回答。如何限制(鉗制)Y軸旋轉transform.rotatearound統一

我已經嘗試從這兩個問題(基本上說是相同的東西)的代碼轉換爲垂直方向工作,但它沿着旋轉一些點出錯,我不明白爲什麼。

First QuestionSecond Question

這就是我如何試圖將它轉換:

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

如果有人知道的正確方法,使這項工作,爲Y軸,或以不同的方式夾緊垂直旋轉,我會非常激動聽到它!泰!

回答

0

我在這裏有一個類,做你想要的。它圍繞目標旋轉攝像機並夾持Y旋轉。它使用左邊的按鈕旋轉和滾動按鈕來翻譯​​目標。 您可以對其進行編輯以適應您的特定需求 - 您可能希望將目標更改爲Vector3,以便無需對象即可將其設置爲(0,0,0)。希望能幫助到你。

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

對不起,我花了幾天的時間回覆!最後有時間來測試它,它完美的工作!在我的搜索答案中,我發現了另一篇有關同一問題的Unity Answers的文章,你介意我是否傳遞了這篇文章的鏈接? –

+0

我不介意。事實上,我很高興知道這個答案會幫助更多的人。 :-)(對你評論的延遲迴答感到抱歉) – Fenixrw