using System;
using System.Collections;
using System.Collections.Generic;
using EZXR.Glass.Core;
using EZXR.Glass.Inputs;
using UnityEngine;
namespace EZXR.Glass.Inputs
{
public enum HandleKeyEvent
{
Idle, //默认状态
Down, //按下(仅单帧有效)
Up, //弹起(仅单帧有效)
///
/// (feat)等同于长按
/// Down之后每帧有效
///
PrePressed, //介于按下和长按之间状态
Pressing //长按(每帧有效)
}
[ScriptExecutionOrder(-49)]
public class HandleControllerManager : MonoBehaviour
{
#region singleton
private static HandleControllerManager instance;
public static HandleControllerManager Instance
{
get
{
return instance;
}
}
#endregion
///
/// 记录了左手柄的所有信息
///
public static ControllerInfo leftHand;
///
/// 记录了右手柄的所有信息
///
public static ControllerInfo rightHand;
// 手柄模型
public Transform leftController;
public Transform rightController;
private List> bindingActions = new List>();
private List> connectedActions = new List>();
private List> powerChangedActions = new List>();
private List> holdChangedActions = new List>();
private List> silenceChangedActions = new List>();
private List> buttonChangedActions = new List>();
private List> trackingChangedActions = new List>();
///
/// 由外部逻辑控制手的射线的方向
///
///
///
///
public delegate bool Delegate_SetRayDataByExternal(ControllerInfo controllerInfo, ref Vector3 value);
public static Delegate_SetRayDataByExternal SetRayDirByExternal;
public static Delegate_SetRayDataByExternal SetRayStartPointByExternal;
private void Awake()
{
instance = this;
leftHand = leftController.GetComponent();
rightHand = rightController.GetComponent();
}
private void Start()
{
HandleControllerSession.Instance.InitRegistration(OnBindingEventCallback, OnConnectEventCallback,
OnButtonEventCallback, OnAxis2DEventCallback,
OnHoldEventCallback, OnSilenceEventCallback,
OnTrackingStateChangedCallback);
if (leftHand != null)
{
// 初始化手柄的生命状态
leftHand.Init(HandType.Left);
}
if (rightHand != null)
{
// 初始化手柄的生命状态
rightHand.Init(HandType.Right);
}
StartCoroutine(WaitForTimeout());
}
private void Update()
{
//if (Input.GetKeyDown(KeyCode.Q))
// Debug.Log($"HandleControllerManager, rightHand binding = {rightController != null && rightHand.Exist}, controllerPose: ({HandleControllerSession.controllerPose_right.position.x}, {HandleControllerSession.controllerPose_right.position.y}, {HandleControllerSession.controllerPose_right.position.z})");
if (leftHand.Exist || rightHand.Exist)
HandleControllerSession.Instance.UpdateHandlePose();
if (leftController != null && leftHand.Exist)
leftController.SetLocalPositionAndRotation(HandleControllerSession.controllerPose_left.position, HandleControllerSession.controllerPose_left.rotation);
if (rightController != null && rightHand.Exist)
rightController.SetLocalPositionAndRotation(HandleControllerSession.controllerPose_right.position, HandleControllerSession.controllerPose_right.rotation);
}
///
/// 初始化注册,监听手柄生命状态
///
/// 绑定状态改变的回调事件
/// 连接状态改变的回调事件
/// 电量改变的回调事件
public void InitRegistration(Action bindingEventCallback, Action connectedEventCallback, Action powerChangedCallback)
{
InitRegistration(bindingEventCallback, connectedEventCallback, powerChangedCallback, null, null, null);
}
///
/// 初始化注册,监听手柄生命状态
///
/// 绑定状态改变的回调事件
/// 连接状态改变的回调事件
/// 电量改变的回调事件
/// 跟踪状态改变的回调事件(3/6dof)
public void InitRegistration(Action bindingEventCallback, Action connectedEventCallback, Action powerChangedCallback, Action trackingStateChangedCallback)
{
InitRegistration(bindingEventCallback, connectedEventCallback, powerChangedCallback, null, null, null);
trackingChangedActions.Add(trackingStateChangedCallback);
}
///
/// 初始化注册,监听手柄生命状态
///
/// 绑定状态改变的回调事件
/// 连接状态改变的回调事件
/// 电量改变的回调事件
/// 按键状态改变的回调
/// 握持状态改变的回调
/// 静置状态改变的回调
public void InitRegistration(Action bindingEventCallback,
Action connectedEventCallback,
Action powerChangedCallback,
Action buttonChangedCallback,
Action holdChangedCallback,
Action silenceChangedCallback)
{
bindingActions.Add(bindingEventCallback);
connectedActions.Add(connectedEventCallback);
powerChangedActions.Add(powerChangedCallback);
silenceChangedActions.Add(silenceChangedCallback);
holdChangedActions.Add(holdChangedCallback);
buttonChangedActions.Add(buttonChangedCallback);
}
///
/// 进行手柄配对
///
public bool BindHandle(HandType handType)
{
return HandleControllerSession.Instance.BindHandle((int)handType);
}
///
/// 取消手柄配对
///
public bool UnbindHandle(HandType handType)
{
return HandleControllerSession.Instance.UnbindHandle((int)handType);
}
///
/// 手柄震动,震动等级 1-8,震动时长 0-65535 ms
///
public bool VibrateHandle(HandType handType, int level, int time)
{
return HandleControllerSession.Instance.VibrateHandle((int)handType, level, time);
}
///
/// 获取手柄绑定状态
///
///
///
public bool GetBindState(HandType handType)
{
return HandleControllerSession.Instance.GetBindState(handType);
}
///
/// 获取手柄连接状态
///
public bool GetConnectState(HandType handType)
{
return HandleControllerSession.Instance.GetConnectState((int)handType);
}
///
/// 获取手柄电量
///
public float GetPowerStats(HandType handType)
{
return HandleControllerSession.Instance.GetPowerStats((int)handType);
}
///
/// 手柄按键是否按下
///
public bool GetButtonDown(HandType handType, HandleKeyCode keyCode)
{
if (handType == HandType.Left)
return leftHand.GetButtonDown(keyCode);
else
return rightHand.GetButtonDown(keyCode);
}
///
/// 手柄按键是否弹起
///
public bool GetButtonUp(HandType handType, HandleKeyCode keyCode)
{
if (handType == HandType.Left)
return leftHand.GetButtonUp(keyCode);
else
return rightHand.GetButtonUp(keyCode);
}
///
/// 手柄按键是否长按
///
public bool GetButton(HandType handType, HandleKeyCode keyCode)
{
if (handType == HandType.Left)
return leftHand.GetButton(keyCode);
else
return rightHand.GetButton(keyCode);
}
///
/// 获取手柄摇杆坐标
///
/// 左手柄or右手柄
/// 坐标范围[-1,-1]到[1,1],复位为[0,0]
public Vector2 GetAxis2D(HandType handType)
{
if (handType == HandType.Left)
return leftHand.GetAxis2D();
else
return rightHand.GetAxis2D();
}
// 控制器统一管理时,激活手柄功能
public void SetActive(bool value)
{
//var controller = handType == HandType.Left ? leftController : rightController;
//controller.GetComponent().enabled = true;
//for (int i = 0; i < controller.childCount; i++)
//{
// controller.GetChild(i).gameObject.SetActive(true);
//}
gameObject.SetActive(value);
if (value)
{
//(handType == HandType.Left ? leftController : rightController).gameObject.SetActive(false);
//StartCoroutine(SetActive_WaitForSeconds(handType, value));
//var handInfo = handType == HandType.Left ? leftHand : rightHand;
//StartCoroutine(handInfo.CheckStatus());
StartCoroutine(leftHand.CheckStatus());
StartCoroutine(rightHand.CheckStatus());
}
}
private IEnumerator SetActive_WaitForSeconds(HandType handType, bool value)
{
yield return new WaitForSeconds(1);
(handType == HandType.Left ? leftController : rightController).gameObject.SetActive(value);
}
private void OnBindingEventCallback(HandType handType, bool status)
{
if (handType == HandType.Left)
{
leftHand.UpdateBindingState(status, _status =>
{
bindingActions.ForEach(action => { if (action != null) action(HandType.Left, _status); });
});
}
else
{
rightHand.UpdateBindingState(status, _status =>
{
bindingActions.ForEach(action => { if (action != null) action(HandType.Right, _status); });
});
}
}
private void OnConnectEventCallback(HandType handType, bool connected)
{
if (handType == HandType.Left)
{
leftHand.UpdateConnectedState(connected, _connected =>
{
connectedActions.ForEach(action => { if (action != null) action(HandType.Left, _connected); });
});
}
else
{
rightHand.UpdateConnectedState(connected, _connected =>
{
connectedActions.ForEach(action => { if (action != null) action(HandType.Right, _connected); });
});
}
}
private void OnPowerStatsChangedCallback(HandType handType, float power)
{
if (handType == HandType.Left)
{
leftHand.UpdatePowerStats(power, _power =>
{
powerChangedActions.ForEach(action => { if (action != null) action(HandType.Left, _power); });
});
}
else
{
rightHand.UpdatePowerStats(power, _power =>
{
powerChangedActions.ForEach(action => { if (action != null) action(HandType.Right, _power); });
});
}
}
private void OnButtonEventCallback(HandType handType, HandleKeyCode keycode, bool pressed)
{
if (handType == HandType.Left)
{
leftHand.UpdateButtonState(keycode, pressed);
buttonChangedActions.ForEach(action => { if (action != null) action(HandType.Left, pressed); });
}
else
{
rightHand.UpdateButtonState(keycode, pressed);
buttonChangedActions.ForEach(action => { if (action != null) action(HandType.Right, pressed); });
}
}
private void OnAxis2DEventCallback(HandType handType, Vector2 coord)
{
if (handType == HandType.Left)
leftHand.UpdateAxis2D(coord);
else
rightHand.UpdateAxis2D(coord);
}
private void OnHoldEventCallback(HandType handType, HandleKeyCode keycode, bool isHeld)
{
if (handType == HandType.Left)
{
leftHand.UpdateHoldState(isHeld, _isHeld =>
{
holdChangedActions.ForEach(action => { if (action != null) action(HandType.Left, _isHeld); });
});
}
else
{
rightHand.UpdateHoldState(isHeld, _isHeld =>
{
holdChangedActions.ForEach(action => { if (action != null) action(HandType.Right, _isHeld); });
});
}
}
private void OnSilenceEventCallback(HandType handType, bool silent)
{
if (handType == HandType.Left)
{
leftHand.UpdateSilenceState(silent, _silent =>
{
silenceChangedActions.ForEach(action => { if (action != null) action(HandType.Left, _silent); });
});
}
else
{
rightHand.UpdateSilenceState(silent, _silent =>
{
silenceChangedActions.ForEach(action => { if (action != null) action(HandType.Right, _silent); });
});
}
}
private void OnTrackingStateChangedCallback(HandType handType, int state) //state 0: 6dof,1: 3dof
{
if (handType == HandType.Left)
{
trackingChangedActions.ForEach(action => { if (action != null) action(HandType.Left, state); });
}
else
{
trackingChangedActions.ForEach(action => { if (action != null) action(HandType.Right, state); });
}
}
///
/// 定时刷新手柄电量
///
///
private IEnumerator WaitForTimeout()
{
yield return new WaitForSeconds(3);
if (leftHand.Exist) OnPowerStatsChangedCallback(HandType.Left, GetPowerStats(HandType.Left));
if (rightHand.Exist) OnPowerStatsChangedCallback(HandType.Right, GetPowerStats(HandType.Right));
while (true)
{
yield return new WaitForSeconds(300);
if (leftHand.Exist) OnPowerStatsChangedCallback(HandType.Left, GetPowerStats(HandType.Left));
if (rightHand.Exist) OnPowerStatsChangedCallback(HandType.Right, GetPowerStats(HandType.Right));
}
}
}
}