第一人称射击游戏实战——第一人称相机控制

第一人称射击游戏实战——第一人称相机控制

创建一个Camera,命名为FP_Camera,标签改为MainCamera,将Camera作为FP_Player的子物体。
并把position改成 X=0,Y=2,Z=-0.2
创建C#脚本 ,命名为fps_FPCamera

知识储备

1.Transform中的关于旋转
(1)Rotate
Transform.Rotate(enlerAngles:Vector3,relativeTo:Spave=Space.Self):void
作用:如果相对于留空或者设置为Space.Self,旋转角度Vector3被应用围绕自身轴做变换。如果相对于Space.World,旋转角度Vector3被应用围绕世界X,Y,Z轴。
(2)eulerAngle
Unity中默认的是先绕z轴,后x轴,后y轴的顺序欧拉旋转。这个要求是一个绝对值,注意:不要递增,不要超过360°。(注意:这不意味着单次的旋转角度不能超过360°,而是意味着即使超过了,需要做一个周期处理。因此属于(-360,360))
(3)rotation
旋转角度的存储用四元数。四元数是高阶的含有虚数的向量。我们可以将一个初始轴表示成四元数,也可以将一种绕某一个轴旋转一定角度的旋转变化表示成四元数。A*B表示对四元数B表示的轴经过四元数A表示的旋转变换得到了一个新的四元数(新的轴)。这就是左乘一个旋转变化可以得到新的轴。当然,本质上,每一个四元数都代表了一种旋转变换,我们将B这个初始轴,可以看成是物体围绕初始轴旋转了0度。因此B本身和A都是一种对物体的旋转变换。
注意区别:
1.Rotate是一种方法,而rotation是一种属性
2.Rotate的旋转可以是以自身坐标系或者世界坐标系。而rotation是针对世界坐标系。
3.Rotate的每一次旋转是在上一次的角度的基础上叠加,但是rotation的旋转是基于世界坐标系中初始状态一次性完成旋转。
2.Quaternion四元数的表示
Quaternion.AngleAxis(float angle,Vector3 axis)
作用:返回一个绕轴线axis旋转angle角度的四元数变换。
注意四元素的使用过程中,axis是一个单位向量。angle不能超过180°。
3.静态、动态欧拉角
静态欧拉角是相对于世界坐标系旋转,动态欧拉角是刚体自身作为参考系旋转。
4.世界坐标系与自身坐标表示方法
transform.up 世界坐标系Y轴
transform.right 世界坐标系 X轴
transform.forward 世界坐标系Z轴
Vector3.right 表示(1,0,0),物体右轴或者世界坐标X轴正方向
Vector3.left 表示(-1,0,0),物体左轴。。。
Vector3.up 表示(0,1,0),物体上轴。。。
Vector3.down 表示(0,-1,0),物体下轴。。。
Vector3.forward 表示(0,0,1),物体前轴。。。
Vector3.back 表示(0,0,-1),物体后轴。。。
注意Vextor3系列主要功能只是对于单位向量的简写,具体是世界坐标系还是自身坐标系,定义是不同的。
5.Mathf.Clamp(float value,float min,float max)
该函数做一个限制,返回
(1)max; value>max
(2)value; min<=value<=max
(3)min;value<=min
利用分段函数对value的值做一个限制。

编程思路

前面两个部分中,对于用户的输入进行判断,同时转化成Vector2或者bool量为fps_PlayerParamer中的定义人物参数做一个赋值。那么,人物参数inputSmoothLook也需要在相机控制中被用到。因此一定需要找标签为player的游戏对象上的组件。Vector2中的x和y实际上代表的是鼠标的x方向和y方向上的移动方向和量。那么需要分类讨论:如果移动的是x方向,视角左右旋转,可以通过控制人物或者是camera来控制。此时若围绕Vector3.up顺时针(俯视)为正方向,与鼠标移动的x正方向相对应。如果移动的是y方上下向,视图上下旋转,可以通过camera来控制。此时若围绕Vector3.right顺时针(俯视)为正方向,但是注意:与鼠标移动的y的负方向相对应,因此此时鼠标的移动量*灵敏度在转化成相机的转动量的过程中,需要对转动角度加一个负号。
另外,因为角度的表示不能超过360°,因此需要做周期性的处理。但是因为本游戏中基本都是用小角度旋转,因此只需要做一个周期即可。另外视角上具有一定的限制,例如控制相机抬头低头有一个限度,不能把脖子扭了。因此周期性处理完,就可以用Clamp的分段函数做一个限制。最后利用四元数完成旋转。
注意:四元数旋转对应最后的代码,其中第一个yQuaternion并非一定要加。如果加上去,相当于告诉transform的y方向上有自由度,但是自由度为0。如果不加,相当于没有自由度。虽然本质是一样的,不过加上去就相当于刻意强调了player父物体本身不能在y轴上有自由度(不能绕X轴翻转)。这样的话也提高了代码的可读性。最后这段代码其实就是表达鼠标的移动对应父物体player和子物体camera在两个方向上的自由度,只不过父物体的其中一个自由度为0。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Camera))]
public class fps_FPCamera:MonoBehaviour
{
	public Vector2 mouseLookSensitivity = new Vector2(5,5);//鼠标的灵敏度,主要有两个轴的灵敏度,因此用二维向量表示了。
	public Vector2 rotationXLimit = new Vector2(87,-87);//绕x轴旋转的角度(抬头低头)
	public Vector2 rotationYLimit = new Vector2(-360,360);//绕y轴旋转的角度(左转右转)
	public Vector3 positionOffset = new Vector3(0,2,-0.2f);//相机的初始位置
	private Vector2 currentMouseLook=Vector2.zero;//初始角度
	private float x_Angle=0;
	private float y_Angle=0;
	private fps_PlayerParameter parameter;
	private Transform m_Transform;
	void Start()
	{
		parameter = GameObject.FindGameObjectWithTag(Tag.player).GetComponent<fps_PlayerParameter>();
		m_Transform = transform;
		m_Transform = positionOffset;//初始位置
	}
	private void GetMouseLook()
	{
		currentMouseLook.x=parameter.inputSmoothLook.x;
		currentMouseLook.y=parameter.inputSmoothLook.y;
		currentMouseLook.x*=mouseLookSensitivity.x;
		currentMouseLook.y*=mouseLookSensitivity.y;
		currentMouseLook.y=-1;
		//若鼠标向X正方向移动,那么应该物体绕Y轴顺时针旋转,但是如果鼠标向Y正方向移动,那么应该物体绕X轴顺时针旋转,但是如果这样,就会实现低头操作。可是鼠标向Y正方向移动是为了实现抬头操作。因此需要乘上-1.
	}
	private void UpdateInput()
	{
		if(parameter.inputSmoothLook==Vector2.zero)
			return;
		GetMouseLook();
		y_Angle+=currentMouseLook.x;//每一次的移动都是在之前的基础上转动角度,因此X_Angle可以获得总的角度。
		x_Angle+=currentMouseLook.y;
		y_Angle=y_Angle<-360? y_Angle+=360:y_Angle;
		y_Angle=y_Angle>360? y_Angle-=360:y_Angle;
		y_Angle=Mathf.Clamp(y_Angle,rotationYLimit.x,rotationYLimit.y)
		x_Angle=x_Angle<-360? x_Angle+=360:x_Angle;
		x_Angle=x_Angle>360? x_Angle-=360:x_Angle;
		x_Angle=Mathf.Clamp(x_Angle,rotationXLimit.x,rotationXLimit.y)
	}
	void Update()
	{
		UpdateInput();
	}
	void LateUpdate()
	{
		Quaternion xQuaternion = Quaternion.AngleAxis(y_Axis,Verter3.up);
		Quaternion yQuaternion = Quaternion.AngleAxis(0,Verter3.right);
		m_transform.parent.rotation = xQuaternion*yQuaternion;
		yQuaternion = Quaternion.AngleAxis(x_Angle,Verter3.right);
		m_transform.rotation = xQuaternion*yQuaternion;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值