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

来源:互联网 发布:科比本赛季数据 编辑:程序博客网 时间:2024/06/13 10:06


在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快速完成





然后贴上代码:

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<VRTK_Pointer>();        pointer.DestinationMarkerEnter += onEnter;        pointer.DestinationMarkerExit += onExist;        pointer.DestinationMarkerSet += onSet;        events = GetComponent<VRTK_ControllerEvents>();        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)

阅读全文
0 0
原创粉丝点击