UnityVR.05如何实现VR第一人称射击行为
2017-05-02 16:06
239 查看
【学习项目为Unity官方的VR Smaples,可以在Asset Store下载】
【参考官方学习教程Unity.learn.Virtual Reality】
VR射击游戏之中,准心是随着玩家的头部转动进行瞄准的,当准心落在了某个可射击对象时,再按下开火键,即可实现VR游戏的瞄准射击行为。在这个过程中,我们要考虑的是,包含玩家血量、得分的一些信息UI应该是随着玩家视野的转动而跟随变动的,而一些可被射击的对象则是静止不动的,下面通过具体的代码来讲解一下关键的地方。
1.让信息UI跟随着摄像机旋转
想象一下我们需要实现的效果,当玩家站在水平面上时,敌人出现在四面八方,这时候我们通过转动身体来寻找前后左右的敌人进行射击。这个过程中,一些得分之类的UI信息也同步显示在玩家的视野中。
不过需要注意的是,当玩家进行抬头和低头的动作时,如果这些信息UI也跟随上下浮动,从游戏设计上来说,没有必要,因为我们不需要面对来自头顶和地面的敌人,同时为了保证游戏界面的稳定以防玩家不会轻易产生眩晕感,我们可以将这些UI元素的Y轴坐标固定不动。
这样这些UI元素就能够面对着玩家的身体正面进行转动,而不是围绕着玩家的头部进行旋转。
下面是我们需要声明的变量:
在游戏开始运行时,在Start方法中,存储下摄像机和UI元素的距离,用来在游戏时,UI元素旋转时能和摄像机的距离保持不变。
下面是具体的实现方法:
Vector3.ProjectOnPlane 将向量投影到由以另一个向量为法线定义的平面上
2.让武器跟随者玩家的视野改变朝向
我们要实现的效果如上图所示,武器要随着摄像机的朝向改变自己的朝向,下面是实现这个行为的具体代码:
//这个脚本应该与射击的武器的父级进行关联
private void Update()
{
// 武器父级的朝向插值转向头部朝着的方向
transform.rotation = Quaternion.Slerp(transform.rotation, InputTracking.GetLocalRotation(VRNode.Head),
m_Damping * (1 - Mathf.Exp(k_DampingCoef * Time.deltaTime)));
// 武器的位置与摄像机的位置保持一致
transform.position = m_CameraTransform.position;
// 通过准心与武器的位置来确定武器的朝向
Quaternion lookAtRotation = Quaternion.LookRotation (m_Reticle.ReticleTransform.position - m_GunContainer.position);
// 武器的朝向向着朝准心的方向进行插值旋转
m_GunContainer.rotation = Quaternion.Slerp (m_GunContainer.rotation, lookAtRotation,
m_GunContainerSmoothing * Time.deltaTime);
}
InputTracking.GetLocalRotation(VRNode.Head) 根据VR头部设备的转向,返回一个四元数
通过以上两步我们就可以实现VR中第一人称的射击行为,具体的实例可以参看官方示例VR Samples中的Shooter360场景。
【参考官方学习教程Unity.learn.Virtual Reality】
VR射击游戏之中,准心是随着玩家的头部转动进行瞄准的,当准心落在了某个可射击对象时,再按下开火键,即可实现VR游戏的瞄准射击行为。在这个过程中,我们要考虑的是,包含玩家血量、得分的一些信息UI应该是随着玩家视野的转动而跟随变动的,而一些可被射击的对象则是静止不动的,下面通过具体的代码来讲解一下关键的地方。
1.让信息UI跟随着摄像机旋转
想象一下我们需要实现的效果,当玩家站在水平面上时,敌人出现在四面八方,这时候我们通过转动身体来寻找前后左右的敌人进行射击。这个过程中,一些得分之类的UI信息也同步显示在玩家的视野中。
不过需要注意的是,当玩家进行抬头和低头的动作时,如果这些信息UI也跟随上下浮动,从游戏设计上来说,没有必要,因为我们不需要面对来自头顶和地面的敌人,同时为了保证游戏界面的稳定以防玩家不会轻易产生眩晕感,我们可以将这些UI元素的Y轴坐标固定不动。
这样这些UI元素就能够面对着玩家的身体正面进行转动,而不是围绕着玩家的头部进行旋转。
下面是我们需要声明的变量:
[SerializeField] private bool m_LookatCamera = true; // UI元素是否应该面对着摄像机 [SerializeField] private Transform m_UIElement; // 引用这些要旋转UI元素 [SerializeField] private Transform m_Camera; // 引用摄像机 [SerializeField] private bool m_RotateWithCamera; // UI元素是否应该随着摄像机旋转 [SerializeField] private float m_FollowSpeed = 10f; // UI元素的跟随速度 private float m_DistanceFromCamera; // UI元素和摄像机的保持距离
在游戏开始运行时,在Start方法中,存储下摄像机和UI元素的距离,用来在游戏时,UI元素旋转时能和摄像机的距离保持不变。
private void Start () { m_DistanceFromCamera = Vector3.Distance (m_UIElement.position, m_Camera.position); }
下面是具体的实现方法:
private void Update() { if(m_LookatCamera) //UI元素的自身,面对着摄像机保持朝向 m_UIElement.rotation = Quaternion.LookRotation(m_UIElement.position - m_Camera.position); if (m_RotateWithCamera) { //相机朝向的方向向量在水平面上的投影 Vector3 targetDirection = Vector3.ProjectOnPlane (m_Camera.forward, Vector3.up).normalized; // 计算出UI元素要移动到的目标位置 Vector3 targetPosition = m_Camera.position + targetDirection * m_DistanceFromCamera; // UI元素由当前点向目标点进行插值移动 targetPosition = Vector3.Lerp(m_UIElement.position, targetPosition, m_FollowSpeed * Time.deltaTime); // UI元素在XZ水平面上进行旋转,Y轴坐标值保持不变 targetPosition.y = m_UIElement.position.y; // Set the UI's position to the calculated target position. m_UIElement.position = targetPosition; } }
Vector3.ProjectOnPlane 将向量投影到由以另一个向量为法线定义的平面上
2.让武器跟随者玩家的视野改变朝向
我们要实现的效果如上图所示,武器要随着摄像机的朝向改变自己的朝向,下面是实现这个行为的具体代码:
//这个脚本应该与射击的武器的父级进行关联
private void Update()
{
// 武器父级的朝向插值转向头部朝着的方向
transform.rotation = Quaternion.Slerp(transform.rotation, InputTracking.GetLocalRotation(VRNode.Head),
m_Damping * (1 - Mathf.Exp(k_DampingCoef * Time.deltaTime)));
// 武器的位置与摄像机的位置保持一致
transform.position = m_CameraTransform.position;
// 通过准心与武器的位置来确定武器的朝向
Quaternion lookAtRotation = Quaternion.LookRotation (m_Reticle.ReticleTransform.position - m_GunContainer.position);
// 武器的朝向向着朝准心的方向进行插值旋转
m_GunContainer.rotation = Quaternion.Slerp (m_GunContainer.rotation, lookAtRotation,
m_GunContainerSmoothing * Time.deltaTime);
}
InputTracking.GetLocalRotation(VRNode.Head) 根据VR头部设备的转向,返回一个四元数
通过以上两步我们就可以实现VR中第一人称的射击行为,具体的实例可以参看官方示例VR Samples中的Shooter360场景。
相关文章推荐
- WCF技术剖析之二十四: ServiceDebugBehavior服务行为是如何实现异常的传播的?
- 写给VR手游开发小白的教程:(七)Cardboard如何实现沉浸式VR体验之扭曲矫正和FOV匹配
- WCF技术剖析之二十四: ServiceDebugBehavior服务行为是如何实现异常的传播的?
- 写给VR手游开发小白的教程:(八)最终篇:Cardboard如何实现沉浸式VR体验之头部跟踪和Gaze的实现
- 前端开发如何实现结构、样式、行为彻底分离
- 写给VR手游开发小白的教程:(六)Cardboard如何实现沉浸式VR体验之构造双眼
- unity3d完成VR手柄第一人称射击小游戏(纯代码)
- python 7-1 如何派生内置不可变类型(int,str,tuple,float)并修改实例化行为,继承内置tuple并实现__new__
- 虚拟桌面如何实现动态行为审计
- 用VR观看LoL,这到底是如何实现的
- 在Java程序,如何实现自适应位置的快捷菜单
- 在32位程序中如何实现进程间通讯
- [导入]如何在VC中实现动态菜单
- 如何点对点实现多线程断点续传
- 如何实现应用程序中的”回车”成TAB?
- 如何实现win9X进程间数据通讯技术
- 如何利用C++ Builder 5.0 实现屏幕保护程序的开发
- 如何在应用程序中实现关机功能
- 如何实现Iframe透明
- 如何在程序中实现XP模式