您的位置:首页 > 移动开发 > Unity3D

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元素就能够面对着玩家的身体正面进行转动,而不是围绕着玩家的头部进行旋转。
下面是我们需要声明的变量:
[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场景。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息