using System.Net; using UnityEngine; using System; using Wave.Native; using Wave.Essence; using System.Runtime.InteropServices; using System.Collections; using UnityEngine.XR; using Valheim; public class VIVECamera : MonoBehaviour { public GameObject marker; [NonSerialized] public InputDevice leftHandDevice; [NonSerialized] public InputDevice rightHandDevice; private bool is_start = false; private bool _clickA = false; private bool _clickB = false; private bool _clickX = false; private bool _clickY = false; void Start() { #if !UNITY_EDITOR && UNITY_ANDROID && VIVE string polling_value; string key = "PLAYER00InitMA"; key += "{\"marker1\":{\"id\":0,\"behavior\":3,\"size\":0.21,\"pose\":[0,0,0,1,0,0.7,0]}}"; uint RETURN_SIZE = 256; IntPtr value = Marshal.AllocHGlobal(new IntPtr(RETURN_SIZE)); Interop.WVR_GetParameters(WVR_DeviceType.WVR_DeviceType_HMD, Marshal.StringToHGlobalAnsi(key), value, RETURN_SIZE); polling_value = Marshal.PtrToStringAnsi(value); Marshal.FreeCoTaskMem(value); Debug.Log("初始化marker"); if (string.Compare(polling_value, "InitErr") == 0) // initialization failed, should check config string { Debug.Log("初始化marker失败"); } leftHandDevice = InputDevices.GetDeviceAtXRNode(XRNode.LeftHand); rightHandDevice = InputDevices.GetDeviceAtXRNode(XRNode.RightHand); #endif } void Update() { #if !UNITY_EDITOR && UNITY_ANDROID && VIVE // X键 bool triggerX = false; bool pressedOnceX = false; if (leftHandDevice != null && leftHandDevice.TryGetFeatureValue(CommonUsages.primaryButton, out triggerX) && triggerX) { if (!_clickX) { _clickX = true; pressedOnceX = true; Debug.Log("按下X键"); } } else { _clickX = false; } // Y键 bool triggerY = false; bool pressedOnceY = false; if (leftHandDevice != null && leftHandDevice.TryGetFeatureValue(CommonUsages.secondaryButton, out triggerY) && triggerY) { if (!_clickY) { _clickY = true; pressedOnceY = true; Debug.Log("按下Y键"); } } else { _clickY = false; } // A键 bool triggerA = false; bool pressedOnceA = false; if (rightHandDevice != null && rightHandDevice.TryGetFeatureValue(CommonUsages.primaryButton, out triggerA) && triggerA) { if (!_clickA) { _clickA = true; pressedOnceA = true; Debug.Log("按下A键"); } } else { _clickA = false; } // B键 bool triggerB = false; bool pressedOnceB = false; if (rightHandDevice != null && rightHandDevice.TryGetFeatureValue(CommonUsages.secondaryButton, out triggerB) && triggerB) { if (!_clickB) { _clickB = true; pressedOnceB = true; Debug.Log("按下B键"); } } else { _clickB = false; } // A+X扫描 if (pressedOnceA && pressedOnceX) { Debug.Log("按下A+X键"); if (is_start == false) { string key = "ClearRecenterXform"; Interop.WVR_SetParameters(WVR_DeviceType.WVR_DeviceType_HMD, Marshal.StringToHGlobalAnsi(key)); Interop.WVR_SetParameters(WVR_DeviceType.WVR_DeviceType_Controller_Right, Marshal.StringToHGlobalAnsi(key)); Interop.WVR_SetParameters(WVR_DeviceType.WVR_DeviceType_Controller_Left, Marshal.StringToHGlobalAnsi(key)); key = "PLAYER00StartScan"; uint RETURN_SIZE = 256; IntPtr value = Marshal.AllocHGlobal(new IntPtr(RETURN_SIZE)); Interop.WVR_GetParameters(WVR_DeviceType.WVR_DeviceType_HMD, Marshal.StringToHGlobalAnsi(key), value, RETURN_SIZE); Marshal.FreeCoTaskMem(value); is_start = true; StartCoroutine("Polling"); } else { string key = "PLAYER00StopScan"; uint RETURN_SIZE = 256; IntPtr value = Marshal.AllocHGlobal(new IntPtr(RETURN_SIZE)); Interop.WVR_GetParameters(WVR_DeviceType.WVR_DeviceType_HMD, Marshal.StringToHGlobalAnsi(key), value, RETURN_SIZE); Marshal.FreeCoTaskMem(value); StopCoroutine("Polling"); is_start = false; Debug.Log("手动停止扫描marker"); } } // B+Y退出游戏 if (pressedOnceB && pressedOnceY) { Debug.Log("按下B+Y键"); ExitPanel.Show(); } #endif } IEnumerator Polling() { string key = "PLAYER00CheckMA"; string key2 = "PLAYER00GetArucoPoseByID=0"; string key3 = "PLAYER00StopScan"; uint RETURN_SIZE = 2048 * 128; IntPtr value = Marshal.AllocHGlobal(new IntPtr(RETURN_SIZE)); string polling_value; bool need_do_check = true; bool need_do_MA = true, need_do_IMU = true; while (need_do_check) { Debug.Log("开始check"); Interop.WVR_GetParameters(WVR_DeviceType.WVR_DeviceType_HMD, Marshal.StringToHGlobalAnsi(key), value, RETURN_SIZE); polling_value = Marshal.PtrToStringAnsi(value); Debug.Log("polling_value: " + polling_value); if (string.Compare(polling_value, "CTdone") == 0) Debug.Log("第一个marker已对齐, 请扫描下一个marker"); if (string.Compare(polling_value, "CTdone") == 0) { Debug.Log("地图已对齐,停止扫描"); need_do_MA = false; } Interop.WVR_GetParameters(WVR_DeviceType.WVR_DeviceType_HMD, Marshal.StringToHGlobalAnsi(key2), value, RETURN_SIZE); polling_value = Marshal.PtrToStringAnsi(value); if (string.Compare(polling_value, "f") != 0) { char[] separator = { ',' }; string[] sArray = polling_value.Split(separator); if (sArray.Length == 8 && float.TryParse(sArray[1], out float x) && float.TryParse(sArray[2], out float y) && float.TryParse(sArray[3], out float z)) { if (marker != null) { marker.transform.position = new Vector3(x, y, z); } Debug.Log("marker已放置新位置"); need_do_IMU = false; } } need_do_check = need_do_MA || need_do_IMU; yield return new WaitForSeconds(1.0f); } Interop.WVR_GetParameters(WVR_DeviceType.WVR_DeviceType_HMD, Marshal.StringToHGlobalAnsi(key3), value, RETURN_SIZE); Marshal.FreeCoTaskMem(value); is_start = false; } }