123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504 |
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using EZXR.Glass.Core;
- using EZXR.Glass.Inputs;
- using EZXR.Glass.SixDof;
- using UnityEngine;
- namespace EZXR.Glass.Inputs
- {
- [ScriptExecutionOrder(-48)]
- public class ControllerInfo : InputInfoBase
- {
- public Transform handleOrigin;
- public Transform tipPoint;
- /// <summary>
- /// 手柄当前是否已配对
- /// </summary>
- protected bool isBinding = false;
- public bool IsBinding
- {
- get
- {
- return isBinding;
- }
- }
- /// <summary>
- /// 手柄当前是否已连接
- /// </summary>
- protected bool isConnected = false;
- public bool IsConnected
- {
- get
- {
- return isConnected;
- }
- }
- /// <summary>
- /// 手柄当前电量
- /// </summary>
- protected float powerStats = 0.0f;
- public float PowerStats
- {
- get
- {
- return powerStats;
- }
- }
- /// <summary>
- /// 手柄当前是否被握持
- /// </summary>
- protected bool isHeld;
- public bool IsHeld
- {
- get
- {
- return isHeld;
- }
- }
- /// <summary>
- /// 手柄当前是否被静置
- /// </summary>
- protected bool isSilent;
- public bool IsSilent
- {
- get
- {
- return isSilent;
- }
- }
- protected Vector2 axis2DCoord;
- /// <summary>
- /// 监听手柄的生命状态改变(立即发生)
- /// </summary>
- private bool bindingChanged = false;
- private bool connectedChanged = false;
- private bool powerChanged = false;
- private bool holdChanged = false;
- private bool silenceChanged = false;
- /// <summary>
- /// 监听到生命状态改变的回调(在Update中发生)
- /// 可能立即发生也可能滞后一帧
- /// </summary>
- private Action<bool> bindingAction;
- private Action<bool> connectedAction;
- private Action<float> powerChangedAction;
- private Action<bool> holdChangedAction;
- private Action<bool> silenceChangedAction;
- /// 保存按键状态(在Update中发生,可能立即发生也可能滞后一帧)
- private Dictionary<HandleKeyCode, HandleKeyEvent> buttonState;
- /// 监听按键状态的改变(立即发生)
- private Dictionary<HandleKeyCode, bool> buttonStateChanged;
- //private Dictionary<HandleKeyCode, float> buttonDownTimeSpan;
- private bool isPaused = false;
- /// <summary>
- /// 当前眼镜视野中是否存在这个手
- /// </summary>
- public override bool Exist
- {
- get
- {
- if (Application.isEditor)
- {
- return true;
- }
- return isConnected;
- }
- }
- /// <summary>
- /// 手掌正在朝向头部
- /// </summary>
- /// <param name="angle"></param>
- /// <returns></returns>
- public override bool isPalmFacingHead(float angle = 90) { return false; }
- #region 手交互能力开关
- /// <summary>
- /// 设置或获得当前手的显示状态(仅仅影响显示,并不影响交互)
- /// </summary>
- private bool visibility = true;
- public override bool Visibility
- {
- get
- {
- /*if (handType == HandType.Left) return false;
- else */return visibility;
- }
- set
- {
- // 判断是否开发者自定义了手柄模型
- //if (handType == HandType.Right)
- {
- var dummy = handType == HandType.Left ? "LeftDummy" : "RightDummy";
- // 若在handleOrigin下添加自定义的手柄模型,则隐藏默认手柄
- var hasAlter = handleOrigin.GetComponentsInChildren<Renderer>().Length > 0;
- if (!hasAlter) transform.Find(dummy).gameObject.SetActive(value);
- else handleOrigin.gameObject.SetActive(value);
- visibility = value;
- }
- }
- }
- /// <summary>
- /// 设置或获得远距离射线交互状态
- /// </summary>
- public override bool RaycastInteraction
- {
- get
- {
- return GetComponent<InputRaycast>().enabled;
- }
- set
- {
- GetComponent<InputRaycast>().enabled = value;
- }
- }
- /// <summary>
- /// 设置或获得近距离交互状态
- /// </summary>
- public override bool TouchInteraction
- {
- get
- {
- return false;
- }
- set
- {
- }
- }
- /// <summary>
- /// 设置或获得手部的物理碰撞交互状态
- /// </summary>
- public override bool PhysicsInteraction
- {
- get
- {
- return false;
- }
- set
- {
- }
- }
- #endregion
- protected override void Awake()
- {
- base.Awake();
- buttonState = new Dictionary<HandleKeyCode, HandleKeyEvent>();
- //buttonDownTimeSpan = new Dictionary<HandleKeyCode, float>();
- buttonStateChanged = new Dictionary<HandleKeyCode, bool>();
- }
- protected override void Update()
- {
- base.Update();
- UpdateStatus();
- if (handleOrigin != null)
- {
- //射线方向
- if (!(HandleControllerManager.SetRayDirByExternal != null && HandleControllerManager.SetRayDirByExternal(this, ref rayDirection)))
- {
- rayDirection = handleOrigin.forward;
- }
- //射线起点
- if (!(HandleControllerManager.SetRayStartPointByExternal != null && HandleControllerManager.SetRayStartPointByExternal(this, ref rayPoint_Start)))
- {
- rayPoint_Start = handleOrigin.position + rayDirection * rayStartDistance;
- }
- }
- }
- private void OnApplicationPause(bool pause)
- {
- //Debug.Log($"HandleControllerInfo, OnApplicationPause: pause = {pause} handType = {this.handType} isBinding = {isBinding}, isConnected = {isConnected}, powerStats = {powerStats} ({Time.frameCount})");
- if (!pause)
- {
- isBinding = HandleControllerManager.Instance.GetBindState(handType);
- isConnected = HandleControllerManager.Instance.GetConnectState(handType);
- powerStats = HandleControllerManager.Instance.GetPowerStats(handType);
- Debug.Log($"HandleControllerInfo, OnApplicationPause: pause = {pause} handType = {this.handType} isBinding = {isBinding}, isConnected = {isConnected}, powerStats = {powerStats}");
- }
- isPaused = pause;
- //UpdatePinching();
- buttonState.Clear(); buttonStateChanged.Clear();
- startPinch = false; endPinch = false; isPinching = false;
- }
- private void OnEnable()
- {
- //Debug.Log($"HandleControllerInfo, OnEnable: handType = {this.handType} isBinding = {isBinding}, isConnected = {isConnected}, powerStats = {powerStats} ({Time.frameCount})");
- isBinding = HandleControllerManager.Instance.GetBindState(handType);
- isConnected = HandleControllerManager.Instance.GetConnectState(handType);
- powerStats = HandleControllerManager.Instance.GetPowerStats(handType);
- Debug.Log($"HandleControllerInfo, OnEnable: handType = {this.handType} isBinding = {isBinding}, isConnected = {isConnected}, powerStats = {powerStats}");
- //UpdatePinching();
- buttonState.Clear(); buttonStateChanged.Clear();
- startPinch = false; endPinch = false; isPinching = false;
- }
- private void OnDisable()
- {
- //UpdatePinching();
- buttonState.Clear(); buttonStateChanged.Clear();
- startPinch = false; endPinch = false; isPinching = false;
- Debug.Log($"HandleControllerInfo, OnDisable: handType = {this.handType} isBinding = {isBinding}, isConnected = {isConnected}, powerStats = {powerStats} ({Time.frameCount})");
- }
- public override void Init(HandType handType)
- {
- base.Init(handType);
- //if (handType == HandType.Right)
- {
- // 若在handleOrigin下添加自定义的手柄模型,则隐藏默认手柄
- var hasAlter = handleOrigin.GetComponentsInChildren<Renderer>().Length > 0;
- // fix: 控制器切换时不能任意设置手柄显示
- if (hasAlter) transform.Find(handType == HandType.Left ? "LeftDummy" : "RightDummy").gameObject.SetActive(!hasAlter);
- }
- isBinding = HandleControllerManager.Instance.GetBindState(handType);
- isConnected = HandleControllerManager.Instance.GetConnectState(handType);
- powerStats = HandleControllerManager.Instance.GetPowerStats(handType);
- Debug.Log($"HandleControllerInfo, Init: handType = {this.handType} isBinding = {isBinding}, isConnected = {isConnected}, powerStats = {powerStats}");
- StartCoroutine(CheckStatus());
- }
- public void UpdateBindingState(bool status, Action<bool> callback)
- {
- if (isBinding == status) return;
- isBinding = status;
- bindingChanged = true;
- bindingAction = callback;
- Debug.Log($"HandleControllerInfo, UpdateBinding: handType = {this.handType} isBinding = {status}");
- if (isPaused || !gameObject.activeInHierarchy) UpdateStatus();
- }
- public void UpdateConnectedState(bool connected, Action<bool> callback)
- {
- if (isConnected == connected) return;
- isConnected = connected;
- connectedChanged = true;
- connectedAction = callback;
- Debug.Log($"HandleControllerInfo, UpdateConnectedState: handType = {this.handType} isConnected = {connected}");
- if (!connected) { buttonState.Clear(); buttonStateChanged.Clear(); }
- if (!connected) { startPinch = false; endPinch = false; isPinching = false; }
- if (isPaused || !gameObject.activeInHierarchy) UpdateStatus();
- }
- public void UpdatePowerStats(float power, Action<float> callback)
- {
- Debug.Log($"HandleControllerInfo, UpdatePowerStats: handType = {this.handType} power = {power}");
- if (powerStats == power) return;
- powerStats = power;
- powerChanged = true;
- powerChangedAction = callback;
- if (isPaused || !gameObject.activeInHierarchy) UpdateStatus();
- }
- public void UpdateButtonState(HandleKeyCode keyCode, bool pressed)
- {
- if (isPaused || !gameObject.activeInHierarchy) return;
- //Debug.Log($"HandleControllerInfo, {handType} {keyCode} StateChanged to {(pressed ? "pressed" : "released")} ({Time.frameCount})");
- if (!buttonState.ContainsKey(keyCode))
- {
- buttonState[keyCode] = pressed ? HandleKeyEvent.Idle : HandleKeyEvent.Pressing;
- buttonStateChanged[keyCode] = true;
- }
- else if ((pressed && buttonState[keyCode] == HandleKeyEvent.Idle) || (!pressed && buttonState[keyCode] == HandleKeyEvent.Pressing))
- {
- buttonStateChanged[keyCode] = true;
- }
- }
- public void UpdateAxis2D(Vector2 coord)
- {
- if (isPaused || !gameObject.activeInHierarchy) return;
- axis2DCoord = coord;
- }
- public void UpdateHoldState(bool isHeld, Action<bool> callback)
- {
- if (this.isHeld == isHeld) return;
- this.isHeld = isHeld;
- holdChanged = true;
- holdChangedAction = callback;
- //Debug.Log($"HandleControllerInfo, UpdateHoldState: handType = {this.handType} isHeld = {isHeld} ({Time.frameCount})");
- if (isPaused || !gameObject.activeInHierarchy) UpdateStatus();
- }
- public void UpdateSilenceState(bool isSilent, Action<bool> callback)
- {
- if (this.isSilent == isSilent) return;
- this.isSilent = isSilent;
- silenceChanged = true;
- silenceChangedAction = callback;
- //Debug.Log($"HandleControllerInfo, UpdateSilenceState: handType = {this.handType} isSilent = {isSilent} ({Time.frameCount})");
- if (isPaused || !gameObject.activeInHierarchy) UpdateStatus();
- }
- public bool GetButtonDown(HandleKeyCode keyCode)
- {
- if (!isPaused && isConnected && buttonState.ContainsKey(keyCode))
- return buttonState[keyCode] == HandleKeyEvent.Down;
- return false;
- }
- public bool GetButtonUp(HandleKeyCode keyCode)
- {
- if (!isPaused && isConnected && buttonState.ContainsKey(keyCode))
- return buttonState[keyCode] == HandleKeyEvent.Up;
- return false;
- }
- public bool GetButton(HandleKeyCode keyCode)
- {
- if (!isPaused && isConnected && buttonState.ContainsKey(keyCode))
- return buttonState[keyCode] == HandleKeyEvent.Pressing;
- return false;
- }
- public Vector2 GetAxis2D()
- {
- return axis2DCoord;
- }
- protected override void UpdatePinching()
- {
- var keys = new List<HandleKeyCode>(buttonStateChanged.Keys);
- for (int j = 0; j < keys.Count; ++j)
- {
- var keyCode = keys[j];
- if (!buttonStateChanged[keyCode]) continue;
- if (buttonState[keyCode] == HandleKeyEvent.Idle)
- {
- buttonState[keyCode] = HandleKeyEvent.Down;
- //Debug.Log($"HandleControllerInfo, {handType} {keyCode} change to Down from Idle ({Time.frameCount})");
- //按下扳机键触发开始捏合动作
- if (keyCode == HandleKeyCode.Trigger) startPinch = true;
- }
- else if (buttonState[keyCode] == HandleKeyEvent.Pressing)
- {
- buttonState[keyCode] = HandleKeyEvent.Up;
- //Debug.Log($"HandleControllerInfo, {handType} {keyCode} change to Up from Pressing ({Time.frameCount})");
- //松开扳机键触发结束捏合动作
- if (keyCode == HandleKeyCode.Trigger) endPinch = true;
- }
- //buttonStateChanged.Remove(keyCode);
- }
- keys = new List<HandleKeyCode>(buttonState.Keys);
- for (int i = 0; i < keys.Count; ++i)
- {
- var keyCode = keys[i];
- if (buttonStateChanged.ContainsKey(keyCode))
- {
- buttonStateChanged.Remove(keyCode);
- continue;
- }
- if (buttonState[keyCode] == HandleKeyEvent.Down)
- {
- buttonState[keyCode] = HandleKeyEvent.Pressing;
- //Debug.Log($"HandleControllerInfo, {handType} {keyCode} change to Pressing from Down ({Time.frameCount})");
- // startPinch结束,触发持续捏合
- if (keyCode == HandleKeyCode.Trigger) { startPinch = false; isPinching = true; }
- }
- else if (buttonState[keyCode] == HandleKeyEvent.Up)
- {
- buttonState[keyCode] = HandleKeyEvent.Idle;
- //Debug.Log($"HandleControllerInfo, {handType} {keyCode} change to Idle from Up ({Time.frameCount})");
- // endPinch结束,触发结束捏合
- if (keyCode == HandleKeyCode.Trigger) { endPinch = false; isPinching = false; }
- }
- }
- }
- private void UpdateStatus()
- {
- if (bindingChanged)
- {
- if (bindingAction != null) bindingAction(isBinding);
- bindingChanged = false;
- }
- if (connectedChanged)
- {
- if (connectedAction != null) connectedAction(isConnected);
- connectedChanged = false;
- Visibility = isConnected;
- RaycastInteraction = isConnected;
- TouchInteraction = isConnected;
- PhysicsInteraction = isConnected;
- }
- if (powerChanged)
- {
- if (powerChangedAction != null) powerChangedAction(powerStats);
- powerChanged = false;
- }
- if (holdChanged)
- {
- if (holdChangedAction != null) holdChangedAction(isHeld);
- holdChanged = false;
- }
- if (silenceChanged)
- {
- if (silenceChangedAction != null) silenceChangedAction(isSilent);
- silenceChanged = false;
- }
- }
- // for fix
- public IEnumerator CheckStatus()
- {
- yield return new WaitUntil(() => SessionManager.Instance != null && SessionManager.Instance.IsInited);
- isBinding = HandleControllerManager.Instance.GetBindState(handType);
- isConnected = HandleControllerManager.Instance.GetConnectState(handType);
- powerStats = HandleControllerManager.Instance.GetPowerStats(handType);
- Debug.Log($"HandleControllerInfo, Check: handType = {this.handType} isBinding = {isBinding}, isConnected = {isConnected}, powerStats = {powerStats} ({Time.frameCount})");
- Visibility = isConnected;
- RaycastInteraction = isConnected;
- TouchInteraction = isConnected;
- PhysicsInteraction = isConnected;
- }
- }
- }
|