Last active
April 10, 2022 08:49
-
-
Save JCxYIS/02877f8e3904695c51cd076f631efe9c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// by JCxYIS | |
/// 20220406 | |
using UnityEngine; | |
/// <summary> | |
/// 繼承此介面以監聽物件點擊事件 | |
/// </summary> | |
public interface IClickable | |
{ | |
void OnClick(); | |
} | |
/// <summary> | |
/// 繼承此介面以監聽物件拖移事件 | |
/// </summary> | |
public interface IDragable | |
{ | |
void OnDrag(); | |
} | |
/// <summary> | |
/// 繼承此介面以管理控制器 Hover 事件 | |
/// </summary> | |
public interface ITriggerManager | |
{ | |
/// <summary> | |
/// Hover Enter | |
/// </summary> | |
void OnTriggerEnter(Collider other); | |
/// <summary> | |
/// Hover Exit | |
/// </summary> | |
void OnTriggerExit(Collider other); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// by JCxYIS / Modded from Pico VR demo script | |
/// 20220410 | |
using UnityEngine; | |
using System.Collections; | |
using System.Collections.Generic; | |
using Pvr_UnitySDKAPI; | |
using UnityEngine.SceneManagement; | |
/// <summary> | |
/// Pico 控制器與他的好朋友們 | |
/// </summary> | |
[RequireComponent(typeof(Pvr_Controller))] | |
public class PicoVRcontroller : MonoBehaviour | |
{ | |
public static PicoVRcontroller Instance; | |
/// <summary> | |
/// 要看指到啥東西就把這個設 true | |
/// </summary> | |
public const bool PRINT_DEBUG = false; | |
private GameObject controller0; | |
private GameObject controller1; | |
private Ray ray; | |
public Ray Ray => ray; | |
private GameObject currentController; | |
private Transform lastHit; | |
[SerializeField] private Transform currentHit; | |
GameObject referenceObj; | |
private bool isHasController = false; | |
private RaycastHit hit; | |
private GameObject rayLine; | |
private GameObject dot; | |
private Transform dragObj; | |
private List<ITriggerManager> _triggerManagers = new List<ITriggerManager>(); | |
void Awake() | |
{ | |
Instance = this; | |
} | |
void Start() | |
{ | |
ray = new Ray(); | |
hit = new RaycastHit(); | |
Pvr_Controller pvr_Controller = GetComponent<Pvr_Controller>(); | |
controller0 = pvr_Controller.controller0; | |
controller1 = pvr_Controller.controller1; | |
if (Pvr_UnitySDKManager.SDK.isHasController) | |
{ | |
Pvr_ControllerManager.PvrServiceStartSuccessEvent += ServiceStartSuccess; | |
Pvr_ControllerManager.SetControllerStateChangedEvent += ControllerStateListener; | |
isHasController = true; | |
#if UNITY_EDITOR | |
currentController = controller1; | |
dot = controller1.transform.Find("dot").gameObject; | |
dot.SetActive(true); | |
rayLine = controller1.transform.Find("ray_LengthAdaptive").gameObject; | |
rayLine.SetActive(true); | |
#endif | |
} | |
referenceObj = new GameObject("ReferenceObj"); | |
_triggerManagers = FindObjectsOfInterfaces<ITriggerManager>(); | |
} | |
void OnDestroy() | |
{ | |
if (isHasController) | |
{ | |
Pvr_ControllerManager.PvrServiceStartSuccessEvent -= ServiceStartSuccess; | |
Pvr_ControllerManager.SetControllerStateChangedEvent -= ControllerStateListener; | |
} | |
} | |
void Update() | |
{ | |
if (currentController == null) | |
{ | |
Debug.LogWarning("No controller."); | |
return; | |
} | |
ray.direction = currentController.transform.forward - currentController.transform.up * 0.25f; | |
ray.origin = currentController.transform.Find("start").position; | |
if (Physics.Raycast(ray, out hit)) | |
{ | |
currentHit = hit.transform; | |
if (currentHit != null && lastHit != null && currentHit != lastHit) | |
{ | |
if (lastHit.GetComponent<Pvr_UIGraphicRaycaster>() && lastHit.transform.gameObject.activeInHierarchy && lastHit.GetComponent<Pvr_UIGraphicRaycaster>().enabled) | |
{ | |
lastHit.GetComponent<Pvr_UIGraphicRaycaster>().enabled = false; | |
} | |
} | |
if (currentHit != null && lastHit != null && currentHit == lastHit) | |
{ | |
if (currentHit.GetComponent<Pvr_UIGraphicRaycaster>() && !currentHit.GetComponent<Pvr_UIGraphicRaycaster>().enabled) | |
{ | |
currentHit.GetComponent<Pvr_UIGraphicRaycaster>().enabled = true; | |
} | |
} | |
if (currentHit != null) | |
{ | |
// Hover | |
print("[PicoVRcontroller] Hover: "+currentHit.gameObject); | |
_triggerManagers.ForEach(i => i.OnTriggerEnter(hit.collider)); | |
// Click | |
if (Controller.UPvr_GetKeyDown(0, Pvr_KeyCode.Any) || | |
Controller.UPvr_GetKeyDown(1, Pvr_KeyCode.Any) || Input.GetMouseButtonDown(0)) | |
{ | |
print("[PicoVRcontroller] Click: "+currentHit.gameObject); | |
currentHit.GetComponent<IClickable>()?.OnClick(); | |
} | |
// Drag | |
if (Controller.UPvr_GetKeyDown(0, Pvr_KeyCode.TOUCHPAD) || Controller.UPvr_GetKeyDown(1, Pvr_KeyCode.TOUCHPAD) || Input.GetMouseButtonDown(0)) | |
{ | |
referenceObj.transform.position = hit.point; | |
dragObj = currentHit; | |
print("[PicoVRcontroller] DragStart: "+currentHit.gameObject); | |
} | |
if (Controller.UPvr_GetKey(0, Pvr_KeyCode.TOUCHPAD) || Controller.UPvr_GetKey(1, Pvr_KeyCode.TOUCHPAD) || Input.GetMouseButton(0)) | |
{ | |
if (currentHit == dragObj.transform) | |
{ | |
print("[PicoVRcontroller] Drag: "+currentHit.gameObject); | |
currentHit.GetComponent<IDragable>()?.OnDrag(); | |
} | |
} | |
} | |
// Exit from last stuff (if hit changes) | |
if (lastHit != null && lastHit != currentHit) | |
{ | |
print("[PicoVRcontroller] Exit: "+lastHit.transform.gameObject); | |
_triggerManagers.ForEach(i => i.OnTriggerExit(lastHit.GetComponent<Collider>())); | |
} | |
lastHit = currentHit; | |
#if UNITY_EDITOR | |
Debug.DrawLine(ray.origin, hit.point, Color.red); | |
#endif | |
currentController.transform.Find("dot").position = hit.point; | |
if (Pvr_ControllerManager.Instance.LengthAdaptiveRay) | |
{ | |
float scale = 0.178f * currentController.transform.Find("dot").localPosition.z / 3.3f; | |
Mathf.Clamp(scale, 0.05f, 0.178f); | |
currentController.transform.Find("dot").localScale = new Vector3(scale, scale, 1); | |
} | |
} | |
else // hit nothing | |
{ | |
if (lastHit != null) | |
{ | |
print("[PicoVRcontroller] Exit: "+lastHit.transform.gameObject); | |
_triggerManagers.ForEach(i => i.OnTriggerExit(lastHit.GetComponent<Collider>())); | |
} | |
lastHit = null; | |
currentHit = null; | |
if(Pvr_ControllerManager.Instance.LengthAdaptiveRay) | |
{ | |
currentController.transform.Find("dot").localScale = new Vector3(0.178f, 0.178f, 1); | |
} | |
} | |
#if UNITY_EDITOR | |
rayLine.GetComponent<LineRenderer>().SetPosition(0,currentController.transform.TransformPoint(0, 0, 0.072f)); | |
rayLine.GetComponent<LineRenderer>().SetPosition(1, dot.transform.position); | |
#endif | |
} | |
private void ServiceStartSuccess() | |
{ | |
if (Controller.UPvr_GetMainHandNess() == 0) | |
{ | |
currentController = controller0; | |
} | |
if (Controller.UPvr_GetMainHandNess() == 1) | |
{ | |
currentController = controller1; | |
} | |
} | |
private void ControllerStateListener(string data) | |
{ | |
if (Controller.UPvr_GetMainHandNess() == 0) | |
{ | |
currentController = controller0; | |
} | |
if (Controller.UPvr_GetMainHandNess() == 1) | |
{ | |
currentController = controller1; | |
} | |
} | |
/// <summary> | |
/// https://answers.unity.com/questions/863509/how-can-i-find-all-objects-that-have-a-script-that.html | |
/// </summary> | |
/// <typeparam name="T"></typeparam> | |
/// <returns></returns> | |
public static List<T> FindObjectsOfInterfaces<T>( ) | |
{ | |
List<T> interfaces = new List<T>(); | |
GameObject[] rootGameObjects = SceneManager.GetActiveScene().GetRootGameObjects(); | |
foreach( var rootGameObject in rootGameObjects ) | |
{ | |
T[] childrenInterfaces = rootGameObject.GetComponentsInChildren<T>(); | |
foreach( var childInterface in childrenInterfaces ) | |
{ | |
interfaces.Add(childInterface); | |
} | |
} | |
return interfaces; | |
} | |
new void print(object obj) | |
{ | |
if(PRINT_DEBUG) | |
Debug.Log(obj); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment