unity旋转 缩放摄像机

来源:互联网 发布:上海 红牌js 编辑:程序博客网 时间:2024/04/28 05:12

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


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

[csharp] view plain copy 在CODE上查看代码片派生到我的代码片
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. public class FreeView : MonoBehaviour {  
  5.   
  6.     //观察目标  
  7.     public Transform Target;  
  8.   
  9.     //观察距离  
  10.     public float Distance = 5F;  
  11.   
  12.     //旋转速度  
  13.     private float SpeedX=240;  
  14.     private float SpeedY=120;  
  15.   
  16.     //角度限制  
  17.     private float  MinLimitY = -180;  
  18.     private float  MaxLimitY = 180;  
  19.       
  20.     //旋转角度  
  21.     private float mX = 0.0F;  
  22.     private float mY = 0.0F;  
  23.       
  24.     //鼠标缩放距离最值  
  25.     private float MaxDistance=10;  
  26.     private float MinDistance=1.5F;  
  27.     //鼠标缩放速率  
  28.     private float ZoomSpeed=2F;  
  29.       
  30.     //是否启用差值  
  31.     public bool isNeedDamping=true;  
  32.     //速度  
  33.     public float Damping=10F;  
  34.   
  35.     //存储角度的四元数  
  36.     private Quaternion mRotation;  
  37.   
  38.     //定义鼠标按键枚举  
  39.     private enum MouseButton  
  40.     {  
  41.         //鼠标左键  
  42.         MouseButton_Left=0,  
  43.         //鼠标右键  
  44.         MouseButton_Right=1,  
  45.         //鼠标中键  
  46.         MouseButton_Midle=2  
  47.     }  
  48.   
  49.     //相机移动速度  
  50.     private float MoveSpeed=5.0F;  
  51.     //屏幕坐标  
  52.     private Vector3 mScreenPoint;  
  53.     //坐标偏移  
  54.     private Vector3 mOffset;  
  55.   
  56.     void Start ()   
  57.     {  
  58.         //初始化旋转角度  
  59.         mX=transform.eulerAngles.x;  
  60.         mY=transform.eulerAngles.y;  
  61.     }  
  62.       
  63.     void LateUpdate ()   
  64.     {  
  65.         //鼠标右键旋转  
  66.         if(Target!=null && Input.GetMouseButton((int)MouseButton.MouseButton_Right))  
  67.         {  
  68.             //获取鼠标输入  
  69.             mX += Input.GetAxis("Mouse X") * SpeedX * 0.02F;  
  70.             mY -= Input.GetAxis("Mouse Y") * SpeedY * 0.02F;  
  71.             //范围限制  
  72.             mY = ClampAngle(mY,MinLimitY,MaxLimitY);  
  73.             //计算旋转  
  74.             mRotation = Quaternion.Euler(mY, mX, 0);  
  75.             //根据是否插值采取不同的角度计算方式  
  76.             if(isNeedDamping){  
  77.                 transform.rotation = Quaternion.Lerp(transform.rotation,mRotation, Time.deltaTime*Damping);   
  78.             }else{  
  79.                 transform.rotation = mRotation;  
  80.             }  
  81.         }  
  82.   
  83.         //鼠标中键平移  
  84.   
  85.   
  86.         //鼠标滚轮缩放  
  87.         Distance-=Input.GetAxis("Mouse ScrollWheel") * ZoomSpeed;  
  88.         Distance=Mathf.Clamp(Distance,MinDistance,MaxDistance);  
  89.           
  90.         //重新计算位置  
  91.         Vector3 mPosition = mRotation * new Vector3(0.0F, 0.0F, -Distance) + Target.position;  
  92.           
  93.         //设置相机的位置  
  94.         if(isNeedDamping){  
  95.             transform.position = Vector3.Lerp(transform.position,mPosition, Time.deltaTime*Damping);   
  96.         }else{  
  97.             transform.position = mPosition;  
  98.         }  
  99.           
  100.     }  
  101.       
  102.       
  103.     //角度限制  
  104.     private float  ClampAngle (float angle,float min,float max)   
  105.     {  
  106.         if (angle < -360) angle += 360;  
  107.         if (angle >  360) angle -= 360;  
  108.         return Mathf.Clamp (angle, min, max);  
  109.     }  
  110. }  
大家是不是觉得这部分代码很熟悉?不错,这里的原理都是一样的,大家只要掌握核心原理就可以了,即首先根据鼠标输入来计算旋转角、然后通过滚轮输入计算距离、最后通过四元数运算计算相机的角度和距离。好了,我们来看看最终的效果吧!



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

[csharp] view plain copy 在CODE上查看代码片派生到我的代码片
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. public class MobileInput : MonoBehaviour {  
  5.   
  6.     //观察目标  
  7.     public Transform Target;  
  8.   
  9.     //观察距离  
  10.     public float Distance = 2F;  
  11.   
  12.     //距离最值  
  13.     public float MaxDistance=5F;  
  14.     public float MinDistance=0.5F;  
  15.   
  16.     //缩放速率  
  17.     private float ZoomSpeed=0.15F;  
  18.   
  19.     //旋转速度  
  20.     private float SpeedX=240;  
  21.     private float SpeedY=120;  
  22.     //角度限制  
  23.     private float  MinLimitY = 5;  
  24.     private float  MaxLimitY = 180;  
  25.       
  26.     //旋转角度  
  27.     private float mX=0;  
  28.     private float mY=0;  
  29.   
  30.     //当前手势  
  31.     private Vector2 mPos;  
  32.   
  33.     void Start ()   
  34.     {  
  35.         //允许多点触控  
  36.         Input.multiTouchEnabled=true;  
  37.         //初始化旋转  
  38.         mX=Target.eulerAngles.x;  
  39.         mY=Target.eulerAngles.y;  
  40.     }  
  41.   
  42.     void Update ()   
  43.     {  
  44.         if(!Target) return;  
  45.   
  46.   
  47.         //单点触控  
  48.         if(Input.touchCount==1)  
  49.         {  
  50.             //手指处于移动状态  
  51.             if(Input.touches[0].phase==TouchPhase.Moved)  
  52.             {  
  53.                 mX+=Input.GetAxis("Mouse X") * SpeedX * 0.02F;  
  54.                 mY-=Input.GetAxis("Mouse X") * SpeedY * 0.02F;  
  55.                 mY=ClampAngle(mY,MinLimitY,MaxLimitY);  
  56.             }  
  57.         }  
  58.   
  59.         //多点触控  
  60.         if(Input.touchCount>1)  
  61.         {  
  62.             //两只手指都处于移动状态  
  63.             if(Input.touches[0].phase==TouchPhase.Moved || Input.touches[1].phase==TouchPhase.Moved)  
  64.             {  
  65.                 //计算移动方向  
  66.                 Vector2 mDir=Input.touches[1].position-Input.touches[0].position;  
  67.                 //根据向量的大小判断当前手势是放大还是缩小  
  68.                 if(mDir.sqrMagnitude>mPos.sqrMagnitude){  
  69.                     Distance-=ZoomSpeed;  
  70.                 }else{  
  71.                     Distance+=ZoomSpeed;  
  72.                 }  
  73.                 //限制距离  
  74.                 Distance=Mathf.Clamp(Distance,MinDistance,MaxDistance);  
  75.                 //更新当前手势  
  76.                 mPos=mDir;  
  77.             }  
  78.         }  
  79.   
  80.         //计算相机的角度和位置  
  81.         transform.rotation=Quaternion.Euler(new Vector3(mY,mX,0));  
  82.         transform.position=transform.rotation * new Vector3(0,0,-Distance)+Target.position;  
  83.     }  
  84.   
  85.     //角度限制  
  86.     private float ClampAngle (float angle,float min,float max)   
  87.     {  
  88.         if (angle < -360) angle += 360;  
  89.         if (angle >  360) angle -= 360;  
  90.         return Mathf.Clamp (angle, min, max);  
  91.     }  
  92. }  


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








0 0
原创粉丝点击