您的位置:首页 > 移动开发 > Unity3D

unity旋转 缩放摄像机

2016-05-31 14:42 381 查看

研究了摄像机旋转、缩放等问题,那么今天为大家分享的是一个在3D展示中比较常用的功能,即通过鼠标右键实现旋转、鼠标滚轮实现缩放、鼠标中键实现平移。本文采用的方法依然是在[Unity3D]Unity3D游戏开发之自由视角下的角色控制这篇文章中所采用的方法,所以如果大家对于这部分内容不太了解的话,最好先去看看这篇文章。好了,下面我们将以一个具体的实例来讲解今天的内容。如图,是博主创建的一个简单地场景。我们希望实现通过鼠标右键实现对角色的旋转、鼠标滚轮实现对角色的缩放、鼠标中键实现对角色的平移。



    好了,接下来我们来创建一个名为FreeView的脚本,该脚本依附在主相机上,下面我们来看它的实现过程:

[csharp]
view plain
copy





using UnityEngine;  
using System.Collections;  
  
public class FreeView : MonoBehaviour {  
  
    //观察目标  
    public Transform Target;  
  
    //观察距离  
    public float Distance = 5F;  
  
    //旋转速度  
    private float SpeedX=240;  
    private float SpeedY=120;  
  
    //角度限制  
    private float  MinLimitY = -180;  
    private float  MaxLimitY = 180;  
      
    //旋转角度  
    private float mX = 0.0F;  
    private float mY = 0.0F;  
      
    //鼠标缩放距离最值  
    private float MaxDistance=10;  
    private float MinDistance=1.5F;  
    //鼠标缩放速率  
    private float ZoomSpeed=2F;  
      
    //是否启用差值  
    public bool isNeedDamping=true;  
    //速度  
    public float Damping=10F;  
  
    //存储角度的四元数  
    private Quaternion mRotation;  
  
    //定义鼠标按键枚举  
    private enum MouseButton  
    {  
        //鼠标左键  
        MouseButton_Left=0,  
        //鼠标右键  
        MouseButton_Right=1,  
        //鼠标中键  
        MouseButton_Midle=2  
    }  
  
    //相机移动速度  
    private float MoveSpeed=5.0F;  
    //屏幕坐标  
    private Vector3 mScreenPoint;  
    //坐标偏移  
    private Vector3 mOffset;  
  
    void Start ()   
    {  
        //初始化旋转角度  
        mX=transform.eulerAngles.x;  
        mY=transform.eulerAngles.y;  
    }  
      
    void LateUpdate ()   
    {  
        //鼠标右键旋转  
        if(Target!=null && Input.GetMouseButton((int)MouseButton.MouseButton_Right))  
        {  
            //获取鼠标输入  
            mX += Input.GetAxis("Mouse X") * SpeedX * 0.02F;  
            mY -= Input.GetAxis("Mouse Y") * SpeedY * 0.02F;  
            //范围限制  
            mY = ClampAngle(mY,MinLimitY,MaxLimitY);  
            //计算旋转  
            mRotation = Quaternion.Euler(mY, mX, 0);  
            //根据是否插值采取不同的角度计算方式  
            if(isNeedDamping){  
                transform.rotation = Quaternion.Lerp(transform.rotation,mRotation, Time.deltaTime*Damping);   
            }else{  
                transform.rotation = mRotation;  
            }  
        }  
  
        //鼠标中键平移  
  
  
        //鼠标滚轮缩放  
        Distance-=Input.GetAxis("Mouse ScrollWheel") * ZoomSpeed;  
        Distance=Mathf.Clamp(Distance,MinDistance,MaxDistance);  
          
        //重新计算位置  
        Vector3 mPosition = mRotation * new Vector3(0.0F, 0.0F, -Distance) + Target.position;  
          
        //设置相机的位置  
        if(isNeedDamping){  
            transform.position = Vector3.Lerp(transform.position,mPosition, Time.deltaTime*Damping);   
        }else{  
            transform.position = mPosition;  
        }  
          
    }  
      
      
    //角度限制  
    private float  ClampAngle (float angle,float min,float max)   
    {  
        if (angle < -360) angle += 360;  
        if (angle >  360) angle -= 360;  
        return Mathf.Clamp (angle, min, max);  
    }  
}  

大家是不是觉得这部分代码很熟悉?不错,这里的原理都是一样的,大家只要掌握核心原理就可以了,即首先根据鼠标输入来计算旋转角、然后通过滚轮输入计算距离、最后通过四元数运算计算相机的角度和距离。好了,我们来看看最终的效果吧!



         大家应该注意到博主没有实现按下鼠标中键平移的相关方法,因为这部分博主目前还没有彻底正确地写出来,如果大家知道的话,可以给博主留言,或者等博主什么时候想清楚了再来更新这篇博客吧。博主的博客会经常更新的,希望大家继续关注我的博客吧。好了,最后我们再来做一个迁移,我们将把这个功能移植到Android平台上,本来想把这部分作为Android手势控制单独写一篇文章的,可是感觉这里的代码都是相似的,再写一篇实在没有必要,所以,就直接给出代码吧!

[csharp]
view plain
copy





using UnityEngine;  
using System.Collections;  
  
public class MobileInput : MonoBehaviour {  
  
    //观察目标  
    public Transform Target;  
  
    //观察距离  
    public float Distance = 2F;  
  
    //距离最值  
    public float MaxDistance=5F;  
    public float MinDistance=0.5F;  
  
    //缩放速率  
    private float ZoomSpeed=0.15F;  
  
    //旋转速度  
    private float SpeedX=240;  
    private float SpeedY=120;  
    //角度限制  
    private float  MinLimitY = 5;  
    private float  MaxLimitY = 180;  
      
    //旋转角度  
    private float mX=0;  
    private float mY=0;  
  
    //当前手势  
    private Vector2 mPos;  
  
    void Start ()   
    {  
        //允许多点触控  
        Input.multiTouchEnabled=true;  
        //初始化旋转  
        mX=Target.eulerAngles.x;  
        mY=Target.eulerAngles.y;  
    }  
  
    void Update ()   
    {  
        if(!Target) return;  
  
  
        //单点触控  
        if(Input.touchCount==1)  
        {  
            //手指处于移动状态  
            if(Input.touches[0].phase==TouchPhase.Moved)  
            {  
                mX+=Input.GetAxis("Mouse X") * SpeedX * 0.02F;  
                mY-=Input.GetAxis("Mouse X") * SpeedY * 0.02F;  
                mY=ClampAngle(mY,MinLimitY,MaxLimitY);  
            }  
        }  
  
        //多点触控  
        if(Input.touchCount>1)  
        {  
            //两只手指都处于移动状态  
            if(Input.touches[0].phase==TouchPhase.Moved || Input.touches[1].phase==TouchPhase.Moved)  
            {  
                //计算移动方向  
                Vector2 mDir=Input.touches[1].position-Input.touches[0].position;  
                //根据向量的大小判断当前手势是放大还是缩小  
                if(mDir.sqrMagnitude>mPos.sqrMagnitude){  
                    Distance-=ZoomSpeed;  
                }else{  
                    Distance+=ZoomSpeed;  
                }  
                //限制距离  
                Distance=Mathf.Clamp(Distance,MinDistance,MaxDistance);  
                //更新当前手势  
                mPos=mDir;  
            }  
        }  
  
        //计算相机的角度和位置  
        transform.rotation=Quaternion.Euler(new Vector3(mY,mX,0));  
        transform.position=transform.rotation * new Vector3(0,0,-Distance)+Target.position;  
    }  
  
    //角度限制  
    private float ClampAngle (float angle,float min,float max)   
    {  
        if (angle < -360) angle += 360;  
        if (angle >  360) angle -= 360;  
        return Mathf.Clamp (angle, min, max);  
    }  
}  

下面是程序在手机上运行过程中的截图







内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: