国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Unity中使用VR手柄射線觸發(fā)UI事件

這篇具有很好參考價值的文章主要介紹了Unity中使用VR手柄射線觸發(fā)UI事件。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

創(chuàng)建射線檢測,確定起點和終點

public class LineController : SingletonMono<LineController>
{
    //屬性
    [HideInInspector] public Vector3 pointStartPos, pointEndPos;
    [HideInInspector] public Vector3 lineDirection;
    [HideInInspector] public float lineRealLength;
    public Hand hand;
    public float rayLength = 20.0f;
    public LayerMask layerMask;

    //private UITriggerSystem currentTarget;
    private IEventHandle_VR currentTarget;
    /// <summary>
    /// 當前是否有觸發(fā)對象
    /// </summary>
    public bool hasTarget
    {
        get { return currentTarget != null; }
    }

    //委托
    public Action OnEnterEvent;
    public Action OnExitEvent;
    public Action OnClickEvent;
    public Action<bool> OnActiveEvent;

    [HideInInspector] public bool active;
    private bool tempLineActive;

    public SteamVR_Action_Boolean menuAction = SteamVR_Input.GetAction<SteamVR_Action_Boolean>("Menu");
    public SteamVR_Action_Boolean teleportAction = SteamVR_Input.GetAction<SteamVR_Action_Boolean>("Teleport");

    private IEventHandle_VR currentObj;
    private IEventHandle_VR pressObj;
    void Start()
    {
        hand = Player.instance.rightHand;
    }

    void Update()
    {
        //判斷是否觸發(fā)圓盤按鈕,如果按下就關(guān)閉射線檢測
        if (teleportAction.GetStateDown(hand.handType))
        {
            tempLineActive = active;
            SetActive(false);
        }
        else if (teleportAction.GetStateUp(hand.handType))
        {
            if (tempLineActive) SetActive(true);
        }

        //按下菜單鍵,呼出射線
        if (menuAction.GetStateDown(hand.handType))
        {
            SetActive(!active);
        }

        if (!active) return;//未開啟射線檢測

        pointStartPos = hand.transform.position;
        lineDirection = hand.transform.forward;
        Ray ray = new Ray(pointStartPos, lineDirection);
        if (Physics.Raycast(ray, out RaycastHit hit, rayLength, layerMask))
        {
            if (hit.transform.TryGetComponent(out IEventHandle_VR uiTriggerSystem))
            {
                pointEndPos = hit.point;
                lineRealLength = hit.distance;

                onTrigger(uiTriggerSystem);

                //Debug.DrawLine(pointStartPos, lineDirection * rayLength, Color.green);
            }
            else
            {
                onTrigger(null);

                pointEndPos = pointStartPos + (lineDirection * 10000.0f - pointStartPos).normalized * rayLength;
                lineRealLength = rayLength;
            }
        }
        else
        {
            onTrigger(null);

            //pointEndPos = lineDirection * rayLength * 1000.0f;//有較大的誤差,還不知道怎么解決,希望大佬看到可以留言解決,暫時用下面的方法。
            pointEndPos = pointStartPos + (lineDirection * 10000.0f - pointStartPos).normalized * rayLength;
            lineRealLength = rayLength;

            //Debug.DrawLine(pointStartPos, lineDirection * rayLength, Color.magenta);
        }


        if (hand.grabPinchAction.GetStateDown(hand.handType))
        {
            if (currentObj == null) return;
            pressObj = currentObj;
            onClick(pressObj);
            pressObj.OnHandDown(hand);
        }
        if (hand.grabPinchAction.GetStateUp(hand.handType))
        {
            if (pressObj == null) return;
            pressObj.OnHandUp(hand);
            pressObj = null;
        }
        if (hand.grabPinchAction.GetState(hand.handType))
        {
            currentObj?.OnHandStay(hand);
        }
    }

    private void onTrigger(IEventHandle_VR target)
    {
        currentObj = target;
        if (target == null)//離開
        {
            if (currentTarget != null)
            {
                currentTarget.OnHandExit(hand);
                onExit(currentTarget);
                //Debug.Log($"離開{currentTarget}");
            }
            currentTarget = null;
        }
        else
        {
            //第一次
            if (currentTarget == null)
            {
                target.OnHandEnter(hand);
                onEnter(target);
                //Debug.Log($"進入{target}");
                currentTarget = target;
            }
            else if (currentTarget != target)//第n次
            {
                currentTarget.OnHandExit(hand);
                target.OnHandEnter(hand);

                onExit(currentTarget);
                onEnter(target);
                //Debug.Log($"進入{target},離開{currentTarget}");
                currentTarget = target;
            }
        }
    }
    /// <summary>
    /// 射線進入
    /// </summary>
    private void onEnter(IEventHandle_VR target)
    {
        //Debug.Log("進入");
        OnEnterEvent?.Invoke();
    }
    /// <summary>
    /// 射線進入
    /// </summary>
    private void onExit(IEventHandle_VR target)
    {
        //Debug.Log("離開");
        OnExitEvent?.Invoke();
    }
    /// <summary>
    /// 手柄扣動扳機
    /// </summary>
    private void onClick(IEventHandle_VR target)
    {
        //Debug.Log("手柄點擊");
        OnClickEvent?.Invoke();
    }
    /// <summary>
    /// 激活或者關(guān)閉射線檢測
    /// </summary>
    public void SetActive(bool _active)
    {
        OnActiveEvent?.Invoke(_active);
        active = _active;

        if (!_active) onTrigger(null);//當手柄關(guān)閉射線檢測
    }
}

繪制射線

public class LineRenderer : MonoBehaviour
{
    private LineController lineController;
    public LineRenderer line;
    [SerializeField] GameObject targetPoint;
    void Start()
    {
        lineController = GetComponent<LineController>();

        createLine();
        createTargetPoint();

        lineController.OnEnterEvent += onEnter;
        lineController.OnExitEvent += onExit;
        lineController.OnActiveEvent += onActive;
    }

    // Update is called once per frame
    void Update()
    {
        line.SetPosition(0, lineController.pointStartPos);
        line.SetPosition(1, lineController.pointEndPos);

        targetPoint.SetActive(lineController.hasTarget);
        if (lineController.hasTarget)
        {
            targetPoint.transform.position = lineController.pointEndPos;
        }
    }
    void createLine()
    {
        line = Instantiate(line);
        line.useWorldSpace = true;
        line.startWidth = 0.0035f;
        line.endWidth = 0.0035f;
    }
    void createTargetPoint()
    {
        targetPoint = Instantiate(targetPoint);
    }
    private void onEnter()
    {
        line.material.SetFloat("_CenterIntensity", 10.0f);
    }
    private void onExit()
    {
        line.materials[0].SetFloat("_CenterIntensity", 2.0f);
    }
    private void onActive(bool active)
    {
        line.enabled = active;
    }
}

觸發(fā)UI控件的各種狀態(tài),在手柄射線觸發(fā)的時候調(diào)用

public class UIInputModule_VR : SingletonMono<UIInputModule_VR>
{
    private EventSystem eventSystem;
    private PointerEventData eventData;

    private GameObject currentObj;
    public HandTriggerType handTriggerType;
    void Start()
    {
        eventSystem = GetComponent<EventSystem>();
        eventData = new PointerEventData(eventSystem);
    }
    public void MouseEnter(GameObject obj)
    {
        currentObj = obj;
        eventData.pointerEnter = obj;
        ExecuteEvents.Execute(obj, eventData, ExecuteEvents.pointerEnterHandler);
    }
    public void MouseExit(GameObject obj)
    {
        currentObj = null;
        ExecuteEvents.Execute(eventData.pointerEnter, eventData, ExecuteEvents.pointerExitHandler);
    }
    public void MouseDown(GameObject obj)
    {
        eventData.pointerPress = obj;
        ExecuteEvents.Execute(obj, eventData, ExecuteEvents.pointerDownHandler);

        if(handTriggerType == HandTriggerType.Down)
        {
            ExecuteEvents.Execute(obj, eventData, ExecuteEvents.pointerClickHandler);
        }
    }
    public void MouseUp(GameObject obj)
    {
        ExecuteEvents.Execute(eventData.pointerPress, eventData, ExecuteEvents.pointerUpHandler);
        ExecuteEvents.Execute(eventData.pointerPress, eventData, ExecuteEvents.deselectHandler);

        if (currentObj == eventData.pointerPress && handTriggerType == HandTriggerType.Up)
        {
            ExecuteEvents.Execute(obj, eventData, ExecuteEvents.pointerClickHandler);
        }
    }

    public enum HandTriggerType
    {
        Up, Down
    }
}

public static class UIInputModuleExtension
{
    public static void MouseEnter(this GameObject obj)
    {
        UIInputModule_VR.Instance.MouseEnter(obj);
    }
    public static void MouseExit(this GameObject obj)
    {
        UIInputModule_VR.Instance.MouseExit(obj);
    }
    public static void MouseDown(this GameObject obj)
    {
        UIInputModule_VR.Instance.MouseDown(obj);
    }
    public static void MouseUp(this GameObject obj)
    {
        UIInputModule_VR.Instance.MouseUp(obj);
    }
}

其他一些按鈕相關(guān)的代碼

public class UIComponent_VR : MonoBehaviour, IEventHandle_VR
{
    private CanvasRenderer canvasRenderer;
    private RectTransform rectTransform;
    private BoxCollider boxCollider;
    public bool triggerSizeEveryFrame = false;

    public Action OnHandEnterEvent;
    public Action OnHandExitEvent;

    public Action OnHandDownEvent;
    public Action OnHandStayEvent;
    public Action OnHandUpEvent;
    protected virtual void Start()
    {
        boxCollider = GetComponent<BoxCollider>();
        rectTransform = GetComponent<RectTransform>();
        canvasRenderer = GetComponent<CanvasRenderer>();

        boxCollider.isTrigger = true;
        boxCollider.size = new Vector3(rectTransform.rect.width, rectTransform.rect.height);
    }

    protected virtual void Update()
    {
        if (triggerSizeEveryFrame)
        {
            boxCollider.size = new Vector3(rectTransform.rect.width, rectTransform.rect.height);
        }
    }

    protected virtual void LateUpdate()
    {
        transform.localPosition = new Vector3(transform.localPosition.x, transform.localPosition.y, -canvasRenderer.absoluteDepth);
    }

    public virtual void OnHandEnter(Hand hand)
    {
        OnHandEnterEvent?.Invoke();
    }

    public virtual void OnHandExit(Hand hand)
    {
        OnHandExitEvent?.Invoke();
    }

    public virtual void OnHandDown(Hand hand)
    {
        OnHandDownEvent?.Invoke();
    }

    public virtual void OnHandStay(Hand hand)
    {
        OnHandStayEvent?.Invoke();
    }

    public virtual void OnHandUp(Hand hand)
    {
        OnHandUpEvent?.Invoke();
    }
}

public interface IEventHandle_VR
{
    /// <summary>
    /// 手柄進入觸發(fā)
    /// </summary>
    public void OnHandEnter(Hand hand);
    /// <summary>
    /// 手柄離開觸發(fā)
    /// </summary>
    public void OnHandExit(Hand hand);
    /// <summary>
    /// 手柄按下觸發(fā)
    /// </summary>
    public void OnHandDown(Hand hand);
    /// <summary>
    /// 手柄停留觸發(fā)
    /// </summary>
    public void OnHandStay(Hand hand);
    /// <summary>
    /// 手柄抬起觸發(fā)
    /// </summary>
    public void OnHandUp(Hand hand);
}

Button代碼

public class Button_VR : UIComponent_VR
{

    public override void OnHandEnter(Hand hand)
    {
        base.OnHandEnter(hand);

        hand.TriggerHapticPulse(1000);

        gameObject.MouseEnter();
    }
    public override void OnHandExit(Hand hand)
    {
        base.OnHandExit(hand);

        gameObject.MouseExit();
    }

    public override void OnHandDown(Hand hand)
    {
        base.OnHandDown(hand);

        gameObject.MouseDown();
    }

    public override void OnHandUp(Hand hand)
    {
        base.OnHandUp(hand);

        gameObject.MouseUp();
    }
}

文章來源地址http://www.zghlxwxcb.cn/news/detail-514868.html

到了這里,關(guān)于Unity中使用VR手柄射線觸發(fā)UI事件的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關(guān)文章

  • 【vr】【unity】白馬VR課堂系列-VR開發(fā)核心基礎05-主體設置-手柄對象的引入和設置

    【vr】【unity】白馬VR課堂系列-VR開發(fā)核心基礎05-主體設置-手柄對象的引入和設置

    【白馬VR課堂系列-VR開發(fā)核心基礎05-主體設置-手柄對象的引入和設置】 https://www.bilibili.com/video/BV19D4y1N73i/?share_source=copy_webvd_source=7f5c96f5a58b7542fc6b467a9824b04e 上一節(jié)引入了XR Origin并進行了初步設置,運行測試時VR場景中的玩家視野已經(jīng)可以跟隨頭盔了。 這一節(jié)來了解如何將手柄

    2024年02月05日
    瀏覽(25)
  • 【unity】Pico VR 開發(fā)筆記(基礎篇)包括射線

    【unity】Pico VR 開發(fā)筆記(基礎篇)包括射線

    XR Interaction Tooikit 版本 2.3.2 一、環(huán)境搭建 其實官方文檔已經(jīng)寫的很詳細了,這里只是不廢話快速搭建,另外有一項官方說明有誤的,補充說明一下,在開發(fā)工具部分說明 插件安裝——安裝pico的sdk和XR Interaction Tooikit 環(huán)境配置——在場景里添加頭顯和手柄,并進行配置和項目

    2024年02月04日
    瀏覽(34)
  • Unity之OpenXR+XR Interaction Toolkit實現(xiàn) 監(jiān)聽VR手柄按鍵

    Unity之OpenXR+XR Interaction Toolkit實現(xiàn) 監(jiān)聽VR手柄按鍵

    當我們接入XR Interaction Toolkit之后,我們可以很方便的做不同VR設備的適配,這在很大程度上提升了我們的開發(fā)效率,我們除了通過射線和物體交互之外,偶爾我們也會希望監(jiān)聽手柄上的部分按鍵的點擊事件,今天我們就來實現(xiàn)如何監(jiān)聽VR手柄的按鈕事件。 我們需要準備好Uni

    2024年02月05日
    瀏覽(90)
  • Unity+Pico 響應射線事件

    1、添加組件 為了讓場景內(nèi)的物體能夠響應射線的操作,需要在該物體上添加“XR Simple Interactable”組件,并對射線的交互事件編寫腳本看,最常用的是“Hover”和“Select”事件。 2、編寫腳本 在編寫腳本時,需要引入UnityEngine.XR.Interaction.Toolkit命名空間,另外,從步驟1中的截圖

    2024年02月12日
    瀏覽(89)
  • Unity使用SteamVR2.0實現(xiàn)基本功能(瞬移,抓取物品,射線點擊,UI交互等)

    Unity使用SteamVR2.0實現(xiàn)基本功能(瞬移,抓取物品,射線點擊,UI交互等)

    ?把SteamVR的Player預制件拖到一個空場景,刪掉場景內(nèi)原本的相機 新建一個Plane,當做地板 找到SteamVR的人物瞬移控制器 ?Teleporting ,把它拖到場景里 ?我們需要在可以移動的區(qū)域,也就是碰撞器上,掛 TeleportArea 腳本 這個腳本會自動修改你的材質(zhì)球 locked 該區(qū)域是否可以移動 markerAc

    2024年02月02日
    瀏覽(26)
  • Unity VR開發(fā)教程 OpenXR+XR Interaction Toolkit(七)射線抓取

    Unity VR開發(fā)教程 OpenXR+XR Interaction Toolkit(七)射線抓取

    此教程相關(guān)的詳細教案,文檔,思維導圖和工程文件會放入 Spatial XR 社區(qū) 。這是一個高質(zhì)量知識星球 XR 社區(qū),博主目前在內(nèi)擔任 XR 開發(fā)的講師。此外,該社區(qū)提供教程答疑、及時交流、進階教程、外包、行業(yè)動態(tài)等服務。 社區(qū)鏈接: Spatial XR 高級社區(qū)(知識星球) Spatial

    2023年04月08日
    瀏覽(27)
  • Unity VR 開發(fā)教程 OpenXR+XR Interaction Toolkit(七)射線抓取

    Unity VR 開發(fā)教程 OpenXR+XR Interaction Toolkit(七)射線抓取

    此教程相關(guān)的詳細教案,文檔,思維導圖和工程文件會放入 Spatial XR 社區(qū) 。這是一個高質(zhì)量知識星球 XR 社區(qū),博主目前在內(nèi)擔任 XR 開發(fā)的講師。此外,該社區(qū)提供教程答疑、及時交流、進階教程、外包、行業(yè)動態(tài)等服務。 社區(qū)鏈接: Spatial XR 高級社區(qū)(知識星球) Spatial

    2024年02月13日
    瀏覽(27)
  • Unity UG算法能力可視化UI的PhysicsRaycaster (物理射線檢測)組件的介紹及使用

    PhysicsRaycaster是Unity UGUI中的一個組件,用于在UI元素上進行物理射線檢測。它可以檢測鼠標或觸摸事件是否發(fā)生在UI元素上,并將事件傳遞給相應的UI元素。 PhysicsRaycaster通過發(fā)射一條射線來檢測UI元素。當射線與UI元素相交時,PhysicsRaycaster會將事件傳遞給相應的UI元素。 Event

    2024年01月20日
    瀏覽(50)
  • Unity VR:XR Interaction Toolkit 輸入系統(tǒng)(Input System):獲取手柄的輸入

    Unity VR:XR Interaction Toolkit 輸入系統(tǒng)(Input System):獲取手柄的輸入

    輸入系統(tǒng)是 VR 應用中非常重要的一部分。我們通常需要獲取 VR 手柄上某個按鍵的輸入,然后將其作用到應用中,比如按下手柄的 Grip 鍵進行抓取。在我的其他 Unity XR Interaction Toolkit 的開發(fā)教程里,已經(jīng)有介紹如何去獲取手柄的輸入。那么這篇教程我將做一個總結(jié),將相關(guān)的

    2024年02月12日
    瀏覽(23)
  • Unity射線穿透UI解決

    Unity射線穿透UI解決

    unity場景中,射線是可以穿透UI的。我用過很多版本,都有這個問題。 比如我現(xiàn)在用2020版本的unity做了個范例: 我在場景中新建了一個cube名叫:我秦始皇打錢。 點擊這個物體就會出現(xiàn)log顯示這個物體的名字,代碼在下面。 運行之后確實會彈出這個log,這沒有什么問題。如下

    2024年02月15日
    瀏覽(11)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包