如何限制(钳制)Y轴旋转以进行transform.rotatearound Unity

时间:2017-06-30 00:58:00

标签: c# unity3d camera rotation unity5

我有一台相机,我想绕各个方向的一个点(0,0,0)旋转,但我想在它上面放一个夹子,这样它就不会在它上方或下方太远点。我已经看到这个问题的答案是左右方向,但从来没有针对垂直方向。

我已经尝试将这两个问题的代码(基本上说同样的东西)转换为在垂直方向上工作,但它在旋转的某些点上会出错,我无法弄清楚原因。

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轴,或以不同的方式来夹住垂直旋转,我会非常兴奋地听到它! TY!

1 个答案:

答案 0 :(得分:1)

我在这里有一个完全按照你想要的课程。它围绕目标旋转相机并夹紧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);
    }
}