【问题标题】:How to Limit (clamp) Y axis Rotation for transform.rotatearound Unity如何为 transform.rotatearound Unity 限制(钳位)Y 轴旋转
【发布时间】:2017-06-30 00:58:00
【问题描述】:

我有一个相机,我想围绕一个点 (0,0,0) 向所有方向旋转,但我想在它上面放一个夹子,这样它就不会在该点上方或下方太远。我以前见过这个问题回答了左右方向,但从来没有回答过垂直方向。

我尝试将这两个问题的代码(基本上说的是同一件事)转换为在垂直方向上工作,但它在旋转的某些点上出现错误,我不知道为什么。

First Question, Second 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 轴的正确方法,或者钳制垂直旋转的不同方法,我会非常高兴听到它!太棒了!

【问题讨论】:

    标签: c# unity3d camera rotation unity5


    【解决方案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);
        }
    }
    

    【讨论】:

    • 抱歉,过了几天才回复!终于有时间测试了,效果很好!在我寻找答案的过程中,我在 Unity Answers 上找到了另一个帖子,上面有同样的问题,你介意我传递这个帖子的链接吗?
    • 我一点也不介意。事实上,我很高兴知道这个答案会帮助更多的人。 :-) (抱歉,您的评论回复延迟)
    猜你喜欢
    • 1970-01-01
    • 2019-04-14
    • 2015-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-14
    • 2017-12-07
    • 1970-01-01
    相关资源
    最近更新 更多