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

Unity3D游戏开发之鼠标旋转、缩放实现3D物品展示

2015-01-23 15:55 776 查看
http://blog.csdn.net/qinyuanpei/article/details/39253951

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



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

[csharp] view
plaincopy





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
plaincopy





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);

}

}

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









今天的内容就是这样子啦,博主最近在捣鼓Unity与Android对接的一些东西,等博主研究好了就分享给大家,希望大家喜欢。最后送上:

喜欢我的博客请记住我的名字:秦元培,我博客地址是blog.csdn.net/qinyuanpei。

转载请注明出处,本文作者:秦元培,本文出处:http://blog.csdn.net/qinyuanpei/article/details/39253951
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: