2014-09-08 01:32:37 qinyuanpei 阅读数 22040

       各位朋友,大家好,我是秦元培,欢迎大家关注我的博客,我的博客地址是blog.csdn.net/qinyuanpei。在上一篇文章<[Unity3D]Unity3D游戏开发之角色控制漫谈>一文中,博主与大家分享自己在角色控制方面的一些感悟。今天呢,我们继续来探讨Unity3D角色控制的内容,今天博主将解决在上一篇文章中没有解决的问题,即自由视角下的角色控制。如图是博主非常喜欢的《古剑奇谭》游戏截图,在这款游戏中就使用了博主今天要讲解的自由视角,所谓自由视角是指玩家可以按照自身坐标系向着四个不同的方向移动,当玩家按下鼠标右键时,可以绕Y轴按照一定的角度旋转摄像机,在旋转的过程中,角色将旋转相应的角度。在移动的过程中,摄像机会保持与玩家间的一定距离,然后跟随角色进行移动。好了,下面我们正式开始今天的内容吧!


     

     在开始今天的内容前,首先让我们来学习下Unity3D中较为重要的一部分知识,理解这些知识是我们开始学习今天内容的基础。

     1、Input.GetAxis():该方法用于在Unity3D中根据坐标轴名称返回虚拟坐标系中的值,通常情况下,使用控制器和键盘输入时此值范围在-1到1之间。这段话怎么理解呢?我们来看下面这段脚本:

using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {

	//水平速度
	public float HorizontalSpeed = 2.0F;
	//垂直速度
	public float VerticalSpeed = 2.0F;

	void Update() 
	{
		//水平方向
		float h = HorizontalSpeed * Input.GetAxis("Mouse X");
		//垂直方向
		float v = VerticalSpeed * Input.GetAxis("Mouse Y");
		//旋转
		transform.Rotate(v, h, 0);
	}
}
这段脚本呢是根据鼠标的位置来旋转物体从而实现对物体的观察,从这段脚本中我们可以看出,通过获取输入轴的办法,我们可以获得鼠标移动的方向进而实现对于物体的旋转控制。在Unity3D中我们可以通过Edit->Project Setting->Input来查看项目中的坐标轴名称:


在后面,我们还将使用这种方式,大家可以对这个方法有进一步的了解。


     2、欧拉角eulerAngles:该值是Vector3类型的值,x、y、z分别代表绕x轴旋转x度,绕y轴旋转y度,绕z轴旋转z度。因此,该值最为直观的形式是可以允许我们直接以一个三维向量的形式来修改一个物体的角度,例如下面的脚本:

float mY = 5.0;

void Update () 
{
	mY += Input.GetAxis("Horizontal");
	transform.eulerAngles =new Vector3(0,mY, 0);
}
     如果你已经理解了上面的话,那么不出意外的,这段脚本会如你所愿的,按照鼠标在水平方向上移动的方向绕Y轴旋转。通常情况下,我们不会单独设置欧拉角其中一个轴,例如eulerAngles.x = 10,因为这将导致偏移和不希望的旋转。当设置它们一个新的值时,要同时设置全部。好在我们可以通过Quaternion.Euler()方法将一个Vector3类型的值转化为一个四元数,进而通过修改Transform.Rotation来实现相同的目的。

    

     3、插值:所谓插值是指离散数据的基础上补插连续函数,使得这条连续曲线通过全部给定的离散数据点。插值是离散函数逼近的重要方法,利用它可通过函数在有限个点处的取值状况,估算出函数在其他点处的近似值。在某些情况下,如果我们希望过程中处理得较为平滑,此时我们就可以使用插值的方法来实现对中间过程的模拟。在Unity3D中我们可以使用两种插值方法,即线性插值Lerp,球形插值SLerp。我们来看下面的脚本:

void Rotating (float horizontal, float vertical)
	{
		// Create a new vector of the horizontal and vertical inputs.
		Vector3 targetDirection = new Vector3(horizontal, 0f, vertical);
		
		// Create a rotation based on this new vector assuming that up is the global y axis.
		Quaternion targetRotation = Quaternion.LookRotation(targetDirection, Vector3.up);
		
		// Create a rotation that is an increment closer to the target rotation from the player's rotation.
		Quaternion newRotation = Quaternion.Lerp(rigidbody.rotation, targetRotation, turnSmoothing * Time.deltaTime);
		
		// Change the players rotation to this new rotation.
		rigidbody.MoveRotation(newRotation);
	}
插值的方法很简单,只要我们给出初始和结束的状态、时间就可以了,大家可以自己看API。


      好了,有了这三部分的基础,我们就可以开始今天的内容了,今天的脚本分为两个部分,第一部分是角色控制的部分,主要负责的角色在场景中的移动、转身和动画处理。第二部分是相机控制的部分,主要涉及相机旋转、相机缩放的相关内容。下面,我们分别来讲这两个部分,场景依然是博主自己在做的小游戏:


本次的主角呢,是博主非常喜欢的角色谢沧行,好了,我们回到今天的内容里吧!在第一部分,主要的是完成角色向各个方向的转身,这里博主定义四个方向(其实八个方向是一样的!),脚本如下:

using UnityEngine;
using System.Collections;

public class NoLockiVew_Player : MonoBehaviour {

	/*自由视角下的角色控制*/
	/*作者:秦元培*/

	//玩家的行走速度
	public float WalkSpeed=1.5F;
	//重力
	public float Gravity=20;

	//角色控制器
	private CharacterController mController;
	//动画组件
	private Animation mAnim;
	//玩家方向,默认向前
	private DirectionType mType=DirectionType.Direction_Forward;

	[HideInInspector]
	//玩家状态,默认为Idle
	public PlayerState State=PlayerState.Idle;

	//定义玩家的状态枚举
	public enum PlayerState
	{
		Idle,
		Walk
	}

	//定义四个方向的枚举值,按照逆时针方向计算
	protected enum DirectionType
	{
		Direction_Forward=90,
		Direction_Backward=270,
		Direction_Left=180,
		Direction_Right=0
	}
	
	void Start () 
	{
	   //获取角色控制器
	   mController=GetComponent<CharacterController>();
	   //获取动画组件
	   mAnim=GetComponentInChildren<Animation>();
	}
	
	
	void Update () 
	{
		MoveManager();
		//MouseEvent();
	}

	//玩家移动控制
	void MoveManager()
	{
		//移动方向
		Vector3 mDir=Vector3.zero;
		if(mController.isGrounded)
		{
			//将角色旋转到对应的方向
			if(Input.GetAxis("Vertical")==1)
			{
				SetDirection(DirectionType.Direction_Forward);
				mDir=Vector3.forward * Time.deltaTime * WalkSpeed;
				mAnim.CrossFade("Walk",0.25F);
				State=PlayerState.Walk;
			}
			if(Input.GetAxis("Vertical")==-1)
			{
				SetDirection(DirectionType.Direction_Backward);
				mDir=Vector3.forward * Time.deltaTime * WalkSpeed;
				mAnim.CrossFade("Walk",0.25F);
				State=PlayerState.Walk;
			}
			if(Input.GetAxis("Horizontal")==-1)
			{
				SetDirection(DirectionType.Direction_Left);
				mDir=Vector3.forward * Time.deltaTime * WalkSpeed;
				mAnim.CrossFade("Walk",0.25F);
				State=PlayerState.Walk;
			}
			if(Input.GetAxis("Horizontal")==1)
			{
				SetDirection(DirectionType.Direction_Right);
				mDir=Vector3.forward * Time.deltaTime * WalkSpeed;
				mAnim.CrossFade("Walk",0.25F);
				State=PlayerState.Walk;
			}
			//角色的Idle动画
			if(Input.GetAxis("Vertical")==0 && Input.GetAxis("Horizontal")==0)
			{
				mAnim.CrossFade("Idle",0.25F);
				State=PlayerState.Idle;
			}

		}
		//考虑重力因素
		mDir=transform.TransformDirection(mDir);
		float y=mDir.y-Gravity *Time.deltaTime;
		mDir=new Vector3(mDir.x,y,mDir.z);
		mController.Move(mDir);
	}

	//设置角色的方向,有问题
	void SetDirection(DirectionType mDir)
	{
		if(mType!=mDir)
		{
			transform.Rotate(Vector3.up*(mType-mDir));
			mType=mDir;
		}
	}
}
这里定义四个方向,是按照逆时针方向转的,相邻的两个方向间相差90度,所以我们只需要将当前的角度和目标角度相减就可以转到目标角度的方向(其实这是以前写的代码,现在回头再看,直接用欧拉角似乎更为简单啊,呵呵)。这里主要的内容就是这样了。下面我们来看相机控制部分的代码吧,这里的代码参考了MouseOrbit脚本,主要完成了鼠标右键旋转控制,博主在此基础上增加了相机缩放的代码。提到相机缩放,其实就是根据鼠标滚轮滚动的方向和大小重新计算角色与相机的距离,与之类似地还有小地图的放缩,其实同样是通过修改距离来实现的。博主今天的一个体会是官方的代码能自己写一遍的最好自己写一遍,这样好多东西就能在这个过程中给理解了。我们一起来看脚本
using UnityEngine;
using System.Collections;

public class NoLockView_Camera : MonoBehaviour 
{
	//观察目标
	public Transform Target;
	//观察距离
	public float Distance = 5F;
	//旋转速度
	private float SpeedX=240;
	private float SpeedY=120;
	//角度限制
	private float  MinLimitY = 5;
	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=2.5F;

	void Start () 
	{
		//初始化旋转角度
		mX=transform.eulerAngles.x;
		mY=transform.eulerAngles.y;
	}
	
	void LateUpdate () 
	{
		//鼠标右键旋转
		if(Target!=null && Input.GetMouseButton(1))
		{
		    //获取鼠标输入
			mX += Input.GetAxis("Mouse X") * SpeedX * 0.02F;
			mY -= Input.GetAxis("Mouse Y") * SpeedY * 0.02F;
			//范围限制
			mY = ClampAngle(mY,MinLimitY,MaxLimitY);
		}

		//鼠标滚轮缩放

		Distance-=Input.GetAxis("Mouse ScrollWheel") * ZoomSpeed;
		Distance=Mathf.Clamp(Distance,MinDistance,MaxDistance);

		//重新计算位置和角度
		Quaternion mRotation = Quaternion.Euler(mY, mX, 0);
		Vector3 mPosition = mRotation * new Vector3(0.0F, 0.0F, -Distance) + Target.position;

		//设置相机的角度和位置
		if(isNeedDamping){
		   //球形插值
		   transform.rotation = Quaternion.Lerp(transform.rotation,mRotation, Time.deltaTime*Damping); 
		   //线性插值
		   transform.position = Vector3.Lerp(transform.position,mPosition, Time.deltaTime*Damping); 
		}else{
		   transform.rotation = mRotation;
		   transform.position = mPosition;
		}
		//将玩家转到和相机对应的位置上
		if(Target.GetComponent<NoLockiVew_Player>().State==NoLockiVew_Player.PlayerState.Walk)
		{
			Target.eulerAngles=new Vector3(0,mX,0);
		}
	}
	
	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);
	}
    



}



这里很多朋友可能对我设置一个状态很不理解吧,这其实是为了让玩家有一个自由查看角色的机会,否则当玩家按下鼠标右键的话,角色就会转向相机正对着的位置,这样玩家就看不到角色的正面了。当然,这里用到了插值,这样能使角色在转身的时候平滑一点,效果会更好。

唉,不知不觉已经这个时候了,开学已经一周了,这学期我们只上九周课,然后就是实习、毕设、找工作一大堆事情在等着我们。可是不知道为什么博主宿舍的同学居然还能每天什么事情都不做,从早上一直看电视剧到晚上十点,虽然这件事情和博主没有什么关系吧,可是整个宿舍的人都安安静静地做着自己的事情,就有这么一个人整天声音开得很大在那里外放,这样真的好吗?以前和这个人闹过一次,因为他聚了一帮人在宿舍打麻将,我觉得吵就说了他一顿,结果就和我僵上了。说真的,博主对目前的专业真的没有什么情感,大学四年里最让博主开心的事情就是博主学会了好多自己想要学的东西,认识了几个不错的老师和朋友,仅此而已。或许我们注定要越走越远吧,因为我们根本就不是同一种人。

前几天网上有人通过博客联系到博主,希望博主能到他哪里工作,可惜博主目前仍然有一大堆的琐事缠身,不然离开这喧嚣吵闹的宿舍,去做博主喜欢的事情,去寻找博主自己的梦想,博主相信,博主一定可以做得更好吧。人生或许就是这样,你越是在乎的可能越让你得不到,你无心插柳可能会得到一片绿荫。对于未来,不管怎么样,坦然面对就好了,博主改变不了周围的这群人,只能努力地去改变自己。好了,晚安吧!

效果演示(2M的限制让很多展示都无可奈何)



每日箴言:所有的悲伤,总会留下一丝欢乐的线索。所有的遗憾,总会留下一处完美的角落。我在冰封的深海,找寻希望的缺口。却在午夜惊醒时,蓦然瞥见绝美的月光。——几米


       喜欢我的博客请记住我的名字:秦元培,我博客地址是blog.csdn.net/qinyuanpei。
       转载请注明出处,本文作者:秦元培,本文出处:http://blog.csdn.net/qinyuanpei/article/details/39125353


      文章更新:

      9月10日,博主在测试这个项目的时候意外地发现了一个Bug。Bug出现在如下位置:

		//设置玩家跟随角度
		if(Target.GetComponent<NoLockiVew_Player>().State==NoLockiVew_Player.PlayerState.Walk)
		{
			Target.rotation=Quaternion.Euler(new Vector3(0,mX,0));
		}

该方法主要的作用是当玩家同时按下方向控制键和鼠标右键,玩家可以随着鼠标旋转到对应的角度,这主要是为了满足玩家双手操作的需求,不过由于这行代码,导致玩家在向左、向右、向后三个方向上的转身失效,如果除去这行代码,则原来的方向控制没有任何问题,可是没有这行代码,玩家的操作感就会下降。后来博主想到我们对角色的旋转实际上应该是放在鼠标右键事件里的,所以博主将代码修改如下,这样就解决了这个Bug:

using UnityEngine;
using System.Collections;

public class NoLockView_Camera : MonoBehaviour 
{
	//观察目标
	public Transform Target;
	//观察距离
	public float Distance = 5F;
	//旋转速度
	private float SpeedX=240;
	private float SpeedY=120;
	//角度限制
	private float  MinLimitY = 5;
	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;

	void Start () 
	{
		//初始化旋转角度
		mX=transform.eulerAngles.x;
		mY=transform.eulerAngles.y;
	}
	
	void LateUpdate () 
	{
		//鼠标右键旋转
		if(Target!=null && Input.GetMouseButton(1))
		{
		    //获取鼠标输入
			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;
			}
			//处理同时按下鼠标右键和方向控制键
			if(Target.GetComponent<NoLockiVew_Player>().State==NoLockiVew_Player.PlayerState.Walk){
				Target.rotation=Quaternion.Euler(new Vector3(0,mX,0));
			}
		}

		//鼠标滚轮缩放
		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);
	}
}


不过经过博主测试,如果不采用插值的话,似乎效果更为真实啊(为什么会和第一次测试的感觉不一样啊,囧!)




2016-12-29 14:31:57 qq_36703442 阅读数 1670

蓝鸥免费Unity3D教程讲解  Unity3D学习必看教程

随着AR/VR进入人们的生活,面对AR/VR体验馆的出现,全民开始聊“AR/VR”成为一种社会现象!而作为一款全面整合的专业游戏引擎Unity是一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具。两者之间有什么联系?


到目前为止,针对VR开发的内容,至少有90%是基于Unity3D的平台开发的。换句话说Unity 3D之于VR有什么作用?现在我们正在叩开新时代的大门,Unity3D就是打开这座大门的钥匙。

免费Unity3D教程可以解决什么问题?


所需基础:零基础或C语言基础及其他编程基础   适合人群:游戏开发爱好者

Unity3D学习必看教程解说

在Unity3D的开发过程中,需要学习编程语言!目前Unity所支持C#和JavaScript,而C#开发的项目占90%以上。为了能更好匹配到企业岗位需求,学习C#开发成为众多开发者的首选!

免费Unity3D教程C#入门知识包括:二进制、数据类型,运算符,表达式,控制台语句,关系运算符,循环语句,一维数组,二维数组等。对于有C语言基础或其他编程基础的朋友,C#入门会变得更为容易一些!

C#入门只是让我们对编程语言有一些认识,C#入门的知识点设计可以帮助零基础的朋友,快速入门!而相对于C#入门,C#基础方面知识的学习,开始偏向逻辑性,简单的说是要开始和计算机对话!开始对计算机编辑指令!

免费Unity3D教程C#基础知识包括:枚举类型、结构体、类和对象、字段、方法、抽象类、静止类、封装、继承、构造和析构等,单从这些知识点的名称来说,在学习的过程中需要动用大脑。C#基础的学习并不是一个死记硬背的过程,需要我们举一反三的过程。如果无法做到举一反三,可能需要在C#基础部分,下功夫好好的锻炼是必不可少的。千万不要书到用时方恨少!

在C#学习之后,我们接下来将要步入正题:对Unity引擎的了解,这将是一场没有硝烟的较量!Unity作为一个工具,我们需要对其充分了解,才能更好的运用Unity来实现我们构想。那么,大家对于自己学习Unity有哪些构想?欢迎大家留意讨论!
2019-09-22 14:05:19 fengliaoai 阅读数 12376

每周更新unity3d视频教程,从入门到就业,官方unity3d培训,上千门实时更新课程,供学员在线观看学习,unity3d游戏开发,可以让学员随时随地学习!
免费网上学习unity3d自学教程,国内名师机构专业授课,O基础快速学习,1小时快速入门,7天unity3d自学教程学习,能力快速提升,优质作品随手呈现!

unity3d菜鸟自学教程介绍

unity3d难学吗?

unity3d自学教程目录

unity3d视频教程百度网盘下载

unity3d难学吗?
学习unity3d特效,多来学习路线网看教程,一线游戏特效老师,游戏特效就业安排!学习unity3d特效入门+进阶+精通选择专业才能学得专业!

unity3d自学教程目录
课程介绍:
Unity3d史诗 MMO ARPG 课程《泰斗破坏神》,精心设计将包含200+课时,由视频课时+直播课时+测试课时混合组成。最重头unity3d ARGP课程,完整的 ARPG 网络游戏开发教学。包含多人合作,在线多人游戏开发,角色创建系统,作战系统,RPG系统,技能系统,任务系统,商店系统。

课程大纲:

单机版功能实现

项目概要
登录系统
角色创建、选择、自定义系统
场景加载与游戏存储记录
角色控制
聊天通讯
游戏AI
战斗系统
游戏角色与玩家信息系统
商店系统
道具系统
装备系统
装备与道具掉落
仓库与背包系统
副本系统
任务系统
地图与寻路系统

网络版功能实现

服务端搭建
登录系统
角色选择
游戏场景
聊天功能
角色具体信息
商店系统
道具系统
装备系统
仓库和背包
副本系统
任务系统

unity3d视频教程百度网盘下载
http://www.xuexiluxian.net/unity3d-cainiao-zixue.html

2017-07-16 20:10:17 dark00800 阅读数 16329

Unity3d不久之前正式发布了Unity3d 2017.1, 这个版本的发布也宣告了Unity3d正式告别了5.x时代,并且开始已年份直接命名,开启了新的纪元。那么Unity3d 2017相较上一版本到底有哪些改进呢?

这介绍这些改进之前先放出下载地址:Unity 2017.1
有趣的是通过Unity产品蓝图我们可以发现Unity 2017.2 beta已经提供下载测试并且Unity 2017.3也已经在制作中了。
这里写图片描述
Unity 2017.2 beta下载地址:Unity 2017.2 beta

以下关于Unity2017.1的介绍内容来自Unity官方中文社区,原帖地址:[官方] Unity 2017.1正式版发布

Unity 2017.1中包含大量新功能与改进。主要内容如下:

  • 艺术家和设计师们:全新的叙事和游戏视频创作工具
    Unity 2017.1为艺术家和设计师们提供了全新的工具,使用Timeline,Cinemachine和Post-processing工具,可以创造令人惊叹的影视内容,合成精美相机镜头,描绘更好的视觉故事。
    Timeline是一款强大的可视化新工具,可用于创建影视内容,例如过场动画、预告片、游戏试玩视频等等。
    Cinemachine是一个高级相机系统,您可以像电影导演一样,在Unity中合成镜头,无需编写任何代码,引领您进入程序化摄影时代。
    Post-processing可以很方便地为场景应用各种逼真滤镜,使用电影工业级技术、控件和颜色空间格式来创造高质量视觉效果,让画面更生动、更逼真,助您描绘更好的视觉故事。
  • 效率:协作、实时操作分析、工具
    我们发布了Unity Teams,它由一系列简化创作者协作流程的功能和解决方案组成,包含Collaborate多人协作(现已发布)和Cloud Build云构建。
    实时操作分析系统引入了新的、更简单的方法,帮助您理解用户,并在不需要重新部署的情况下,对游戏做出动态的反应和调整。
    最重要的是,Unity 2017.1对编辑器进行了大量更新,包括对FBX导入、动画工作流程、2D功能、Asset Bundle工作流和Visual Studio集成的改进。
  • 图形与平台:全面改进
    Unity 2017.1对粒子系统和Progressive Lightmapper进行了大量改进,提供了更多选择来实现您的艺术愿景并控制性能。不同平台可采用不同的渲染品质,例如iOS平台上的Deferred Rendering,和PC上的NVIDIA VRWorks。
    这些都只是Unity 2017.1的亮点概念,下面将介绍完整丰富的细节内容!

Unity 2017.1新看点

艺术家叙事工具: Timeline和Cinemachine介绍

设计师、艺术家或动画师们可以使用新的集成叙事工具,自己制作影视内容和游戏视频,而不用依赖程序员。这意味着开发效率更高,而节约沟通与排队成本。

Timeline是一款强大的可视化新工具,可用于创建影视内容(例如短片Adam)。通过编排游戏对象、动画、声音和场景,来创建过场动画、游戏视频等等。有了Timeline,您可以专注于叙事和电影艺术创作,而非编码。

Timeline基于轨道的序列工具,使用“拖放”操作来编排动画、声音、事件、视频等元素,以更快地创建漂亮的过场动画和程序化内容。Timeline有许多功能,例如动画、音频、自动关键帧,以及可以锁定或静音特定轨道的多轨道界面。Timeline可通过Playable API进行扩展,支持创建自定义轨道,来驱动游戏中的任意系统。您可以制作一个Timeline剪辑来表示几乎所有内容——并且可以重复播放、缩放和混合这些剪辑,所有这些都可在Timeline中实现。
这里写图片描述

Cinemachine 是多年游戏和电影摄像机的构建经验凝聚而成的结晶。现在,它将业界领先的摄像操作置于所有人手中,引领了程序化摄影的时代。

这是一套智能摄像机,可以动态的根据场景组成和交互,在最佳时间拍摄最佳镜头。使您摆脱无尽的手工动画、摄像机编程以及修订的过程。

Cinemachine可以在Asset Store资源商店中下载,现在就添加到您的项目中。

从第一人称射击游戏到第三人称动作冒险,您可以用Cinemachine彻底改变游戏内摄像机。很容易地:

  • 像电影导演那样,使用高级摄像机工具及真实的摄像机设置,来控制视频序列。
  • 合成镜头,把重点放在艺术方向上,而非实现细节。给Cinemachine智能摄像机一个简单的指示,比如跟随人物的头部,如果动画发生变化,镜头会自动更新并继续正常工作。
    这里写图片描述

    在Unity 2017.1中,我们为Cinemachine增加了很多新功能,比如:

  • 多个目标对象:以多个对象为目标,并设置它们的权重。它基于任意数量的对象创建一个逻辑组,根据其成员的位置来定位自己。在跟踪一组对象时,可以将其用作LookAt和Follow方法的目标。对2D场景也非常适用。
  • 动态取景多个对象:该功能将基于对象的位置自动取景一组目标。如果对象散开,Cinemachine将根据您创建的一套规则调整FOV或推拉(或两者同时进行)
  • 全新开放API:轻松定制Cinemachine配置,获得项目需要的摄像机行为。
  • 推拉轨道:创造出像电影一样的推拉镜头,让摄像机在游戏世界里平滑移动。适合于电影序列,或当您希望摄像机沿着一组轨道跟踪拍摄对象时。
  • 安全镜头:安全镜头会根据镜头优先级与质量,动态选择最佳的摄像机。有东西进了取景框,破坏了镜头?没问题,Cinemachine会切换到下一个最佳摄像机。尤其适用于回放或任何一个可变场景的电影序列。

Timeline和Cinemachine结合使用,您可以将叙事带入更高的层次。使用后处理栈来进一步创建特效,烘托场景氛围和戏剧效果。
这里写图片描述

改进Post-processing栈(测试)

Post-processing将全屏滤镜和特效应用于摄像机的图像缓冲区,然后再将其显示在屏幕上。您可以使用图像后处理特效来模拟物理摄像机和电影效果。

最新版的Post-processing栈测试版可以在此下载。最终版预计将于今年夏季发布。(注意:上一个稳定版本可以在Asset Store资源商店中下载)

改进后的后处理栈将一组完整的图像效果整合到单个后期处理流程中,并带有一系列高质量的摄像机效果:

  • Screen-space anti-aliasing
  • Auto Exposure
  • Motion Blur
  • Bokeh Depth of Field
  • Bloom
  • Color Grading
  • Chromatic Aberration
  • Film Grain
  • Vignette

您可以将多个特效组合到单个Pass中,使用基于Asset的预设配置系统管理特效也非常轻松。

颜色分级效果是一种支持Academy Color Encoding System (ACES)的全HDR颜色管线,低端平台可以使用LDR管线。该栈有两个屏幕空间的光照特效,即环境光遮蔽和屏幕空间反射。

这个新版本还提供了一个基于体积的混合特性,您可以在场景中定义区域(任何类型的网格),并在玩家进入区域时设置特定的氛围/外观。Unity会自动在体积之间进行混合,以实现流畅的外观转换。
这里写图片描述

Unity Collaborate多人协作已正式发布!现为Unity Teams一员

Unity Collaborate多人协作已结束测试,与Cloud Build云构建一起成为Unity Teams的一部分,仅用一个解决方案一套功能,即可帮助您更快速地进行团队协作。Unity Teams将可免费使用至2017年10月。

点击了解有关Unity Teams的更多内容。

对于Collaborate多人协作,我们在Unity 2017.1中发布的首个发布版本优先处理了Beta用户提供的反馈。除了性能改进、稳定性和Bug修复之外,我们还增加了一组新功能:选择性推送、更佳的Asset浏览器集成和一个新的“In Progress”功能,用以标志团队成员在某个场景或预制件上有未发布的本地更改。
这里写图片描述

以下是我们为Collaborate多人协作添加的一些新功能:

  • In Progress标志
    为场景和预制件添加了In Progress标志,以指示团队中其他人已对某个场景或预制件做出了一些未发布的本地更改。这个特性有助于协作者协调对场景和预制件的更改。
    这里写图片描述
    这里写图片描述

  • 右键单击选择发布
    我们添加了右键单击操作,现在您可以在项目浏览器中直接发布、恢复、查看差异,解决文件冲突。这是一个主要的用户痛点源头,我们希望使Collaborate的行为与其他项目浏览器的行为更加一致。请注意,这种UX允许您选择性地发布已更改的Asset。之前的版本中,您必须发布所有更改。
    这里写图片描述

  • 浏览体验更佳
    在项目浏览器的“收藏”中添加了新的过滤器,包括“所有修改”、“所有被排除”和“所有冲突”,这样用户就可以看到他们所有修改过的文件、所有正在修改的文件、带有冲突的文件和忽略的文件。特别要留意的是“All in Progress(一切都在进行中)”,这让您可以实时看到Collaborate团队中的其他人正在处理哪些Asset(稍后将详细介绍)。
    这里写图片描述

  • 实时操作分析
    Unity 2017.1可以通过数据驱动的实时操作,随时获得丰富的分析数据。深入了解您的用户与您作品的互动情况,并实时做出相应的调整,迎合他们的习惯,无需重新部署新版本。在Unity 2017中,您可以更好地为用户提供更佳的游戏体验。
    通过Standard Events (目前是Beta版)可以进行更高效的洞察,它提供了一组精心设计的预定义事件,可揭示与您游戏相关的重要信息。使用新的Analytics Event Tracker,无需代码即可实现这些功能。
    这里写图片描述
    使用Remote Settings特性,可以即时更改游戏,无需重新部署,该特性已添加到Unity Analytics分析服务中。
    这里写图片描述

  • 2D改进
    在Unity 5.6中,我们为2D游戏开发者对工具和工作流程进行了重大改进。Unity 2017.1中引入了2D Sprite Atlas,这是一种新的Asset,将取代Sprite Packer。随着它的出现,新改进的工作流程可以在运行时更好地控制精灵的打包和使用。图集是Unity中2D工作流程的重要组成部分,而精灵图集不仅提供了更简单的图集创建和管理方式,还有相应的脚本API,可获得更多的控制和用途。
    这里写图片描述
    Sprite Masks用于在世界空间中隐藏或显示精灵或精灵组的一部分。精灵遮罩仅对拥有Sprite Renderer组件或粒子系统的对象生效。
    这里写图片描述
    在Unity 2017.1中,我们还为精灵编辑器添加了精灵物理形状。可以为精灵设置自定义的默认形状,以使用PolygonCollider2D生成碰撞器形状。

  • 动画改进
    我们对Animation窗口进行了全面修改,改进了关键帧的工作流程,使动画制作更方便和熟练,并支持与Animator状态机进行交互。Performance Recording是一个实验性功能。
    新的关键帧工作流程支持明确指定何时将哪帧变为关键帧,并在重新评估/预览动画时,将所有未修改且未关键帧化的属性值都丢弃。我们已经改变了在Animation窗口中编辑剪辑的默认行为(新的默认预览模式)、视觉反馈和全局关键帧操作热键。这些变化的目的是在Animation窗口之外为关键帧操作提供一个流畅的工作流程,同时预览动画剪辑无需处于自动关键帧或录制模式下。
    现在在编辑器中可以对状态机行为进行调试。
    我们还引入了GameObjectRecorder,这是一个新的实验性编辑器特性,它允许您记录GameObject和它子对象上的任何属性。这样就可以轻松地创建动画,将被记录的所有内容保存到一个动画剪辑中。欢迎访问论坛进行反馈。
    这里写图片描述

  • Playables已正式发布
    Playables API通过使用树状结构的PlayableGraph组织和评估数据来源,提供一种创建工具、特效或其他游戏机制的方法。PlayableGraph允许您混合和修改多个数据源,合成为单一输出后播放。
    Playables API支持动画、音频和脚本。Playables API还提供了通过脚本来与动画系统和音频系统进行交互的能力。
    Playable API是一个通用API,它最终将用于视频和其他系统。查看文档了解更多细节。

  • Ambisonic音频
    在Unity 2017.1中,我们增加了对环绕立体声音频剪辑的支持,这是全方位环绕音频技术,它(除了水平面外)还覆盖了听众上方和下方的声源。
    Ambisonics以多声道格式储存。它不是将每个通道都映射到一个特定的扬声器,而是以一种更通用的方式来表示声场。然后,根据聆听者的方向(即XR中用户的头部旋转),旋转声场。声场也可以被解码成一种与扬声器设置相匹配的格式。Ambisonics通常与360度视频结合使用,也可以用作音频天空盒,表现遥远的环境声音。
    我们还添加了Ambisonic解码器插件,而且现在也可以使用正开发中的API,在新的叙事工具Timeline中使用音频剪辑了。

  • 编辑器改进
    我们在UnityEditor.IMGUI.Controls中添加了一个新的ArcHandle类,它可以在场景视图中交互式地编辑弧线。还加入了名为SearchField的新IMGUI控件,它带有普通和工具栏用户界面风格,但也可以自行定制。
    这里写图片描述
    现在还支持使用JetBrains Rider作为外部脚本编辑器。
    其他改进还包括对所有播放器循环阶段添加分析器标签,改进Package Export加载状态,以及记录已连接玩家的日志信息,这些都将出现在编辑器控制台中,使调试更加轻松。

  • 改进了对Visual Studio的支持,包括Mac OS
    Unity安装程序现在可以选择在Windows上安装Visual Studio Community 2017(而非Visual Studio Community 2015)。安装速度显著提高也更轻量。
    Mac用户也别难过,现在可以使用Visual Studio了!微软发布了Mac版的Visual Studio和Tools for Unity。Visual Studio for Mac还提供了许多很酷的功能:一键调试,Unity消息的IntelliSense(完整Unity特定库代码),着色器代码高亮显示等等(点此查看详情)。

  • 场景与Asset Bundle改进
    我们对游戏中的场景和Asset Bundle进行了一些改进。更改底层架构使场景和Asset Bundle加载速度更快,从而使玩家体验更加流畅。我们还创建了一个工具,Asset Bundle浏览器——以帮助创建和优化Asset Bundle。

  • Asset Bundle浏览器
    Asset Bundle浏览器的Beta版与Unity 2017.1一同发布。该工具允许您在Unity项目中查看和编辑Asset Bundle的配置。它的目的是替换当前选择Asset的工作流,并在检视窗口中手动设置Asset Bundle的工作流程。现在您可以集中查看所有的Asset Bundle配置。通过使用上下文菜单和拖放功能,配置、修改和分析相关资源包。
    该工具将标记可能值得关注的警告,并提示将中断资源包创建的错误。从上层查看包集合,您可以更有效地组织Asset Bundle。在更低层查看单个Asset Bundle,您可以看到由于显式包含或依赖项的关系,哪些内容将会放入包中。
    更多细节请查阅文档
    这里写图片描述
    Asset Bundle浏览器可以从Asset Store资源商店下载。

  • 脚本运行时升级(实验性):畅享 C# 6和.NET 4.6
    在Unity 2017.1中,我们引入了实验性版本的脚本运行时内核,该内核已升级到Mono/.NET 4.6运行时。它包含了许多修复、性能改进,可以使用C# 6。我们相信它会提高游戏的整体性能。
    可以在Player Settings中启用.NET 4.6:
    这里写图片描述
    注意,更改该设置会在重启编辑器后生效,因为它会影响编辑器和播放器。对应的脚本API是PlayerSettings.scriptingRuntimeVersion属性。
    IL2CPP完全支持新的.NET 4.6 API,因此您仍可使用C#编写脚本,同时享有原生C++的性能优势。如果您发现任何问题,请访问论坛进行反馈。

  • 模型导入器改进
    从像Maya这样流行的数字内容创作(DCC)工具导入Asset的过程是首批重要的改进对象,这使得DCC工作流程变得更加轻松。最终提高了艺术家和设计师的生产力,减少了程序员的麻烦。
    现在Unity导入从Maya导出的FBX文件已支持Segment Scale Compensation,而且FBX SDK已升级至2016.1.2。
    在导入FBX文件时,我们还添加了计算加权法线的选项,如按面积、角度或二者皆有,以及硬边缘的固定法线生成。现在,可以从FBX文件中导入灯光和摄像机,Unity会自动在需要时为对象添加和配置摄像机和/或灯光组件。
    Unity现在可以使用“Import Visibility”属性从FBX文件中读取可见性属性。值和动画曲线将启用或禁用MeshRenderer组件:
    这里写图片描述

  • Progressive Lightmapper改进
    Unity 2017.1增加了Progressive Lightmapper中对烘焙LOD的支持。在烘焙LOD时,Enlighten和Progressive Lightmapper之间的主要区别在于,使用Progressive Lightmapper不必在LOD周围放置光照探针来获得反射光。在完全烘焙分辨率下,间接光照将为LOD提供更优质的烘焙光照贴图,您也可以避免为它们设置光照探针的繁琐过程。(Unity 5.6中也有此功能。)
    我们还在Progressive Lightmapper中增加了对双面材质的支持,通过添加新的材质设置,使光线与背面接触。启用后,在进行全局光照计算时几何体的两面都被包括在内。当从其他对象观察时,背面不会被认定为无效。背面渲染既不受该设置的控制,也不会在光照贴图中显示。背面使用与正面相同的自发光和漫反射设置反射光线。(该功能也可在Unity 5.6中使用)
    这里写图片描述

  • 实时阴影改进
    我们优化了在稳定模式下,级联定向光源阴影投射器的选择。这意味着生成阴影贴图时会产生更少的Draw Call。这增益是与场景和配置相关的。例如,在四个级联光的情况下,可以看到Draw Call数量显著下降。根据太阳/摄像机的方向,场景中可以减少50%的阴影投射器。下面是维京村庄的一个例子:
    下面的场景在Unity 5.6中有5718个阴影投射器。
    这里写图片描述
    在Unity 2017.1中,相同的场景,只有4807个阴影投射器。
    这里写图片描述
    Unity 2017.1还实现了实时阴影的Percentage Closer Filtering (PCF)。每个像素的深度值都是从当前像素周围的阴影贴图中取样,并所有的采样值进行比较。这使得光和影之间的线条更加平滑。您可以在下图中看到对比:
    这里写图片描述
    除了实时阴影改进,Shadowmask和Distance Shadowmask光照模式现在已成为Quality Setting中的参数,可以在运行时进行修改而无需任何成本。例如,可以在室内使用Shadowmask (实现柔和的阴影),并在相同关卡中的户外场景切换至distance Shadowmask。它也可以作为一个质量设置项。
    我们还添加了Custom Render纹理作为渲染纹理的扩展,可以很方便地用着色器来更新纹理。这有助于实现各种复杂的模拟,比如焦散光、雨滴涟漪模拟,墙面液体喷溅等等。它还提供了一个脚本和着色器框架,以便进行更复杂的配置,比如局部或多阶段更新,不同的更新频率等等。
    这里写图片描述
    有了新添加的LineUtility类和LineRenderer.Simplify函数,现在可以优化线条,用LineUtility创建由简单形状组成的简化版本。
    使用Metal/OpenGL ES3实现iOS上的Deferred Rendering
    我们为A8芯片和以后的iOS设备启用了一个使用Metal和OpenGL ES 3.0的延迟渲染路径。当使用延迟着色时,能够影响GameObject的灯光数量是没有限制的。所有的灯光都是按像素计算的,这意味着它们都能与法线贴图进行正确的交互等等。此外,所有的灯光都可以有剪影和阴影。

  • 粒子系统改进
    我们引入了精灵集成,粒子碰撞力(可以推动碰撞器),大量形状方面的改进,包括一个新的形状类型,噪音模块增加了新选项,以及其他一些较小的特性和增强。因为增加了新的控制和约束,例如速度与对齐,使得在2D中使用粒子更加轻松。可以使用粒子来获得比以往更多的特效和动画效果,包括光线的线条和尾迹。
    通过Texture Sheet Animation模块,我们在粒子系统中增加了对精灵使用的支持。这使粒子系统能更好地进行了图集处理和批处理,同时也在粒子系统中增加了大量与精灵相关的特性,例如不同大小的动画帧,以及每帧的轴心点。
    这里写图片描述
    这里写图片描述
    噪音模块提供了新的选项,可以更好地将噪音应用于粒子效果中。这个功能在Unity 5.5中第一次实现,噪音是被应用到粒子的位置属性。在2017.1中,我们可以将噪音应用到更多的地方:
    -位置
    -旋转
    -大小
    -使用Custom Vertex Streams的着色器(非常适合制作UV失真效果!)
    这里写图片描述
    在粒子系统形状模块的碰撞模式中,我们引入了一个新的甜甜圈粒子发射形状和编辑模式。模块内的Transform可以为粒子发射的形状应用自定义位置、旋转和缩放。
    其他的改进还包括将粒子与速度方向对齐的能力,以及允许在局部空间系统使用Emit over Distance。边缘粒子发射现在更加灵活,可以选择用来产生粒子的边缘厚度。
    粒子现在也可以使用碰撞模块对碰撞器进行施力。
    这里写图片描述

  • Windows Store现在改名为Universal Windows Platform
    Unity现在支持Windows商店的Universal Windows Platform(UWP)应用模式,支持为Xbox One、Windows 10、Windows Phone 10和HoloLens进行构建。
    请注意,对Windows混合现实PC设备的支持将在今年晚些时候发布。
    这里写图片描述
    我们增加了对UWP的多显示支持,现在Unity播放器二进制文件已做数字签名,增加了额外的一层安全性,可以防止对Unity运行时二进制文件进行篡改。
    最后,我们取消了对Windows 8.1和Windows Phone 8.1应用的支持,Unity 5.6是最后一个支持这两个平台的版本。

  • 索尼PS4的视频播放器
    我们在Unity 5.6中引入了一个全新的视频播放器,在Unity 2017.1中正式加入了对索尼PS4的支持,从而完成了对跨平台的支持。PS4的视频播放器使用索尼的AvPlayer库来加速h.264流的解码。解码h.264流(PS4的推荐格式)时,CPU开销非常低。可以同时对最多8个并发h.264流进行解码。它还支持对webm容器中的VP8格式流进行软件解码(更高的CPU开销)。最后,它支持多种视频渲染模式(直接渲染到摄像机的近/远平面,作为材质覆盖,或渲染纹理),音频流可以直接输出或发送到音频源进行混合。

  • 底层原生插件渲染扩展
    我们已经扩展了底层渲染插件API,并提供了一些很酷的新特性:
    -现在可以将用户数据发送到回调函数。
    -我们已经扩展了插件将接收回调的可能事件列表。
    -我们在着色器编译器进程中添加了钩子,可以在发送到编译器之前对着色器打补丁。支持创建自定义关键字所控制的自定义变体。
    -要想了解这些扩展的威力,请查看NVIDIA的VRWorks包,它是实现这一切的基石。

  • VR: NVIDIA VRWorks
    现在,在Unity 2017.1中,NVIDIA VRWorks通过以下特性,为虚拟现实提供了一种全新高度的视觉保真度、性能和响应能力:
    -Multi-Res Shading是一种用于VR的创新性渲染技术,它可以使图像的每一部分都能渲染在一个与镜头矫正图像像素密度相匹配的分辨率上。
    -Lens Matched Shading使用NVIDIA基于Pascal的GPU的新Simultaneous Multi-Projection架构,为像素着色提供潜在的性能改进。
    -Single Pass Stereo使用NVIDIA基于Pascal的GPU的新Simultaneous Multi-Projection架构,仅对几何体进行一次绘制,即可在双眼视图同时投射相同几何体。
    -VR SLI为虚拟现实应用程序提供更高的性能,其中两个GPU可以被指派给特定眼睛,极大地加速立体渲染。
    这里写图片描述
    为了更好地利用这些改进,应该在PC上使用GeForce 9系列或更高的GPU来进行回放。可以访问Asset Store资源商店下载NVIDIA VRWorks for Unity

  • 发布说明
    与往常一样,请查阅发布说明,以了解新特性、改进和修复的完整列表。

以上内容来源Unity官方中文社区,原帖地址:http://forum.china.unity3d.com/thread-25171-1-1.html
本文仅做转载和整理。

by:蒋志杰

2018-11-14 16:53:50 a380331382 阅读数 2701

Unity使用鼠标旋转缩放平移视角


用代码在Game界面完美实现Scene界面的操作方法。

使用方法:把脚本挂在相机上,把跟踪的target拖到脚本上。

视角跟踪的是一个空物体,当然如果你是做RPG游戏需要跟踪某一角色的视角,那就不需要中键平移功能,把空物体换成角色就行。

代码主要是分三部分功能进行实现。

  1. 右键拖动控制视角的旋转;
  2. 滚轮旋转控制视角的缩放;
  3. 中键拖动控制视角的平移。

右键拖动控制旋转主要是用GetAxis获得鼠标在x方向与y方向平移的距离,相机的旋转是通过旋转相机本体坐标系的x轴与y轴实现的,重要的是在旋转相机的同时,要控制相机和target物体的相对距离,即同时控制相机绕target物体的旋转。这个网上多数实现都相同,不赘述

中键滚轮控制视角的缩放,定义Distance变量控制相机与target的距离(相机z轴方向的距离),用GetAxis获得滚轮旋转的程度,控制Distance的变动。这里和网上已有的方法也没什么区别。

中键拖动控制视角的平移,之前在网上查找相关的实现,结果实际效果都比较差,所以自己实现了一下。视角的平移是通过获取中键在屏幕坐标系下的平移的方向向量,然后转换为世界坐标系下的target坐标的平移,然后调整相机的位置进行相应的平移以保证旋转和缩放不受影响。

屏幕坐标系的平移转换到世界坐标系下的平移,本质上就是世界坐标系下沿着相机的本体坐标系的x与y轴进行相应的平移。所以只需要求出屏幕坐标系x与y方向的平移,分别乘以相机x与y轴的方向向量,然后与target原来的坐标相加,就可以获得target平移后的位置,再将相机的位置平移过去即实现了视角的平移,这种平移保证了相机平面和target之间的相对距离保持不变。具体代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MouseLookTest : MonoBehaviour {

	//相机跟随的目标物体,一般是一个空物体
	public Transform target;
	private int MouseWheelSensitivity = 1; //滚轮灵敏度设置
	private int MouseZoomMin = 1; //相机距离最小值
	private int MouseZoomMax = 20; //相机距离最大值

	private float moveSpeed = 10; //相机跟随速度(中键平移时),采用平滑模式时起作用,越大则运动越平滑

	private float xSpeed = 250.0f; //旋转视角时相机x轴转速
	private float ySpeed = 120.0f; //旋转视角时相机y轴转速

	private int yMinLimit = -360;
	private int yMaxLimit = 360;

	private float x = 0.0f; //存储相机的euler角
	private float y = 0.0f; //存储相机的euler角

	private float Distance = 5; //相机和target之间的距离,因为相机的Z轴总是指向target,也就是相机z轴方向上的距离
	private Vector3 targetOnScreenPosition; //目标的屏幕坐标,第三个值为z轴距离
	private Quaternion storeRotation; //存储相机的姿态四元数
	private Vector3 CameraTargetPosition; //target的位置
	private Vector3 initPosition; //平移时用于存储平移的起点位置
	private Vector3 cameraX; //相机的x轴方向向量
	private Vector3 cameraY; //相机的y轴方向向量
	private Vector3 cameraZ; //相机的z轴方向向量

	private Vector3 initScreenPos; //中键刚按下时鼠标的屏幕坐标(第三个值其实没什么用)
	private Vector3 curScreenPos; //当前鼠标的屏幕坐标(第三个值其实没什么用)
	void Start () {
		//这里就是设置一下初始的相机视角以及一些其他变量,这里的x和y。。。是和下面getAxis的mouse x与mouse y对应
		var angles = transform.eulerAngles;
		x = angles.y;
		y = angles.x;
		CameraTargetPosition = target.position;
		storeRotation = Quaternion.Euler (y + 60, x, 0);
		transform.rotation = storeRotation; //设置相机姿态
		Vector3 position = storeRotation * new Vector3 (0.0F, 0.0F, -Distance) + CameraTargetPosition; //四元数表示一个旋转,四元数乘以向量相当于把向量旋转对应角度,然后加上目标物体的位置就是相机位置了
		transform.position = storeRotation * new Vector3 (0, 0, -Distance) + CameraTargetPosition; //设置相机位置

		// Debug.Log("Camera x: "+transform.right);
		// Debug.Log("Camera y: "+transform.up);
		// Debug.Log("Camera z: "+transform.forward);

		// //-------------TEST-----------------
		// testScreenToWorldPoint();

	}

	void Update () {
		//鼠标右键旋转功能
		if (Input.GetMouseButton (1)) {
			x += Input.GetAxis ("Mouse X") * xSpeed * 0.02f;
			y -= Input.GetAxis ("Mouse Y") * ySpeed * 0.02f;

			y = ClampAngle (y, yMinLimit, yMaxLimit);

			storeRotation = Quaternion.Euler (y + 60, x, 0);
			var position = storeRotation * new Vector3 (0.0f, 0.0f, -Distance) + CameraTargetPosition;

			transform.rotation = storeRotation;
			transform.position = position;
		} else if (Input.GetAxis ("Mouse ScrollWheel") != 0) //鼠标滚轮缩放功能
		{
			if (Distance >= MouseZoomMin && Distance <= MouseZoomMax) {
				Distance -= Input.GetAxis ("Mouse ScrollWheel") * MouseWheelSensitivity;
			}
			if (Distance < MouseZoomMin) {
				Distance = MouseZoomMin;
			}
			if (Distance > MouseZoomMax) {
				Distance = MouseZoomMax;
			}
			var rotation = transform.rotation;

			transform.position = storeRotation * new Vector3 (0.0F, 0.0F, -Distance) + CameraTargetPosition;
		}

		//鼠标中键平移
		if (Input.GetMouseButtonDown (2)) {
			cameraX = transform.right;
			cameraY = transform.up;
			cameraZ = transform.forward;

			initScreenPos = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, targetOnScreenPosition.z);
			Debug.Log ("downOnce");

			//targetOnScreenPosition.z为目标物体到相机xmidbuttonDownPositiony平面的法线距离
			targetOnScreenPosition = Camera.main.WorldToScreenPoint (CameraTargetPosition);
			initPosition = CameraTargetPosition;
		}

		if (Input.GetMouseButton (2)) {
			curScreenPos = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, targetOnScreenPosition.z);
			//0.01这个系数是控制平移的速度,要根据相机和目标物体的distance来灵活选择
			target.position = initPosition - 0.01f * ((curScreenPos.x - initScreenPos.x) * cameraX + (curScreenPos.y - initScreenPos.y) * cameraY);

			//重新计算位置
			Vector3 mPosition = storeRotation * new Vector3 (0.0F, 0.0F, -Distance) + target.position;
			transform.position = mPosition;

			// //用这个会让相机的平移变得更平滑,但是可能在你buttonup时未使相机移动到应到的位置,导致再进行旋转与缩放操作时出现短暂抖动
			//transform.position=Vector3.Lerp(transform.position,mPosition,Time.deltaTime*moveSpeed);

		}
		if (Input.GetMouseButtonUp (2)) {
			Debug.Log ("upOnce");
			//平移结束把cameraTargetPosition的位置更新一下,不然会影响缩放与旋转功能
			CameraTargetPosition = target.position;
		}

	}

	//将angle限制在min~max之间
	static float ClampAngle (float angle, float min, float max) {
		if (angle < -360)
			angle += 360;
		if (angle > 360)
			angle -= 360;
		return Mathf.Clamp (angle, min, max);
	}

	void testScreenToWorldPoint () {
		//第三个坐标指的是在相机z轴指向方向上的距离
		Vector3 screenPoint = Camera.main.WorldToScreenPoint (CameraTargetPosition);
		Debug.Log ("ScreenPoint: " + screenPoint);

		// var worldPosition = Camera.main.ScreenToWorldPoint(new Vector3(1,1,10));
		// Debug.Log("worldPosition: "+worldPosition);
	}
}

实现的效果如下图:
在这里插入图片描述

demo工程在此下载:
https://github.com/JinghanSun/MouseLookDemoWithUnity3D

初始Unity3D

阅读数 316

Unity3D

博文 来自: yangmeng13930719363
没有更多推荐了,返回首页