Unity3D开发之控制摄像机围绕物体旋转 平移 缩放

这个功能太常用了。做三维模型展示的时候这是必备。旋转我用到的是四元数来控制。至于为什么,我觉得这种方式控制更平滑。忽略其他没用的变量和代码。下面项目中的代码:

//常用开发脚本
//控制摄像机绕着某物体旋转  以及缩放相关功能

public class MouseController : MonoBehaviour
{
    //绕此点旋转
    public Transform PoinTransform;
	public Transform centerGameObject;
    //旋转参数
    private float xspeed = -0.2f;
    private float yspeed = 0.2f;

    private float _viewSpeed = 10;
    //z值控制摄像机和中心点的距离
    private Vector3 posVector3=new Vector3(0,0,-15);
    [HideInInspector]
    public Vector3 rota;
    //_time秒无操作后模型将开始旋转观察模式
    private float _time;
    //鼠标滚轮值
	private float swValue;

    private Vector3 mForward;

    private void Start()
    {
        centerGameObject.position = PoinTransform.position;
        //设置初始摄像机的角度和位置
        rota.x = 30f;
        Quaternion q = Quaternion.Euler(rota);
        transform.position = q * posVector3 + centerGameObject.transform.position;
        transform.rotation = q;
    }

    private void OnEnable()
    {
        _time = 0;
    }

    // Update is called once per frame
    private void Update()
    {
        if (UIFuc.Instance.mCameraMode == CameraMode.XunyouMode) return;
        #region//鼠标控制模型旋转
        swValue = Input.GetAxis("Mouse ScrollWheel");
        //右键鼠标旋转时camera位置信息更新|| 同时按住CTRL加鼠标右键
        if (Input.GetMouseButton(1) || (Input.GetMouseButton(0) && Input.GetKey(KeyCode.LeftControl)))
        {
            posVector3=new Vector3(0,0,-Vector3.Distance(transform.position,centerGameObject.position));
            rota.y += Input.GetAxis("Horizontal")*yspeed;
            rota.x += Input.GetAxis("Vertical")*xspeed;
            rota.x = Mathf.Clamp(rota.x, 0, 90);
            Quaternion q = Quaternion.Euler(rota);
            transform.position = q*posVector3 + centerGameObject.position;
            transform.rotation = q;
            _time = 0;
            Globle._cameraState=CameraState.rotate;
        }
        else if (swValue != 0)//向上滚动是正值
        {
            if (EventSystem.current.IsPointerOverGameObject()) return;
            if (Vector3.Distance(transform.position, centerGameObject.position)<0.8f&&swValue>0) return;
            if (Vector3.Distance(transform.position, centerGameObject.position) > 15f && swValue < 0) return;
            mForward = centerGameObject.position - Camera.main.transform.position;
            transform.position += mForward*swValue;
            _time = 0;
            Globle._cameraState = CameraState.rotate;
        }
        else if (Input.GetMouseButton(2))
        {
            Vector3 moveDir = (Input.GetAxis("Horizontal") * -transform.right+ Input.GetAxis("Vertical")*-transform.up) * 0.05f;
            centerGameObject.position += moveDir;
            transform.position += moveDir;
            _time = 0;
        }
        else
        {
            Globle._cameraState = CameraState.none;
        }
        _time += Time.deltaTime;
        if (_time > 5)
        {
            rota.y -= Time.deltaTime*10;
            Quaternion p = Quaternion.Euler(rota);
            transform.position = p*posVector3 + centerGameObject.position;
            transform.rotation = p;
        }
        #endregion
    }

还有控制摄像机视野平移的代码,是我用的比较简单的一个方法。有缺点,就是平移不是特别顺滑。后来看到一个插件的源码,找到了另一个更好更平滑更满意的实现方式。

//中键平移参数
	private float kPara=0.05f;
	private Vector2 MouseOffsetSincePreviousFrame;

	private Vector2 currentScreenPos ;
	private Vector2 previousScreenPos;
else if(Input.GetMouseButtonDown(2))
		{
			previousScreenPos=Input.mousePosition;
		}
        else if (Input.GetMouseButton(2))
		{
			currentScreenPos=Input.mousePosition;
			MouseOffsetSincePreviousFrame=currentScreenPos-previousScreenPos;
			transform.position+=(MouseOffsetSincePreviousFrame.x*-transform.right+MouseOffsetSincePreviousFrame.y*-transform.up)*kPara;
			previousScreenPos=currentScreenPos;
			return;
		}
效果很棒。希望本博客对你有帮助。

你可能感兴趣的:(Unity)