阅读量:4
刚开始先查看了其他道友的方案:1.Unity使用SteamVR2.0实现基本功能(瞬移,抓取物品,射线点击,UI交互等)_贪小心的博客-CSDN博客_unity steam vr
2.【Steam VR 2.0】5.射线操作UGUI-射线点击物体_恩博同学的博客-CSDN博客_htc steamvr 射线点击ui
嗯。。。试着尝试了一下,不是很好用,于是乎记得以前用过得的方法(别人做的,我只是使用者),剔除出来,整理一下。
一 UGUI射线点击:
使用插件:CurvedUI(CurvedUI+DOTween+Shaders+Sprites-其它文档类资源-CSDN文库),SteamVR Plugin(商店免费)
场景使用SteamVR 的Interactions_Example场景测试的
1.将CurvedUI 下的CurvedUILaserPointer预制体 放置 SteamVR的 Player 下。
其他设置
二 物品射线点击:
继承重写类:CurvedUILaserBeam
using UnityEngine; using System.Collections; using UnityEngine.EventSystems; using UnityEngine.UI; using System; using Valve.VR; using Valve.VR.Extras; using UnityEngine.Events; namespace CurvedUI { /// <summary> /// This class contains code that controls the visuals (only!) of the laser pointer. /// </summary> public class CurvedUILaserBeam : MonoBehaviour { public SteamVR_Action_Boolean interactWithModel = SteamVR_Input.GetBooleanAction("GrabPinch"); bool isActive = false; public event PointerEventHandler PointerClickModel; Transform previousContact = null; public virtual void OnPointerClickModel(PointerEventArgs e) { if (PointerClickModel != null) PointerClickModel(this, e); } GameObject itemObject = null; bool bo = false; #pragma warning disable 0649 [SerializeField] Transform LaserBeamTransform; [SerializeField] Transform LaserBeamDot; [SerializeField] bool hideWhenNotAimingAtCanvas = false; #pragma warning restore 0649 protected void Update() { //get direction of the controller Ray myRay = new Ray(this.transform.position, this.transform.forward); //make laser beam hit stuff it points at. if (LaserBeamTransform && LaserBeamDot) { float length = 10000; RaycastHit hit; if (Physics.Raycast(myRay, out hit, length, CurvedUIInputModule.Instance.RaycastLayerMask)) { length = Vector3.Distance(hit.point, this.transform.position); CurvedUISettings cuiSettings = hit.collider.GetComponentInParent<CurvedUISettings>(); if (cuiSettings != null)//UI 界面 { // Debug.Log("是 UI 界面"); //find if there are any canvas objects we're pointing at. we only want transforms with graphics to block the pointer. (that are drawn by canvas => depth not -1) int selectablesUnderPointer = cuiSettings.GetObjectsUnderPointer().FindAll(x => x != null && x.GetComponent<Graphic>() != null && x.GetComponent<Graphic>().depth != -1).Count; length = selectablesUnderPointer == 0 ? 10000 : Vector3.Distance(hit.point, this.transform.position); } else{ length = 0; } } else if (Physics.Raycast(myRay, out hit, length, LayerMask.GetMask("Obj"))) { //物品的 Layer 设置 Obj ,挂载组件:BoxCollider,FT_InteractableRay length = Vector3.Distance(hit.point, this.transform.position); FT_InteractableRay FT_InteractableRay = hit.collider.GetComponentInParent<FT_InteractableRay>(); BoxCollider boxCollider = hit.collider.GetComponentInParent<BoxCollider>(); if (boxCollider != null&& FT_InteractableRay != null) { length = 1000; length = Vector3.Distance(hit.point, this.transform.position); itemObject = hit.collider.gameObject; if (!bo) { bo = true; itemObject.GetComponent<FT_InteractableRay>().RayEnter(); } if (CurvedUIInputModule.Instance.SteamVRClickAction.GetStateDown(Valve.VR.SteamVR_Input_Sources.RightHand)) { //点击 itemObject.GetComponent<FT_InteractableRay>().RayClick(); } else if (CurvedUIInputModule.Instance.SteamVRClickAction.GetStateDown(Valve.VR.SteamVR_Input_Sources.LeftHand)) { //点击 itemObject.GetComponent<FT_InteractableRay>().RayClick(); } } } else { bo = false; itemObject?.GetComponent<FT_InteractableRay>().RayExit(); itemObject = null; length = 0; } //set the leangth of the beam LaserBeamTransform.localScale = LaserBeamTransform.localScale.ModifyZ(length); 射线长度为零的时候隐藏射线 //if (Math.Abs(length) < 0.0001f && LaserBeamTransform.gameObject.activeSelf) // LaserBeamTransform.gameObject.SetActive(false); //else if (Math.Abs(length) >= 0.0001f && !LaserBeamTransform.gameObject.activeSelf) // LaserBeamTransform.gameObject.SetActive(true); } } } }
2.挂载物品上代码
using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; public class FT_InteractableRay : MonoBehaviour { public bool isActive = true; public UnityEvent OnRayEnter; public UnityEvent OnRayExit; public UnityEvent OnRayClick; public virtual void RayEnter() { OnRayEnter?.Invoke(); // this.GetComponent<HighlightEffect>().highlighted = false; Debug.Log("射线进入:" + name); } public virtual void RayExit() { OnRayExit?.Invoke(); Debug.Log("射线离开:" + name); } public virtual void RayClick() { OnRayClick?.Invoke(); Debug.Log("射线点击:" + name); } }
3.逻辑测试 代码
using HighlightPlus; using System.Collections; using System.Collections.Generic; using UnityEngine; public class TestTest : MonoBehaviour { // Start is called before the first frame update void Start() { this.gameObject.GetComponent<FT_InteractableRay>().OnRayEnter.AddListener(() => { this.gameObject.GetComponent<HighlightEffect>().highlighted = true; }); this.gameObject.GetComponent<FT_InteractableRay>().OnRayExit.AddListener(() => { this.gameObject.GetComponent<HighlightEffect>().highlighted = false; }); this.gameObject.GetComponent<FT_InteractableRay>().OnRayClick.AddListener(() => { }); } // Update is called once per frame void Update() { } }
完事!!!!!!!!!!!
后面 慢慢完善一下。
以上 方案我以弃用,不是不好用,而是 很多功能需要自己 集成。恰好找到了一个别人集成好的方案。
:Unity VR Interaction Framework+VIVE Cosmos(完美组合)_野区捕龙为宠的博客-CSDN博客