AimHandler.cs 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797
  1. using DragonBones;
  2. using SmartBowSDK;
  3. using System;
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. using UnityEngine;
  7. using UnityEngine.SceneManagement;
  8. using UnityEngine.UI;
  9. using SdkAimDeviceInfo = SmartBowSDK.AimDeviceInfo;
  10. namespace AppUI.Bluetooth
  11. {
  12. /// <summary>
  13. /// AppUI 瞄准处理器:设备信息本地维护,九轴/校准走 SmartBowSDK(Axis9Handler_SDK)。
  14. /// </summary>
  15. public class AimHandler : MonoBehaviour
  16. {
  17. CameraToLook m_controlObj => CameraToLook.ins;
  18. #region 设备信息(MAC 走 SDK AimDeviceInfo;型号走 PlayerDeviceTypeStore)
  19. public const string SdkUserTags = "smartbow";
  20. /// <summary>当前 SideSlip / 连接上下文使用的玩家槽位(0=1P,1=2P)。</summary>
  21. int deviceSelectIndex;
  22. /// <summary>与 SDK 同步的当前槽位档案(只读用途请用 <see cref="GetAimDeviceInfo"/>)。</summary>
  23. public SdkAimDeviceInfo aimDeviceInfo;
  24. int _tempDeviceType = -1;
  25. public Action aimDeviceInfoChangeEvent;
  26. public static int GetSdkDeviceId(BluetoothPlayer player) =>
  27. player == BluetoothPlayer.SECOND_PLAYER ? 2 : 1;
  28. public static int GetSdkDeviceId(int playerIndex) =>
  29. playerIndex == (int)BluetoothPlayer.SECOND_PLAYER ? 2 : 1;
  30. static string SdkPrefsKey(int sdkDeviceId) => "aim-device-info-" + SdkUserTags + sdkDeviceId;
  31. SmartBowHelper GetHelperForPlayer(BluetoothPlayer player)
  32. {
  33. if (Ble == null) return null;
  34. return player == BluetoothPlayer.SECOND_PLAYER
  35. ? Ble.getSmartBowHelper2P()
  36. : Ble.getSmartBowHelper1P();
  37. }
  38. SdkAimDeviceInfo LoadSdkDeviceInfoFromPrefs(int sdkDeviceId)
  39. {
  40. string json = PlayerPrefs.GetString(SdkPrefsKey(sdkDeviceId), "");
  41. if (string.IsNullOrEmpty(json))
  42. return null;
  43. return JsonUtility.FromJson<SdkAimDeviceInfo>(json);
  44. }
  45. void SaveSdkDeviceInfo(SdkAimDeviceInfo info, int sdkDeviceId)
  46. {
  47. if (info == null) return;
  48. PlayerPrefs.SetString(SdkPrefsKey(sdkDeviceId), JsonUtility.ToJson(info));
  49. }
  50. public void onClearAimDeviceInfosNew()
  51. {
  52. GetHelperForPlayer(BluetoothPlayer.FIRST_PLAYER)?.ClearDeviceInfo(SdkUserTags, 1);
  53. GetHelperForPlayer(BluetoothPlayer.SECOND_PLAYER)?.ClearDeviceInfo(SdkUserTags, 2);
  54. PlayerPrefs.DeleteKey(SdkPrefsKey(1));
  55. PlayerPrefs.DeleteKey(SdkPrefsKey(2));
  56. PlayerDeviceTypeStore.ClearAll();
  57. aimDeviceInfo = null;
  58. aimDeviceInfoChangeEvent?.Invoke();
  59. }
  60. public void onClear2PAimDeviceInfosNew()
  61. {
  62. GetHelperForPlayer(BluetoothPlayer.SECOND_PLAYER)?.ClearDeviceInfo(SdkUserTags, 2);
  63. PlayerPrefs.DeleteKey(SdkPrefsKey(2));
  64. PlayerDeviceTypeStore.ClearPlayer(BluetoothPlayer.SECOND_PLAYER);
  65. aimDeviceInfoChangeEvent?.Invoke();
  66. }
  67. public void OnGetAimDeviceInfos()
  68. {
  69. if (deviceSelectIndex >= 0)
  70. aimDeviceInfo = GetAimDeviceInfo((BluetoothPlayer)deviceSelectIndex);
  71. aimDeviceInfoChangeEvent?.Invoke();
  72. }
  73. public void OnSaveAimDeviceInfos()
  74. {
  75. if (aimDeviceInfo != null)
  76. SaveSdkDeviceInfo(aimDeviceInfo, aimDeviceInfo.id);
  77. aimDeviceInfoChangeEvent?.Invoke();
  78. }
  79. public void onCreateTempAimDeviceInfo()
  80. {
  81. _tempDeviceType = -1;
  82. Debug.Log("onCreateTempAimDeviceInfo deviceSelectIndex:" + deviceSelectIndex);
  83. }
  84. public int GetTempDeviceType() => _tempDeviceType;
  85. public void onCreateAimDeviceInfoById()
  86. {
  87. BluetoothPlayer player = (BluetoothPlayer)deviceSelectIndex;
  88. int sdkDeviceId = GetSdkDeviceId(player);
  89. aimDeviceInfo = GetAimDeviceInfo(player);
  90. if (aimDeviceInfo == null)
  91. {
  92. aimDeviceInfo = new SdkAimDeviceInfo(sdkDeviceId);
  93. SaveSdkDeviceInfo(aimDeviceInfo, sdkDeviceId);
  94. }
  95. aimDeviceInfoChangeEvent?.Invoke();
  96. }
  97. public void SetAimDeviceSelectIndex(int selectIndex)
  98. {
  99. if (selectIndex < 0)
  100. {
  101. Debug.LogWarning("selectIndex不能小于0:" + selectIndex);
  102. return;
  103. }
  104. deviceSelectIndex = selectIndex;
  105. }
  106. public void SetTempAimDeviceType(AimDeviceType _aimDeviceType) => _tempDeviceType = (int)_aimDeviceType;
  107. public void SetAimDeviceType(AimDeviceType _aimDeviceType) => SetAimDeviceType((int)_aimDeviceType);
  108. public void SetAimDeviceType(int _aimDeviceType)
  109. {
  110. BluetoothPlayer player = (BluetoothPlayer)deviceSelectIndex;
  111. PlayerDeviceTypeStore.SetType(player, _aimDeviceType);
  112. aimDeviceInfoChangeEvent?.Invoke();
  113. }
  114. public int GetDeviceType(BluetoothPlayer player) => PlayerDeviceTypeStore.GetType(player);
  115. public int GetActivePlayerDeviceType()
  116. {
  117. BluetoothPlayer player = BluetoothPlayer.FIRST_PLAYER;
  118. if (Ble != null)
  119. player = Ble.getBLEPlayer();
  120. return GetDeviceType(player);
  121. }
  122. public void SetAimDeviceMac(string _mac)
  123. {
  124. BluetoothPlayer player = BluetoothPlayer.FIRST_PLAYER;
  125. if (Ble != null)
  126. player = Ble.getBLEPlayer();
  127. else if (deviceSelectIndex >= 0)
  128. player = (BluetoothPlayer)deviceSelectIndex;
  129. int sdkDeviceId = GetSdkDeviceId(player);
  130. SdkAimDeviceInfo info = GetAimDeviceInfo(player);
  131. if (info == null)
  132. info = new SdkAimDeviceInfo(sdkDeviceId);
  133. info.setInitMac(_mac);
  134. SaveSdkDeviceInfo(info, sdkDeviceId);
  135. if (deviceSelectIndex == (int)player)
  136. aimDeviceInfo = info;
  137. aimDeviceInfoChangeEvent?.Invoke();
  138. }
  139. public void ResetAimDeviceMac()
  140. {
  141. BluetoothPlayer player = BluetoothPlayer.FIRST_PLAYER;
  142. if (Ble != null)
  143. player = Ble.getBLEPlayer();
  144. else if (deviceSelectIndex >= 0)
  145. player = (BluetoothPlayer)deviceSelectIndex;
  146. int sdkDeviceId = GetSdkDeviceId(player);
  147. SdkAimDeviceInfo info = GetAimDeviceInfo(player);
  148. if (info == null)
  149. return;
  150. info.resetInitMac();
  151. SaveSdkDeviceInfo(info, sdkDeviceId);
  152. if (deviceSelectIndex == (int)player)
  153. aimDeviceInfo = info;
  154. aimDeviceInfoChangeEvent?.Invoke();
  155. }
  156. /// <summary>侧滑连接是否为「切换设备页选型覆盖」;false 表示直接连接,沿用已记录 MAC。</summary>
  157. bool _sideSlipOverwritesDeviceInfo;
  158. public bool SideSlipOverwritesDeviceInfo => _sideSlipOverwritesDeviceInfo;
  159. public void ClearSideSlipOverwriteFlag() => _sideSlipOverwritesDeviceInfo = false;
  160. public void OverwriteAimDeviceInfoForPlayer(BluetoothPlayer player, AimDeviceType deviceType)
  161. {
  162. SetAimDeviceSelectIndex((int)player);
  163. int sdkDeviceId = GetSdkDeviceId(player);
  164. SdkAimDeviceInfo info = GetAimDeviceInfo(player);
  165. if (info == null)
  166. {
  167. info = new SdkAimDeviceInfo(sdkDeviceId);
  168. }
  169. info.resetInitMac();
  170. SaveSdkDeviceInfo(info, sdkDeviceId);
  171. PlayerDeviceTypeStore.SetType(player, (int)deviceType);
  172. aimDeviceInfo = info;
  173. _tempDeviceType = (int)deviceType;
  174. _sideSlipOverwritesDeviceInfo = true;
  175. aimDeviceInfoChangeEvent?.Invoke();
  176. }
  177. public void PrepareDirectSideSlipConnect(int selectIndex)
  178. {
  179. SetAimDeviceSelectIndex(selectIndex);
  180. onCreateAimDeviceInfoById();
  181. _sideSlipOverwritesDeviceInfo = false;
  182. }
  183. public SdkAimDeviceInfo GetAimDeviceInfo(BluetoothPlayer player)
  184. {
  185. int sdkDeviceId = GetSdkDeviceId(player);
  186. SmartBowHelper helper = GetHelperForPlayer(player);
  187. if (helper != null)
  188. {
  189. SdkAimDeviceInfo info = helper.GetDeviceInfo(SdkUserTags, sdkDeviceId);
  190. if (info != null)
  191. return info;
  192. }
  193. return LoadSdkDeviceInfoFromPrefs(sdkDeviceId);
  194. }
  195. public bool isHOUYIPRO(BluetoothPlayer bluetoothPlayer) =>
  196. GetDeviceType(bluetoothPlayer) == (int)AimDeviceType.HOUYIPRO;
  197. public bool isARTEMISPro(BluetoothPlayer bluetoothPlayer) =>
  198. GetDeviceType(bluetoothPlayer) == (int)AimDeviceType.ARTEMISPRO;
  199. #endregion
  200. public int DeviceType => 9;
  201. [NonSerialized] public int gyrCalibrateCompleteCount;
  202. [NonSerialized] public int gyrCalibrateTotalCount = 2000;
  203. public bool bInitOne;
  204. public OnCrossBtnEventEvent OnCrossBtnEvent;
  205. public delegate void OnCrossBtnEventEvent();
  206. SmartBowHelper _boundSdk1P;
  207. SmartBowHelper _lastPollSdk;
  208. int _sdkAxisReadyAfterFrame = -1;
  209. bool _magCompleted;
  210. [NonSerialized] public bool lerpForRotation = true;
  211. [NonSerialized] public float lerpTimeRate = 7;
  212. Quaternion _targetRotation = Quaternion.identity;
  213. BluetoothAim Ble => SmartBowDeviceHub.ins?.Ble;
  214. void OnDestroy()
  215. {
  216. UnbindSdk1P();
  217. }
  218. public void InvokeOnCrossBtnEvent()
  219. {
  220. try { OnCrossBtnEvent?.Invoke(); }
  221. catch (Exception e) { Debug.LogError(e); }
  222. }
  223. #region SDK 绑定(1P 数据由 SmartBowHelper / Axis9Handler_SDK 处理)
  224. public void BindSdk1P(SmartBowHelper helper)
  225. {
  226. if (helper == null) return;
  227. if (_boundSdk1P == helper) return;
  228. UnbindSdk1P();
  229. _boundSdk1P = helper;
  230. helper.OnShooting += OnShot1P;
  231. helper.OnBleDeviceState += HandleUpdateTheMagazine;
  232. helper.OnRotationUpdate += OnSdkRotationUpdate;
  233. helper.OnFunctionKeyPress += OnSdkFunctionKeyShortPress;
  234. helper.OnFunctionKeyLongPress += OnSdkFunctionKeyLongPress;
  235. helper.OnDeviceAndSystemInfoEvent += HandleDeviceAndSystemInfo;
  236. MarkSdkAxisPending(helper);
  237. }
  238. public void UnbindSdk1P()
  239. {
  240. if (_boundSdk1P == null) return;
  241. _boundSdk1P.OnShooting -= OnShot1P;
  242. _boundSdk1P.OnBleDeviceState -= HandleUpdateTheMagazine;
  243. _boundSdk1P.OnRotationUpdate -= OnSdkRotationUpdate;
  244. _boundSdk1P.OnFunctionKeyPress -= OnSdkFunctionKeyShortPress;
  245. _boundSdk1P.OnFunctionKeyLongPress -= OnSdkFunctionKeyLongPress;
  246. _boundSdk1P.OnDeviceAndSystemInfoEvent -= HandleDeviceAndSystemInfo;
  247. _boundSdk1P = null;
  248. }
  249. SmartBowHelper GetSdk1P()
  250. {
  251. if (_boundSdk1P != null) return _boundSdk1P;
  252. return SmartBowDeviceHub.ins?.Ble?.getSmartBowHelper1P();
  253. }
  254. SmartBowHelper GetSdkForCalibration()
  255. {
  256. BluetoothAim ble = Ble;
  257. if (ble == null) return GetSdk1P();
  258. if (ble.getBLEPlayer() == BluetoothPlayer.SECOND_PLAYER)
  259. return ble.getSmartBowHelper2P();
  260. return GetSdk1P();
  261. }
  262. void OnSdkRotationUpdate(Quaternion rotation)
  263. {
  264. _targetRotation = rotation;
  265. if (!bRuning9Axis()) return;
  266. if (SB_EventSystem.ins && SB_EventSystem.ins.simulateMouseIsAwaked)
  267. SB_EventSystem.ins.MoveSimulateMouse(rotation);
  268. if (m_controlObj == null) return;
  269. if (lerpForRotation)
  270. m_controlObj.localRotation = Quaternion.Lerp(m_controlObj.localRotation, rotation, Time.deltaTime * lerpTimeRate);
  271. else
  272. m_controlObj.localRotation = rotation;
  273. }
  274. void OnSdkFunctionKeyShortPress() => HandleFunctionKeyShortPress();
  275. void OnSdkFunctionKeyLongPress() => HandleFunctionKeyLongPress();
  276. #endregion
  277. #region 九轴 / 校准(委托 SDK,不再使用本地 Axis9Handler)
  278. public void ReinitAxisHandler()
  279. {
  280. if (!UsesNineAxisDevice())
  281. return;
  282. Debug.Log("[AppUI.AimHandler] 九轴设备 HOUYI/HOUYI2/ARTEMIS,旋转与校准走 SDK Axis9Handler。");
  283. }
  284. public void SetMsOldDefault() { }
  285. public void DoIdentity()
  286. {
  287. GetSdkForCalibration()?.ResetAim();
  288. if (!bRuning9Axis()) return;
  289. if (m_controlObj) m_controlObj.localRotation = _targetRotation;
  290. }
  291. public void NotifyAxisOnShot() { }
  292. public void CalibrateGyr(bool calibration)
  293. {
  294. if (!UsesNineAxisDevice()) return;
  295. var sdk = GetSdkForCalibration();
  296. if (sdk == null || !CanPollSdkAxisCalibration(sdk)) return;
  297. if (calibration) sdk.StartGyrCalibration();
  298. else sdk.StopGyrCalibration();
  299. }
  300. public void InitGyr(string record) { }
  301. public void InitMag(string record) { }
  302. public void ResetGyr()
  303. {
  304. if (!UsesNineAxisDevice()) return;
  305. var sdk = GetSdkForCalibration();
  306. if (sdk == null || !CanPollSdkAxisCalibration(sdk)) return;
  307. sdk.StopGyrCalibration();
  308. }
  309. public void ResetMag()
  310. {
  311. if (!UsesNineAxisDevice()) return;
  312. TryStartMagCalibration();
  313. }
  314. public void ApplyImpreciseMag() { }
  315. public bool IsGyrCompleted()
  316. {
  317. if (!UsesNineAxisDevice()) return false;
  318. var sdk = GetSdkForCalibration();
  319. return sdk != null && CanPollSdkAxisCalibration(sdk) && sdk.IsGyrCompleted();
  320. }
  321. public bool IsMagCompleted()
  322. {
  323. if (!UsesNineAxisDevice()) return false;
  324. var sdk = GetSdkForCalibration();
  325. return sdk != null && CanPollSdkAxisCalibration(sdk) && sdk.IsMagCompleted();
  326. }
  327. public bool IsGyrCalibrating()
  328. {
  329. if (!UsesNineAxisDevice()) return false;
  330. var sdk = GetSdkForCalibration();
  331. return sdk != null && CanPollSdkAxisCalibration(sdk) && sdk.IsGyrCalibrating();
  332. }
  333. public int GetGyrProgressPercent()
  334. {
  335. if (!UsesNineAxisDevice()) return 0;
  336. var sdk = GetSdkForCalibration();
  337. if (sdk == null || !CanPollSdkAxisCalibration(sdk)) return 0;
  338. return Mathf.Clamp(Mathf.FloorToInt(sdk.GetGyrProgress() * 100f), 0, 100);
  339. }
  340. /// <summary>校准页专用:仅校验 SDK 连接与轮询就绪,不重复判断设备档案类型。</summary>
  341. public bool IsSdkGyrCompleted()
  342. {
  343. var sdk = GetSdkForCalibration();
  344. return sdk != null && CanPollSdkAxisCalibration(sdk) && sdk.IsGyrCompleted();
  345. }
  346. /// <summary>校准页专用:仅校验 SDK 连接与轮询就绪,不重复判断设备档案类型。</summary>
  347. public bool IsSdkMagCompleted()
  348. {
  349. var sdk = GetSdkForCalibration();
  350. return sdk != null && CanPollSdkAxisCalibration(sdk) && sdk.IsMagCompleted();
  351. }
  352. public bool TryStartMagCalibration()
  353. {
  354. var sdk = GetSdkForCalibration();
  355. if (sdk == null || !CanPollSdkAxisCalibration(sdk))
  356. return false;
  357. sdk.StartMagCalibration();
  358. return true;
  359. }
  360. /// <summary>对齐 DemoStarter.OnClick_CalibrateGyr:校准中则停止,否则开始。</summary>
  361. public bool TryToggleGyrCalibration()
  362. {
  363. var sdk = GetSdkForCalibration();
  364. if (sdk == null || !CanPollSdkAxisCalibration(sdk))
  365. return false;
  366. if (sdk.IsGyrCalibrating())
  367. sdk.StopGyrCalibration();
  368. else
  369. sdk.StartGyrCalibration();
  370. return true;
  371. }
  372. public bool TryStopGyrCalibration()
  373. {
  374. var sdk = GetSdkForCalibration();
  375. if (sdk == null || !CanPollSdkAxisCalibration(sdk))
  376. return false;
  377. sdk.StopGyrCalibration();
  378. return true;
  379. }
  380. public bool IsSdkGyrCalibrating()
  381. {
  382. var sdk = GetSdkForCalibration();
  383. return sdk != null && CanPollSdkAxisCalibration(sdk) && sdk.IsGyrCalibrating();
  384. }
  385. public int GetSdkGyrProgressPercent()
  386. {
  387. var sdk = GetSdkForCalibration();
  388. if (sdk == null || !CanPollSdkAxisCalibration(sdk)) return 0;
  389. return Mathf.Clamp(Mathf.FloorToInt(sdk.GetGyrProgress() * 100f), 0, 100);
  390. }
  391. public IEnumerator SaveGyr()
  392. {
  393. yield return null;
  394. }
  395. public IEnumerator SaveMag()
  396. {
  397. yield return null;
  398. }
  399. public void ResumeCalibrateRecord(string record)
  400. {
  401. if (string.IsNullOrEmpty(record)) return;
  402. GetSdkForCalibration()?.ResumeCalibrateRecord(record);
  403. }
  404. public void CorrectMagCompleted(bool value) { _magCompleted = value; }
  405. public void Ban9AxisCalculate(bool ban) { }
  406. public bool bRuning9Axis()
  407. {
  408. return GlobalData.MyDeviceMode == DeviceMode.Archery
  409. && Ble != null
  410. && !Ble.isMainConnectToInfraredDevice()
  411. && UsesNineAxisDevice();
  412. }
  413. /// <summary>HOUYI / HOUYI2 / ARTEMIS 走九轴;Pro/枪等不走本地九轴校准轮询。</summary>
  414. public bool UsesNineAxisDevice()
  415. {
  416. BluetoothPlayer player = BluetoothPlayer.FIRST_PLAYER;
  417. if (Ble != null && Ble.getBLEPlayer() == BluetoothPlayer.SECOND_PLAYER)
  418. player = BluetoothPlayer.SECOND_PLAYER;
  419. return IsNineAxisArcheryType(GetDeviceType(player));
  420. }
  421. static bool IsNineAxisArcheryType(int type)
  422. {
  423. return type == (int)AimDeviceType.HOUYI
  424. || type == (int)AimDeviceType.HOUYI2
  425. || type == (int)AimDeviceType.ARTEMIS;
  426. }
  427. public static bool IsInfraredDeviceType(int type)
  428. {
  429. return type == (int)AimDeviceType.HOUYIPRO
  430. || type == (int)AimDeviceType.Gun
  431. || type == (int)AimDeviceType.ARTEMISPRO
  432. || type == (int)AimDeviceType.PistolM17
  433. || type == (int)AimDeviceType.RifleM416;
  434. }
  435. public bool IsActivePlayerInfraredDevice() =>
  436. IsInfraredDeviceType(GetActivePlayerDeviceType());
  437. public bool IsActivePlayerNineAxisDevice() =>
  438. IsNineAxisArcheryType(GetActivePlayerDeviceType());
  439. public SdkAimDeviceInfo GetActivePlayerAimDeviceInfo()
  440. {
  441. BluetoothPlayer player = BluetoothPlayer.FIRST_PLAYER;
  442. if (Ble != null)
  443. player = Ble.getBLEPlayer();
  444. SdkAimDeviceInfo info = GetAimDeviceInfo(player);
  445. if (info == null && aimDeviceInfo != null && aimDeviceInfo.id == GetSdkDeviceId(player))
  446. return aimDeviceInfo;
  447. return info;
  448. }
  449. void MarkSdkAxisPending(SmartBowHelper sdk)
  450. {
  451. if (sdk == null) return;
  452. _lastPollSdk = sdk;
  453. _sdkAxisReadyAfterFrame = Time.frameCount;
  454. }
  455. bool CanPollSdkAxisCalibration(SmartBowHelper sdk)
  456. {
  457. if (sdk == null) return false;
  458. if (sdk.GetBluetoothStatus() != SmartBowSDK.BluetoothStatusEnum.Connected)
  459. return false;
  460. // AimHandler_SDK 在 Start 里 new Axis9Handler_SDK,同帧调用会 NRE
  461. return _sdkAxisReadyAfterFrame < 0 || Time.frameCount > _sdkAxisReadyAfterFrame;
  462. }
  463. #endregion
  464. void Update()
  465. {
  466. if (!UsesNineAxisDevice())
  467. {
  468. _magCompleted = false;
  469. return;
  470. }
  471. var sdk = GetSdkForCalibration();
  472. if (sdk == null)
  473. {
  474. _magCompleted = false;
  475. return;
  476. }
  477. if (sdk != _lastPollSdk)
  478. MarkSdkAxisPending(sdk);
  479. if (!CanPollSdkAxisCalibration(sdk))
  480. return;
  481. if (sdk.IsGyrCalibrating())
  482. gyrCalibrateCompleteCount = (int)(sdk.GetGyrProgress() * gyrCalibrateTotalCount);
  483. if (IsMagCompleted())
  484. {
  485. if (!_magCompleted)
  486. {
  487. StartCoroutine(SaveMag());
  488. PopupMgr.ins?.ShowTipTop(TextAutoLanguage2.GetTextByKey("tip_mag-calibrate_success"));
  489. }
  490. _magCompleted = true;
  491. }
  492. else
  493. {
  494. _magCompleted = false;
  495. }
  496. }
  497. void HandleDeviceAndSystemInfo(ConnectPlatform connectPlatform, BluetoothDeviceType bleDeviceType)
  498. {
  499. var boxUserSettings = FindAnyObjectByType<CustomUIView.BoxUserSettings>();
  500. switch (bleDeviceType)
  501. {
  502. case BluetoothDeviceType.HOUYIPro:
  503. UserSettings.ins.selectDevicesName = "HOUYI Pro";
  504. UserSettings.ins.Save();
  505. boxUserSettings?.OnUpdateClickInfoByName();
  506. break;
  507. case BluetoothDeviceType.ARTEMISPro:
  508. UserSettings.ins.selectDevicesName = "ARTEMIS Pro";
  509. UserSettings.ins.Save();
  510. boxUserSettings?.OnUpdateClickInfoByName();
  511. break;
  512. case BluetoothDeviceType.PistolM9:
  513. UserSettings.ins.selectDevicesName = "Pistol M9";
  514. UserSettings.ins.Save();
  515. boxUserSettings?.OnUpdateClickInfoByName();
  516. break;
  517. }
  518. }
  519. //弹夹状态
  520. public BluetoothDeviceStatus bluetoothDeviceStatus = BluetoothDeviceStatus.MagazineLoading;
  521. /// <summary>
  522. /// 0x00 - 弹夹分离 0x01 - 弹夹上膛
  523. /// </summary>
  524. /// <param name="bytes"></param>
  525. void HandleUpdateTheMagazine(BluetoothDeviceType bleDeviceType, BluetoothDeviceStatus gunStatusEnum)
  526. {
  527. bluetoothDeviceStatus = gunStatusEnum;
  528. if (gunStatusEnum == BluetoothDeviceStatus.MagazineLoading)
  529. {
  530. //播放上弹夹时候的声音
  531. AudioMgr.ins.PlayBeLoaded();
  532. Debug.Log("弹夹上膛");
  533. if (Billboard.ins)
  534. {
  535. Billboard.ins.bulletManager.ResetBullets(); //game
  536. }
  537. }
  538. Ble.InvokeOnBleDevice(bleDeviceType, gunStatusEnum);
  539. }
  540. void HandleFunctionKeyShortPress()
  541. {
  542. if (bInitOne)
  543. {
  544. bInitOne = false;
  545. if (IsLegacyArcheryType(GetActivePlayerDeviceType()))
  546. AutoResetView.DoIdentity();
  547. else
  548. CrossBtnEvent();
  549. return;
  550. }
  551. if (SB_EventSystem.ins && SB_EventSystem.ins.simulateMouseIsAwaked)
  552. {
  553. if (FindAnyObjectByType<InfraredGuider>() == null)
  554. DoIdentity();
  555. if (FindAnyObjectByType<InfraredScreenPositioningView>() != null)
  556. InvokeOnCrossBtnEvent();
  557. }
  558. else
  559. {
  560. if (IsLegacyArcheryType(GetActivePlayerDeviceType()))
  561. AutoResetView.DoIdentity();
  562. else
  563. CrossBtnEvent();
  564. }
  565. }
  566. void HandleFunctionKeyLongPress()
  567. {
  568. if (GlobalData.MyDeviceMode == DeviceMode.Gun || (Ble != null && Ble.isMainConnectToInfraredDevice()))
  569. {
  570. InfraredGuider infraredGuider = FindAnyObjectByType<InfraredGuider>();
  571. if (infraredGuider == null)
  572. AutoResetView.DoIdentity();
  573. else
  574. infraredGuider.onLongClickDevice();
  575. }
  576. else if (SB_EventSystem.ins)
  577. {
  578. SB_EventSystem.ins.AwakenSimulateMouse();
  579. }
  580. }
  581. static bool IsLegacyArcheryType(int type)
  582. {
  583. return type == (int)AimDeviceType.NONE
  584. || type == (int)AimDeviceType.HOUYI
  585. || type == (int)AimDeviceType.HOUYI2
  586. || type == (int)AimDeviceType.ARTEMIS;
  587. }
  588. void CrossBtnEvent()
  589. {
  590. Debug.Log("CrossBtnEvent");
  591. InvokeOnCrossBtnEvent();
  592. if (CommonConfig.StandaloneModeOrPlatformB)
  593. {
  594. FindAnyObjectByType<InfraredGuider>()?.onClickDevice();
  595. return;
  596. }
  597. if (GameAssistUI.ins)
  598. {
  599. InfraredGuider infraredGuider = FindAnyObjectByType<InfraredGuider>();
  600. if (infraredGuider == null)
  601. {
  602. Transform button5 = GameAssistUI.ins.transform.Find("Button5");
  603. if (button5 != null && button5.gameObject.activeSelf)
  604. button5.GetComponent<Button>()?.onClick.Invoke();
  605. else
  606. {
  607. bool onlyShow = !CrossHair.ins.GetOnlyShow();
  608. CrossHair.ins.SetOnlyShow(onlyShow);
  609. InfraredDemo._ins?.setCrosshairValue(onlyShow);
  610. }
  611. }
  612. else
  613. {
  614. infraredGuider.onClickDevice();
  615. }
  616. }
  617. }
  618. #region 旧逻辑射击触发
  619. float _lastShootTime;
  620. void OnShot1P(float shootSpeed)
  621. {
  622. if (GlobalData.MyDeviceMode == DeviceMode.Gun)
  623. {
  624. if (Time.realtimeSinceStartup - _lastShootTime >= 1)
  625. {
  626. _lastShootTime = Time.realtimeSinceStartup;
  627. if (FindAnyObjectByType<View.Infrared.InfraredScreenPositioningView>() != null)
  628. InvokeOnCrossBtnEvent();
  629. }
  630. }
  631. if (SB_EventSystem.ins && SB_EventSystem.ins.simulateMouseIsAwaked)
  632. {
  633. SB_EventSystem.ins.ClickMouse();
  634. }
  635. else if (ArmBow.ins)
  636. {
  637. ArmBow.ins.ADS_fire(true);
  638. }
  639. else if (DuckHunter.SmartBowController.Instance)
  640. {
  641. //野鸭射击
  642. DuckHunter.SmartBowController.Instance.OnShooting(shootSpeed);
  643. }
  644. else if (WildAttack.SmartBowController.Instance)
  645. {
  646. //荒野射击
  647. WildAttack.SmartBowController.Instance.OnShooting(shootSpeed);
  648. }
  649. else if (GameController.ins && GameController.ins.GetArmBowDoublePlayer(PlayerType.FirstPlayer) != null)
  650. {
  651. //本地双人模式下处理1p,2P 在 BluetoothAim 类处理
  652. GameController.ins.GetArmBowDoublePlayer(PlayerType.FirstPlayer).ADS_fire(true, shootSpeed);
  653. }
  654. else if (GeneratingTarget.gm != null)
  655. {
  656. //移动目标
  657. GeneratingTarget.gm.Shooting(true);
  658. }
  659. }
  660. public void OnShot2P(float speed)
  661. {
  662. if (SceneManager.GetActiveScene().name.Equals("WildAttackDouble"))
  663. {
  664. WildAttack.SmartBowController.Instance.OnShooting2P(speed);
  665. }
  666. else
  667. {
  668. if (GameController.ins.GetArmBowDoublePlayer(PlayerType.SecondPlayer) != null)
  669. {
  670. //本地双人模式下处理2P ,1P在 ShootCheck 类处理
  671. GameController.ins.GetArmBowDoublePlayer(PlayerType.SecondPlayer).ADS_fire(true, speed);
  672. }
  673. }
  674. }
  675. #endregion
  676. }
  677. }