Unity2017-HTC项目串流Pico摇杆移动功能
阅读原文时间:2023年07月08日阅读:2

最近公司PC项目需要串流到Piconec3上运行,HTC手柄是圆盘键按下移动还可以,但是Piconeo3是摇杆,按下移动的话显得不科学,所以写了一套基于圆盘键,使用摇杆移动的方法

第一步:编写摇杆左右旋转功能

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using HTC.UnityPlugin.Vive;
using UnityEngine.UI;
using DG.Tweening;

public class RockerTest : MonoBehaviour {

public Text hint;  
public Transform VR\_Head;  
public GameObject rightRay;  
// Use this for initialization  
void Start () {

}

bool isRotate = true;  
// Update is called once per frame  
void Update () {  
    Vector2 rightPos = ViveInput.GetPadAxis(HandRole.RightHand);

    if (isRotate && Mathf.Abs(rightPos.x)>.7f)  
    {  
        rightRay.SetActive(false);  
        isRotate = false;  
        Invoke("ResetRotate",1);  
        if (rightPos.x>0)  
        {  
            hint.text += "—向右旋转";  
            Debug.Log("向右旋转");  
            VR\_Head.rotation = Quaternion.AngleAxis(30, Vector3.up) \* VR\_Head.rotation;  
            //VR\_Head.DORotateQuaternion(Quaternion.AngleAxis(30, Vector3.up) \* VR\_Head.transform.rotation,1);  
        }  
        else  
        {  
            hint.text += "—向左旋转";  
            Debug.Log("向左旋转");  
            VR\_Head.rotation = Quaternion.AngleAxis(-30, Vector3.up) \* VR\_Head.rotation;  
            //VR\_Head.DORotateQuaternion(Quaternion.AngleAxis(-30, Vector3.up) \* VR\_Head.transform.rotation, 1);  
        }  
    }

}  
void ResetRotate() {  
    isRotate = true;  
    rightRay.SetActive(true);  
}  

}

第二步:移动功能,修改原HTC自带的脚本ViveInputVirtualButton

第二步修改完以后发现它只是能够显示与隐藏射线,真实的移动在Teleportable脚本里边

第三步,修改移动脚本如下,Unity属性面板选择PadTouch选项

//========= Copyright 2016-2017, HTC Corporation. All rights reserved. ===========

using HTC.UnityPlugin.Vive;
using System.Collections;
using UnityEngine;
using UnityEngine.EventSystems;

public class Teleportable : MonoBehaviour
, IPointerExitHandler
{
public enum TeleportButton
{
Trigger,
Pad,
Grip,
PadTouch,
}

public Transform target;  // The actual transfrom that will be moved Ex. CameraRig  
public Transform pivot;  // The actual pivot point that want to be teleported to the pointed location Ex. CameraHead  
public float fadeDuration = 0.3f;

public TeleportButton teleportButton = TeleportButton.Pad;

private Coroutine teleportCoroutine;

public ControllerButton teleportViveButton  
{  
    get  
    {  
        switch (teleportButton)  
        {  
            case TeleportButton.PadTouch:  
                return ControllerButton.PadTouch;

            case TeleportButton.Pad:  
                return ControllerButton.Pad;

            case TeleportButton.Grip:  
                return ControllerButton.Grip;

            case TeleportButton.Trigger:  
            default:  
                return ControllerButton.Trigger;  
        }  
    }  
}  

#if UNITY_EDITOR
private void Reset()
{
FindTeleportPivotAndTarget();
}
#endif
private void FindTeleportPivotAndTarget()
{
foreach (var cam in Camera.allCameras)
{
if (!cam.enabled) { continue; }
#if UNITY_5_4_OR_NEWER
// try find vr camera eye
if (cam.stereoTargetEye != StereoTargetEyeMask.Both) { continue; }
#endif
pivot = cam.transform;
target = cam.transform.root == null ? cam.transform : cam.transform.root;
}
}

public void OnPointerExit(PointerEventData eventData)  
{  
    Debug.Log("释放触摸");  
    // skip if it was teleporting  
    if (teleportCoroutine != null) { return; }

    // don't teleport if it was not releasing the button  
    //if (eventData.eligibleForClick) { return; }

    //VivePointerEventData viveEventData;  
    //if (!eventData.TryGetViveButtonEventData(out viveEventData)) { return; }

    //if (viveEventData.viveButton != teleportViveButton) { return; }

    var hitResult = eventData.pointerCurrentRaycast;  
    if (!hitResult.isValid) { return; }

    if (target == null || pivot == null)  
    {  
        FindTeleportPivotAndTarget();  
    }

    var headVector = Vector3.ProjectOnPlane(pivot.position - target.position, target.up);  
    var targetPos = hitResult.worldPosition - headVector;

    teleportCoroutine = StartCoroutine(StartTeleport(targetPos, fadeDuration));  
}  

#if VIU_STEAMVR
private bool m_steamVRFadeInitialized;

public IEnumerator StartTeleport(Vector3 position, float duration)  
{  
    var halfDuration = Mathf.Max(0f, duration \* 0.5f);

    if (!Mathf.Approximately(halfDuration, 0f))  
    {  
        if (!m\_steamVRFadeInitialized)  
        {  
            // add SteamVR\_Fade to the last rendered stereo camera  
            var fadeScripts = FindObjectsOfType<SteamVR\_Fade>();  
            if (fadeScripts == null || fadeScripts.Length <= 0)  
            {  
                var topCam = SteamVR\_Render.Top().gameObject;  
                if (topCam != null)  
                {  
                    topCam.gameObject.AddComponent<SteamVR\_Fade>();  
                }  
            }

            m\_steamVRFadeInitialized = true;  
        }

        SteamVR\_Fade.Start(new Color(0f, 0f, 0f, 1f), halfDuration);  
        yield return new WaitForSeconds(halfDuration);  
        yield return new WaitForEndOfFrame(); // to avoid from rendering guideline in wrong position  
        target.position = position;  
        SteamVR\_Fade.Start(new Color(0f, 0f, 0f, 0f), halfDuration);  
        yield return new WaitForSeconds(halfDuration);  
    }  
    else  
    {  
        yield return new WaitForEndOfFrame(); // to avoid from rendering guideline in wrong position  
        target.position = position;  
    }

    teleportCoroutine = null;  
}  

#else
public IEnumerator StartTeleport(Vector3 position, float duration)
{
var halfDuration = Mathf.Max(0f, duration * 0.5f);

    if (!Mathf.Approximately(halfDuration, 0f))  
    {  
        Debug.LogWarning("SteamVR plugin not found! install it to enable SteamVR\_Fade!");  
        fadeDuration = 0f;  
    }

    yield return new WaitForEndOfFrame(); // to avoid from rendering guideline in wrong position  
    target.position = position;

    teleportCoroutine = null;  
}  

#endif
}
//进行测试,旋转与移动都可以正常运行了