【几行代码】在VRTK中合并Teleport和Rotate操作

【几行代码】在VRTK中合并Teleport和Rotate操作_第1张图片

在VR的交互设计中,Teleport(闪现传送)是最常用的距离移动手段,SnapRotation(视角旋转)则是快速改变角度的手段(Rec Room中被大量使用),因此用户如需要关注远方某个物体则需要两步操作——1 先Teleport 2 然后SnapRotation。姑且不说SnapRotation容易产生眩晕,对于交互心理学上来说,“少即是好”。所以有同学提出能不能把这两个操作合并在一次操作。


之后【几行代码】专题的代码都遵守干净原则:1 代码量越少越好 2 不修改现有插件源代码和美术资源 3 独立成功能

依循干净原则的伪思路是

1 找到VRTK中Teleport的回调函数(Enter、Exit、Set)的信息,将Arrow箭头画在Enter期间

2 注册Touchpad上的触碰回调函数(TouchpadAxisChanged),改变Arrow的位置和记录旋转量

3 在Teleport触发Set时将旋转量赋予CameraRig(PS:这里CameraRig的旋转轴为代表眼睛的Camera(eye))


首先制作一张Arrow的贴图和一个Arrow的prefab,多几个面片无所谓的话,可以用一个Cube快速完成

【几行代码】在VRTK中合并Teleport和Rotate操作_第2张图片


【几行代码】在VRTK中合并Teleport和Rotate操作_第3张图片


然后贴上代码:

using UnityEngine;
using VRTK;

[RequireComponent(typeof(VRTK_Pointer))]
public class InteractionPoint : MonoBehaviour {

    VRTK_Pointer pointer;
    VRTK_ControllerEvents events; 

    [SerializeField]
    GameObject arrow;

    GameObject actualArrow;

    bool isEnter = false;
    float angleOffset = 0;

    private void Awake()
    {
        pointer = GetComponent();
        pointer.DestinationMarkerEnter += onEnter;
        pointer.DestinationMarkerExit += onExist;
        pointer.DestinationMarkerSet += onSet;

        events = GetComponent();
        events.TouchpadAxisChanged += DoRightTouchpadTouched;

        actualArrow = Instantiate(arrow);
        actualArrow.SetActive(false);
    }

    private void onEnter(object sender, DestinationMarkerEventArgs e)
    {
        actualArrow.SetActive(true);
        Vector3 position = e.destinationPosition;
        actualArrow.transform.position = position;

        Vector3 forward = VRInteractController.CameraRig.position - position;
        actualArrow.transform.forward = new Vector3(forward.x, 0, forward.z);
        float startAngle = actualArrow.transform.eulerAngles.y;
        actualArrow.transform.eulerAngles = new Vector3(0, startAngle + angleOffset, 0);

        isEnter = true;
    }

    private void onExist(object sender, DestinationMarkerEventArgs e)
    {
        actualArrow.SetActive(false);
        isEnter = false;
        angleOffset = 0;
    }

    private void onSet(object sender, DestinationMarkerEventArgs e)
    {
        if (pointer.enableTeleport)
            VRInteractController.CameraRig.RotateAround(VRInteractController.Head.position, Vector3.up, angleOffset);
    }

    private void DoRightTouchpadTouched(object sender, ControllerInteractionEventArgs e)
    {
        if (isEnter)
        {
            angleOffset = e.touchpadAngle;
        }
    }

}


(转载请注明出处http://blog.csdn.net/Poemlike_Studio)

你可能感兴趣的:(VR,Unity)