【Unity3D自学记录】Unity3D游戏开发之自由视角状态下的角色控制(一)

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

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

[csharp] view plaincopy
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. public class example : MonoBehaviour {  
  5.   
  6.     //水平速度  
  7.     public float HorizontalSpeed = 2.0F;  
  8.     //垂直速度  
  9.     public float VerticalSpeed = 2.0F;  
  10.   
  11.     void Update()   
  12.     {  
  13.         //水平方向  
  14.         float h = HorizontalSpeed * Input.GetAxis("Mouse X");  
  15.         //垂直方向  
  16.         float v = VerticalSpeed * Input.GetAxis("Mouse Y");  
  17.         //旋转  
  18.         transform.Rotate(v, h, 0);  
  19.     }  
  20. }  
这段脚本呢是根据鼠标的位置来旋转物体从而实现对物体的观察,从这段脚本中我们可以看出,通过获取输入轴的办法,我们可以获得鼠标移动的方向进而实现对于物体的旋转控制。在Unity3D中我们可以通过Edit->Project Setting->Input来查看项目中的坐标轴名称:


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


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

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

    

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

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


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


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

[csharp] view plaincopy
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. public class NoLockiVew_Player : MonoBehaviour {  
  5.   
  6.     /*自由视角下的角色控制*/  
  7.     /*作者:秦元培*/  
  8.   
  9.     //玩家的行走速度  
  10.     public float WalkSpeed=1.5F;  
  11.     //重力  
  12.     public float Gravity=20;  
  13.   
  14.     //角色控制器  
  15.     private CharacterController mController;  
  16.     //动画组件  
  17.     private Animation mAnim;  
  18.     //玩家方向,默认向前  
  19.     private DirectionType mType=DirectionType.Direction_Forward;  
  20.   
  21.     [HideInInspector]  
  22.     //玩家状态,默认为Idle  
  23.     public PlayerState State=PlayerState.Idle;  
  24.   
  25.     //定义玩家的状态枚举  
  26.     public enum PlayerState  
  27.     {  
  28.         Idle,  
  29.         Walk  
  30.     }  
  31.   
  32.     //定义四个方向的枚举值,按照逆时针方向计算  
  33.     protected enum DirectionType  
  34.     {  
  35.         Direction_Forward=90,  
  36.         Direction_Backward=270,  
  37.         Direction_Left=180,  
  38.         Direction_Right=0  
  39.     }  
  40.       
  41.     void Start ()   
  42.     {  
  43.        //获取角色控制器  
  44.        mController=GetComponent<CharacterController>();  
  45.        //获取动画组件  
  46.        mAnim=GetComponentInChildren<Animation>();  
  47.     }  
  48.       
  49.       
  50.     void Update ()   
  51.     {  
  52.         MoveManager();  
  53.         //MouseEvent();  
  54.     }  
  55.   
  56.     //玩家移动控制  
  57.     void MoveManager()  
  58.     {  
  59.         //移动方向  
  60.         Vector3 mDir=Vector3.zero;  
  61.         if(mController.isGrounded)  
  62.         {  
  63.             //将角色旋转到对应的方向  
  64.             if(Input.GetAxis("Vertical")==1)  
  65.             {  
  66.                 SetDirection(DirectionType.Direction_Forward);  
  67.                 mDir=Vector3.forward * Time.deltaTime * WalkSpeed;  
  68.                 mAnim.CrossFade("Walk",0.25F);  
  69.                 State=PlayerState.Walk;  
  70.             }  
  71.             if(Input.GetAxis("Vertical")==-1)  
  72.             {  
  73.                 SetDirection(DirectionType.Direction_Backward);  
  74.                 mDir=Vector3.forward * Time.deltaTime * WalkSpeed;  
  75.                 mAnim.CrossFade("Walk",0.25F);  
  76.                 State=PlayerState.Walk;  
  77.             }  
  78.             if(Input.GetAxis("Horizontal")==-1)  
  79.             {  
  80.                 SetDirection(DirectionType.Direction_Left);  
  81.                 mDir=Vector3.forward * Time.deltaTime * WalkSpeed;  
  82.                 mAnim.CrossFade("Walk",0.25F);  
  83.                 State=PlayerState.Walk;  
  84.             }  
  85.             if(Input.GetAxis("Horizontal")==1)  
  86.             {  
  87.                 SetDirection(DirectionType.Direction_Right);  
  88.                 mDir=Vector3.forward * Time.deltaTime * WalkSpeed;  
  89.                 mAnim.CrossFade("Walk",0.25F);  
  90.                 State=PlayerState.Walk;  
  91.             }  
  92.             //角色的Idle动画  
  93.             if(Input.GetAxis("Vertical")==0 && Input.GetAxis("Horizontal")==0)  
  94.             {  
  95.                 mAnim.CrossFade("Idle",0.25F);  
  96.                 State=PlayerState.Idle;  
  97.             }  
  98.   
  99.         }  
  100.         //考虑重力因素  
  101.         mDir=transform.TransformDirection(mDir);  
  102.         float y=mDir.y-Gravity *Time.deltaTime;  
  103.         mDir=new Vector3(mDir.x,y,mDir.z);  
  104.         mController.Move(mDir);  
  105.     }  
  106.   
  107.     //设置角色的方向,有问题  
  108.     void SetDirection(DirectionType mDir)  
  109.     {  
  110.         if(mType!=mDir)  
  111.         {  
  112.             transform.Rotate(Vector3.up*(mType-mDir));  
  113.             mType=mDir;  
  114.         }  
  115.     }  
  116. }  

猜你喜欢

转载自blog.csdn.net/hackdjh/article/details/39893959