FPS相机

提要

FPS常用于FPS游戏中,Minecraft默认的视角也是第一人称的。在网上找了半天也没有找到比较好的现成的,还是自己写好了。



相机建模

不管是FPS相机还是TPS的相机,都包含了相机的两个操作,Yaw和Pitch



Roll在一些特殊情况下才会出现,比如角色死亡。


理论上只要只要Camera的position,yaw,pitch, roll,fov,就可以确定一个Viewport了。


角色结构

角色的层次结构应该是这样的:



最外层的Player,上面用来挂脚本。

里面有Model,就是角色的模型。

再有里面一个Capsule,用来处理移动和碰撞。

相机上有一个virtualPos,是相机的子物体,用来表示Model应该在的位置。

相机有一个Target变量,设为Capsule,还有一个offset表示和target之间的一个位移。


游戏的更新逻辑是这样的:

Input -> Capsule移动->更新Camera位置->更新Model位置。


代码片段

通过鼠标输入

rotationX = transform.localEulerAngles.y + Input.GetAxis("Mouse X") * sensitivityX;
rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
rotationY = Mathf.Clamp(rotationY, minimumY, maximumY);

这里用minimunY和maximumY来处理俯仰角的最大最小值,一般是不能超过90度的。


Update

transform.position = target.transform.localToWorldMatrix.MultiplyPoint3x4(FPSoffset);
transform.localEulerAngles = new Vector3(-rotationY, rotationX, 0);
target.forward = new Vector3(transform.forward.x, 0, transform.forward.z);

characterModel.transform.position = fpsVirtualTrans.position;
characterModel.transform.forward = fpsVirtualTrans.forward;


这里的localEulerAngles对应的就是角色的Pitch,Yaw, Roll。


移动端的控制

移动端主要依靠触屏的Drag手势来控制相机的Yaw和Pitch。

首先通过Delegate注册一下Drag事件。

void Start()
{
	GestureManager.Instance.DragEvent += RotateCamera;
}

接下来通过DragEvent提供的信息更新RotateX, RotateY

	void RotateCamera(DragEventData e, ref bool used)
	{
		float DeltaX = e.currentPosition.x - e.lastPosition.x;
		float DeltaY = e.currentPosition.y - e.lastPosition.y;
		UpdateYawPitch(DeltaX, DeltaY);
	}

	void UpdateYawPitch(float DeltaX, float DeltaY)
	{
		float fpsSensPara = 1.3f;
		
		if(GameManager.GetInstance().currentOperationMode == OperationMode.FPS) 
		{
			rotationX += DeltaX / Screen.dpi * sensitivityXmobile;
			rotationY += DeltaY / Screen.dpi * sensitivityYmobile;
		}
		else{
			rotationX += DeltaX / Screen.dpi * sensitivityXmobile * fpsSensPara;
			rotationY += DeltaY / Screen.dpi * sensitivityYmobile * fpsSensPara;
		}
		  
		if (rotationX > 360 || rotationX < -360)
		{
			rotationX = 0;
		}
		rotationY = Mathf.Clamp(rotationY, minimumY, maximumY);
	}

Screen.dpi * sensitivityXmobile, 这个项用来处理不同dpi的手机。


Update部分更新和pc端的一样。


可能遇到的一些问题

model插入到场景里的物体中

当角色太靠近场景中的物体时,角色的手部或者武器可能会插入到墙体中,解决方法是单独开一个相机用于model的渲染,并且把depth放到放到最后。


注意culling mask 和 Depth。



参考

Real-Time Cameras:A Guide for Game Designers and Developers

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值