标签:style blog http color os io 使用 ar strong
在开始今天的内容前,首先让我们来学习下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)
- {
-
- Vector3 targetDirection = new Vector3(horizontal, 0f, vertical);
-
-
- Quaternion targetRotation = Quaternion.LookRotation(targetDirection, Vector3.up);
-
-
- Quaternion newRotation = Quaternion.Lerp(rigidbody.rotation, targetRotation, turnSmoothing * Time.deltaTime);
-
-
- 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]
-
- 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();
-
- }
-
-
- 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;
- }
-
- 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);
- }
-
-
-
-
- }
这里很多朋友可能对我设置一个状态很不理解吧,这其实是为了让玩家有一个自由查看角色的机会,否则当玩家按下鼠标右键的话,角色就会转向相机正对着的位置,这样玩家就看不到角色的正面了。当然,这里用到了插值,这样能使角色在转身的时候平滑一点,效果会更好。
唉,
不知不觉已经这个时候了,开学已经一周了,这学期我们只上九周课,然后就是实习、毕设、找工作一大堆事情在等着我们。可是不知道为什么博主宿舍的同学居然
还能每天什么事情都不做,从早上一直看电视剧到晚上十点,虽然这件事情和博主没有什么关系吧,可是整个宿舍的人都安安静静地做着自己的事情,就有这么一个
人整天声音开得很大在那里外放,这样真的好吗?以前和这个人闹过一次,因为他聚了一帮人在宿舍打麻将,我觉得吵就说了他一顿,结果就和我僵上了。说真的,
博主对目前的专业真的没有什么情感,大学四年里最让博主开心的事情就是博主学会了好多自己想要学的东西,认识了几个不错的老师和朋友,仅此而已。或许我们
注定要越走越远吧,因为我们根本就不是同一种人。
前
几天网上有人通过博客联系到博主,希望博主能到他哪里工作,可惜博主目前仍然有一大堆的琐事缠身,不然离开这喧嚣吵闹的宿舍,去做博主喜欢的事情,去寻找
博主自己的梦想,博主相信,博主一定可以做得更好吧。人生或许就是这样,你越是在乎的可能越让你得不到,你无心插柳可能会得到一片绿荫。对于未来,不管怎
么样,坦然面对就好了,博主改变不了周围的这群人,只能努力地去改变自己。好了,晚安吧!
[Unity3D]Unity3D游戏开发之自由视角下的角色控制
标签:style blog http color os io 使用 ar strong
原文地址:http://www.cnblogs.com/yido9932/p/3961876.html