VRTK3.3射线用代码控制

要想用代码控制射线,首先要搞清楚射线是怎么形成的,射线有主要是组件vrtk_pointer和组件vrtk_UIPoinrer, 组件vrtk_pointer是发射一条可见的渲染射线并不能点击UI,就是给你看的,实际与UI产生交互的是vrtk_UIPoinrer组件,组件vrtk_UIPoinrer是发射一条不可见但可与UI交互的射线,SteamVR Home的射线效果就是由一条不可见但可与UI交互的射线实时检测,射线是否在UI上,是在UI上则显示一条可见的渲染射线,否则隐藏。

以下是vrtk_UIPoinrer组件源码,则可调用PointerActive()函数判断是否发射一条不可见但可UI交互的射线:

以下是vrtk_pointer组件源码,则可调用IsPointerActive()函数判断是否发射一条可见但不可UI交互的渲染射线及用Toggle()函数控制射线开启与关闭:

 

则可如下设置:

 

不用手柄的按钮来改变射线的状态,两个的ActivationButton都设为Undefined,这样vrtk_UIPoinrer组件只要将ActivationMode在HoldButton与AlwaysOn的切换,就可以让这不可见的射线是启用或关闭,组件vrtk_pointer则用IsPointerActive()函数和Toggle()函数,来控制这渲染射线的开启或关闭。

核心代码,如下:

       
    //当前射线组件
    static VRTK_Pointer vRTK_Pointer;
    //实际UI射线组件
    static VRTK_UIPointer vRTK_UIPointer;
    //右手控制器
    VRTK_ControllerEvents controllerEvents;
 void OnEnable()
    {
        //获取射线组件
        vRTK_Pointer = GetComponent<VRTK_Pointer>();
        //实际UI射线
        vRTK_UIPointer = GetComponent<VRTK_UIPointer>();
        //获取手柄控制器
        controllerEvents = GetComponent<VRTK_ControllerEvents>();
    }



/// <summary>
    /// 开启或关闭射线
    /// </summary>
    /// <param name="isBool">是否开启射线</param>
    
public static void vRTKPointer(bool isBool)
{
        bool b = vRTK_Pointer.IsPointerActive();
        //实际射线模式切换
        vRTK_UIPointer.activationMode=isBool? VRTK_UIPointer.ActivationMethods.AlwaysOn:     VRTK_UIPointer.ActivationMethods.HoldButton;
        //已经开启则返回,未开启则继续
        if (isBool ? b : !b) return;
        //渲染射线状态切换操作
        vRTK_Pointer.Toggle(true);
        vRTK_Pointer.Toggle(false);
    }

只要挂载脚本,则可以控制射线的开启和关闭。

完整的脚本:

using UnityEngine;
using VRTK;

public class rightControllerEvent : MonoBehaviour
{
    //当前射线组件
    static VRTK_Pointer vRTK_Pointer;
    //当前射线渲染组件
    static VRTK_StraightPointerRenderer vRTK_StraightRenderer;
    //实际UI射线组件
    static VRTK_UIPointer vRTK_UIPointer;
    //右手控制器
    VRTK_ControllerEvents controllerEvents;
    //若该键被禁用,则返回
    public static bool isDisableTouch;
    //当前是否有其它UI占用
    public static bool isOccupyUI;
    //记录菜单键
    public static bool isPressed;
    public GameObject[] gameObjects;

    void OnEnable()
    {
        isPressed = true;
        //获取射线组件
        vRTK_Pointer = GetComponent<VRTK_Pointer>();
        //获取射线渲染组件
        vRTK_StraightRenderer = GetComponent<VRTK_StraightPointerRenderer>();
        //实际UI射线
        vRTK_UIPointer = GetComponent<VRTK_UIPointer>();
        //获取手柄控制器
        controllerEvents = GetComponent<VRTK_ControllerEvents>();

        //防止有UI时,手柄断开射线失效
        foreach (GameObject go in gameObjects)
        {
            if (go.activeSelf)
            {
                vRTK_Pointer.activateOnEnable = true;
                break;
            }
        }
        if (controllerEvents == null)
            return;
        controllerEvents.ButtonTwoPressed += DoButtonTwoPressed;
        controllerEvents.TriggerPressed += DoTriggerPressed;
    }
    void OnDisable()
    {
        vRTK_Pointer.activateOnEnable = false;
        if (controllerEvents == null)
            return;
        controllerEvents.ButtonTwoPressed -= DoButtonTwoPressed;
        controllerEvents.TriggerPressed -= DoTriggerPressed;
    }


    public static void setvRTK_StraightRenderer(int n=0)
    {
        float[] raySizeArr = { 0.0012f, 0.0008f };
        vRTK_StraightRenderer.scaleFactor = raySizeArr[n];
    }
    /// <summary>
    /// 开启或关闭射线
    /// </summary>
    /// <param name="isBool">是否开启射线</param>
    public static void vRTKPointer(bool isBool)
    {
        bool b = vRTK_Pointer.IsPointerActive();
        //实际射线模式切换
        vRTK_UIPointer.activationMode=isBool? VRTK_UIPointer.ActivationMethods.AlwaysOn: VRTK_UIPointer.ActivationMethods.HoldButton;
        //已经开启则返回,未开启则继续
        if (isBool ? b : !b) return;
        //渲染射线状态切换操作
        vRTK_Pointer.Toggle(true);
        vRTK_Pointer.Toggle(false);
    }
    //菜单
    void DoButtonTwoPressed(object sender, ControllerInteractionEventArgs e)
    {
        //UI是否被占用,是则返回
        if (isOccupyUI) return;
        //菜单UI与射线的启用
        UIManager.Instance.setUI(1, isPressed);
        vRTKPointer(isPressed);
        isPressed = !isPressed;
    }

    public static void EnableButtonTwo(bool isBool)
    {
        if (isBool)
        {
            //不给调用菜单UI
            isOccupyUI = true;
            //关闭菜单UI
            UIManager.Instance.setUI(1, false);
        }
        else
        {
            //射线关闭
            vRTKPointer(false);
            //设为可触发
            isPressed = true;
            //给调用菜单UI
            isOccupyUI = false;
        }
    }

    //Trigger键
    void DoTriggerPressed(object sender, ControllerInteractionEventArgs e)
    {
        //若该键被禁用,则返回
        if (isDisableTouch) return;
        switch (Manager.controllerStruct.interactObjectType) 
        {
            case InteractObjectType.Touch:
                Manager.manageInvoke();
                break;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_39858654/article/details/127446406
3.3