using DG.Tweening; using System; using System.Collections.Generic; using UnityEngine; namespace UDE_HAND_INTERACTION { public class VRControllerSample : MonoBehaviour { public BleManager bleManager; private string LeftHand; private string RightHand; private Transform RealCamera; public GameObject TeleportTarget; private GameObject TempTarget = null; private List Line = new(); private LineRenderer TeleportRender; public Material[] TeleportMats; private float vertexDelta = 0.08f; private Vector3 velocity; private Vector3 PreviousPosition = Vector3.zero; private bool TeleportPermisssion = false; private float rateY; private float rateX; [HideInInspector] public float[] Move = new float[2]; private float ForwardMove; private float SideMove; public Vector3 MotionDir; private float InteractInterval = 0f; public GameObject ExtraSettingPanel; public FingerPressController ExitBtn; private void Start() { RealCamera = transform.GetChild(0).GetChild(0); PreviousPosition = transform.localPosition; TeleportRender = GetComponentsInChildren()[0]; ExitBtn.OnSelect.AddListener(() => { Application.Quit(); }); } void Update() { Vector3 _Forward = transform.GetChild(0).GetChild(0).forward; Vector3 Forward = new(_Forward.x, 0, _Forward.z); Vector3 _Right = transform.GetChild(0).GetChild(0).right; Vector3 Right = new(_Right.x, 0, _Right.z); LeftHand = bleManager.LeftDeviceName; RightHand = bleManager.RightDeviceName; #if UNITY_EDITOR ForwardMove = 0f; if (Input.GetKey(KeyCode.W)) { ForwardMove = 1f; } if (Input.GetKey(KeyCode.S)) { ForwardMove = -1f; } SideMove = 0; if (Input.GetKey(KeyCode.A)) { SideMove = -1f; } if (Input.GetKey(KeyCode.D)) { SideMove = 1f; } transform.localPosition += (ForwardMove * Forward + SideMove * Right) * 0.03f; MotionDir = new Vector3(SideMove, 0, ForwardMove); float Angle = Vector3.Angle(new Vector3(0,0,1), Forward); MotionDir = Quaternion.AngleAxis(Angle, transform.up) * MotionDir; if (Input.GetKeyDown(KeyCode.Q)) { if (TempTarget == null) { TempTarget = Instantiate(TeleportTarget, GetComponentsInChildren()[1].GetControlledHand(true)); InteractInterval = 1; } } if (TempTarget != null) { RefreshTeleport(); } if (Input.GetKeyDown(KeyCode.E)) { Vector3 PosOffset = new(transform.position.x - RealCamera.position.x, 0, transform.position.z - RealCamera.position.z); PreviousPosition = transform.position; transform.root.position = TempTarget.transform.position + PosOffset - new Vector3(0, 0.2f, 0); ResetTeleport(); InteractInterval = 1f; } #endif if (!bleManager.handDrivers[0].UsingAndroidService) { if (string.IsNullOrEmpty(LeftHand) || string.IsNullOrEmpty(RightHand) || !bleManager.FinJoyCalibration) return; } var inputL = BleManager._SDK.UDE_GetInputDeviceData(LeftHand); var inputR = BleManager._SDK.UDE_GetInputDeviceData(RightHand); if (bleManager.handDrivers[0].UsingAndroidService) { inputL = bleManager.handDrivers[0].inputData; inputR = bleManager.handDrivers[1].inputData; } float joy_x = inputL.joyX; float joy_x2 = inputR.joyX; float joy_y = inputL.joyY; float joy_y2 = inputR.joyY; rateX += 0.04f * (float)Math.Round(joy_x2, 2); rateY += 0.04f * (float)Math.Round(joy_y2, 2); Move[0] = 0.02f * (float)Math.Round(joy_x, 2); Move[1] = 0.02f * (float)Math.Round(joy_y, 2); if (rateX < -1) rateX = -1; else if (rateX > 1) rateX = 1; if (rateY < 0) rateY = 0; else if (rateY > 2) rateY = 2; if (InteractInterval <= 0) //移动 { transform.localPosition += Right * Move[0] + Forward * Move[1]; } if (inputR.aButton && InteractInterval <= 0) //传送复位 { transform.localPosition = PreviousPosition; InteractInterval = 0.5f; } if (inputR.joyButton && InteractInterval <= 0) //传送启动 { TeleportPermisssion = !TeleportPermisssion; InteractInterval = 0.5f; } if ((joy_y2 > 0.3f) && TeleportPermisssion && InteractInterval <= 0) //传送 { if (TempTarget == null) { TempTarget = Instantiate(TeleportTarget, GetComponentsInChildren()[1].GetControlledHand(true)); InteractInterval = 1; } } if (TempTarget != null) { RefreshTeleport(); } if (joy_y2 == 0 && TempTarget != null && InteractInterval <= 0) { Vector3 PosOffset = new(transform.position.x - RealCamera.position.x, 0, transform.position.z - RealCamera.position.z); PreviousPosition = transform.position; transform.root.position = TempTarget.transform.position + PosOffset - new Vector3(0, 0.2f, 0); ResetTeleport(); InteractInterval = 1f; } if (inputL.bButton && InteractInterval <= 0) //设置面板 { if (ExtraSettingPanel.transform.localScale.x == 1) { ExtraSettingPanel.transform.DOScale(Vector3.zero, 0.3f).OnComplete(ActiveExtraSetting); } else { ExtraSettingPanel.SetActive(true); ExtraSettingPanel.transform.DOScale(Vector3.one, 0.3f); } InteractInterval = 0.5f; } if (InteractInterval > 0) InteractInterval -= Time.deltaTime; } void RefreshTeleport() { Line.Clear(); TeleportRender.enabled = true; var RealRightHandTrack = TempTarget.transform.parent; velocity = RealRightHandTrack.forward * 2f; Vector3 pos = RealRightHandTrack.position; for (int i = 0; i < 100; ++i) { Vector3 newPos = pos + velocity * vertexDelta + 0.5f * Physics.gravity * vertexDelta * vertexDelta; velocity += Physics.gravity * vertexDelta * vertexDelta; Line.Add(newPos); pos = newPos; if (velocity.y < 0 && pos.y <= 0.2f) { break; } } TeleportRender.positionCount = Line.Count; TeleportRender.SetPositions(Line.ToArray()); Quaternion Rot = Quaternion.Euler(0, RealCamera.eulerAngles.y, 0); TempTarget.transform.SetPositionAndRotation(Line[^1], Rot); } void ResetTeleport() { DestroyImmediate(TempTarget); TeleportRender.enabled = false; } private void ActiveExtraSetting() { ExtraSettingPanel.SetActive(false); } } }