AimHandler.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622
  1. using System;
  2. using UnityEngine;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using UnityEngine.UI;
  6. using UnityEngine.SceneManagement;
  7. using WildAttack;
  8. using DuckHunter;
  9. public enum AimDeviceType {
  10. NONE = -1,
  11. HOUYI = 0,
  12. HOUYI2 = 1,
  13. ARTEMIS = 2,
  14. HOUYIPRO = 3,
  15. //枪械类
  16. Gun = 4,
  17. ARTEMISPRO = 5,
  18. }
  19. [Serializable]//需要在转换为json格式的类的上方添加序列化
  20. public class AimDeviceInfo
  21. {
  22. public int id;
  23. public int type = -1;//类型 AimDeviceType
  24. public int pos; //位置
  25. public bool bInitMac = false; //是否初始化Mac
  26. public string mac; //记录当前
  27. public AimDeviceInfo(int _id) {
  28. this.id = _id;
  29. }
  30. public void setInitMac(string macTemp) {
  31. bInitMac = true;
  32. mac = macTemp;
  33. }
  34. public void resetInitMac() {
  35. bInitMac = false;
  36. mac = "";
  37. }
  38. }
  39. [Serializable]
  40. public class AimDeviceInfos
  41. {
  42. public List<AimDeviceInfo> arry;
  43. }
  44. /* 瞄准处理器 */
  45. public class AimHandler : MonoBehaviour
  46. {
  47. CameraToLook m_controlObj {
  48. get {
  49. return CameraToLook.ins;
  50. }
  51. }
  52. //记录一个设备
  53. public AimDeviceInfo aimDeviceInfo = null;
  54. public AimDeviceInfo tempAimDeviceInfo = null;//临时处理值。最后赋值给aimDeviceInfo
  55. public AimDeviceInfos aimDeviceInfos = new AimDeviceInfos();
  56. int deviceSelectIndex = 0;//默认选中第一个设备(1p)
  57. public Action aimDeviceInfoChangeEvent;
  58. public int DeviceType
  59. {
  60. get
  61. {
  62. if (m_axisHandler.GetType() == typeof(Axis9Handler)) return 9;
  63. if (m_axisHandler.GetType() == typeof(Axis663Handler)) return 663;
  64. return 0;
  65. }
  66. }
  67. private AxisBaseHandler m_axisHandler;
  68. //陀螺仪校准进度记录
  69. [NonSerialized] public int gyrCalibrateCompleteCount = 0;
  70. [NonSerialized] public int gyrCalibrateTotalCount = 2000;
  71. public static AimHandler ins;
  72. public bool bInitOne = false;
  73. void Start()
  74. {
  75. ins = this;
  76. BluetoothDispatcher.aim = OnDataReceived;
  77. // m_axisHandler = new Axis9NopackHandler(this); //九轴旧
  78. m_axisHandler = new Axis9Handler(this); //九轴新
  79. // m_axisHandler = new Axis663Handler(this); //双陀螺仪
  80. m_axisHandler.Init();
  81. // StartCoroutine(TestRecord());
  82. }
  83. public void onClearAimDeviceInfosNew()
  84. {
  85. PlayerPrefs.DeleteKey("aim-device-info-" + LoginMgr.myUserInfo.id);
  86. aimDeviceInfos.arry.Clear();
  87. }
  88. public void OnGetAimDeviceInfos() {
  89. string deviceInfo = PlayerPrefs.GetString("aim-device-info-" + LoginMgr.myUserInfo.id, "");
  90. Debug.Log("get deviceSelectIndex:" + deviceInfo);
  91. if (deviceInfo != "")
  92. {
  93. aimDeviceInfos = JsonUtility.FromJson<AimDeviceInfos>(deviceInfo);//这里的类是依据最外层{}决定的
  94. }
  95. aimDeviceInfoChangeEvent?.Invoke();
  96. }
  97. public void OnSaveAimDeviceInfos()
  98. {
  99. aimDeviceInfoChangeEvent?.Invoke();
  100. PlayerPrefs.SetString("aim-device-info-" + LoginMgr.myUserInfo.id, JsonUtility.ToJson(aimDeviceInfos));
  101. }
  102. //创建一个选择值
  103. public void onCreateTempAimDeviceInfo() {
  104. tempAimDeviceInfo = new AimDeviceInfo(deviceSelectIndex);
  105. Debug.Log("onCreateTempAimDeviceInfo deviceSelectIndex:" + deviceSelectIndex);
  106. }
  107. //是否存在AimDeviceInfo,存在更新,不存在创建;
  108. public void onCreateAimDeviceInfoById()
  109. {
  110. OnGetAimDeviceInfos();
  111. //deviceIndex 区分 1p 还是 2p
  112. bool bCanAdd = true;
  113. foreach (AimDeviceInfo p in aimDeviceInfos.arry)
  114. {
  115. if (deviceSelectIndex == p.id)
  116. {
  117. aimDeviceInfo = p;
  118. bCanAdd = false;
  119. }
  120. //Debug.Log("33deviceSelectIndex:" + deviceSelectIndex + ",bCanAdd:" + bCanAdd+ " , id:" + p.id +" , type:"+ p.type);
  121. }
  122. if (bCanAdd)
  123. {
  124. Debug.Log("add deviceSelectIndex:" + deviceSelectIndex);
  125. aimDeviceInfo = new AimDeviceInfo(deviceSelectIndex);
  126. aimDeviceInfos.arry.Add(aimDeviceInfo);
  127. }
  128. OnSaveAimDeviceInfos();
  129. }
  130. public void SetAimDeviceSelectIndex(int selectIndex) {
  131. if (selectIndex < 0) {
  132. Debug.LogWarning("selectIndex不能小于0:"+ selectIndex);
  133. return;
  134. }
  135. deviceSelectIndex = selectIndex;
  136. Debug.Log("SetAimDeviceSelectIndex :" + selectIndex);
  137. }
  138. public void SetTempAimDeviceType(AimDeviceType _aimDeviceType)
  139. {
  140. if (tempAimDeviceInfo == null) return;
  141. tempAimDeviceInfo.type = (int)_aimDeviceType;
  142. }
  143. public void SetAimDeviceType(AimDeviceType _aimDeviceType)
  144. {
  145. if (aimDeviceInfo == null) return;
  146. aimDeviceInfo.type = (int)_aimDeviceType;
  147. _AimDeviceInfosUpdate();
  148. OnSaveAimDeviceInfos();
  149. }
  150. public void SetAimDeviceType(int _aimDeviceType)
  151. {
  152. if (aimDeviceInfo == null) return;
  153. aimDeviceInfo.type = _aimDeviceType;
  154. _AimDeviceInfosUpdate();
  155. OnSaveAimDeviceInfos();
  156. }
  157. //APP连接需进行MAC地址的比对。
  158. //只有再引导初始化页面才保存连接使用的mac地址。
  159. public void SetAimDeviceMac(string _mac) {
  160. if (aimDeviceInfo == null) return;
  161. aimDeviceInfo.setInitMac(_mac);
  162. _AimDeviceInfosUpdate();
  163. OnSaveAimDeviceInfos();
  164. }
  165. //重置mac存储信息
  166. public void ResetAimDeviceMac() {
  167. if (aimDeviceInfo == null) return;
  168. aimDeviceInfo.resetInitMac();
  169. _AimDeviceInfosUpdate();
  170. OnSaveAimDeviceInfos();
  171. }
  172. void _AimDeviceInfosUpdate() {
  173. for (int i = 0; i < aimDeviceInfos.arry.Count; i++)
  174. {
  175. if (aimDeviceInfo.id == aimDeviceInfos.arry[i].id)
  176. {
  177. aimDeviceInfos.arry[i] = aimDeviceInfo;
  178. }
  179. }
  180. }
  181. #region 根据设备1p或者2p 获取HOUYIPRO的状态
  182. public bool isHOUYIPRO(BluetoothPlayer bluetoothPlayer)
  183. {
  184. bool _isHOUYIPRO = false;
  185. foreach (AimDeviceInfo p in AimHandler.ins.aimDeviceInfos.arry)
  186. {
  187. if ((int)bluetoothPlayer == p.id && p.type == (int)AimDeviceType.HOUYIPRO)
  188. {
  189. _isHOUYIPRO = true;
  190. }
  191. }
  192. return _isHOUYIPRO;
  193. }
  194. #endregion
  195. #region 根据设备1p或者2p 获取ARTEMISPro的状态
  196. public bool isARTEMISPro(BluetoothPlayer bluetoothPlayer)
  197. {
  198. bool _isARTEMISPro = false;
  199. foreach (AimDeviceInfo p in ins.aimDeviceInfos.arry)
  200. {
  201. if ((int)bluetoothPlayer == p.id && p.type == (int)AimDeviceType.ARTEMISPRO)
  202. {
  203. _isARTEMISPro = true;
  204. }
  205. }
  206. return _isARTEMISPro;
  207. }
  208. #endregion
  209. public void ReinitAxisHandler()
  210. {
  211. Debug.Log("ReinitAxisHandler");
  212. m_axisHandler.Init();
  213. }
  214. // System.Collections.IEnumerator TestRecord() {
  215. // while (LoginMgr.myUserInfo.id == 0) yield return null;
  216. // UserComp.Instance.saveMac();
  217. // }
  218. [NonSerialized] private Quaternion newRotation = Quaternion.identity;
  219. public void SetNewRotation(Quaternion quat) {
  220. this.newRotation = quat;
  221. }
  222. public void SetNewRotation(o0.Geometry.Quaternion o0Quat) {
  223. Quaternion quat = o0.Bow.Extension.ToUnityQuaternion(o0Quat);
  224. if (float.IsNaN(quat.x) || float.IsNaN(quat.y) || float.IsNaN(quat.z) || float.IsNaN(quat.w)) {
  225. Debug.LogError($"九轴Rotation存在Nan值,double:{o0Quat.ToString()},float:{quat.ToString()}");
  226. return;
  227. }
  228. if (float.IsInfinity(quat.x) || float.IsInfinity(quat.y) || float.IsInfinity(quat.z) || float.IsInfinity(quat.w)) {
  229. Debug.LogError($"九轴Rotation存在Infinity值,double:{o0Quat.ToString()},float:{quat.ToString()}");
  230. return;
  231. }
  232. this.newRotation = quat;
  233. }
  234. [NonSerialized] public bool lerpForRotation = true;
  235. [NonSerialized] public float lerpTimeRate = 7;
  236. public void Update()
  237. {
  238. //&& !InfraredDemo.running
  239. if (m_controlObj && !m_ban9AxisCalculate && bRuning9Axis())
  240. {
  241. if (lerpForRotation)
  242. m_controlObj.localRotation = Quaternion.Lerp(m_controlObj.localRotation, newRotation, Time.deltaTime * lerpTimeRate);
  243. else
  244. m_controlObj.localRotation = newRotation;
  245. }
  246. if (IsMagCompleted())
  247. {
  248. if (!m_magCompleted)
  249. {
  250. StartCoroutine(SaveMag());
  251. PopupMgr.ins.ShowTipTop(TextAutoLanguage2.GetTextByKey("tip_mag-calibrate_success"));
  252. }
  253. m_magCompleted = true;
  254. } else {
  255. m_magCompleted = false;
  256. }
  257. if (Input.GetKeyDown(KeyCode.Space))
  258. {
  259. AutoResetView.DoIdentity();
  260. }
  261. }
  262. public void OnDataReceived(byte[] bytes)
  263. {
  264. if (bytes.Length != 27 && bytes.Length != 39)
  265. {
  266. if (bytes.Length == 2)
  267. {
  268. if (bytes[0] == 0x66 && bytes[1] == 0x31)
  269. {
  270. if (bInitOne)
  271. {
  272. bInitOne = false;
  273. if (aimDeviceInfo.type == (int)AimDeviceType.NONE ||
  274. aimDeviceInfo.type == (int)AimDeviceType.HOUYI ||
  275. aimDeviceInfo.type == (int)AimDeviceType.HOUYI2 ||
  276. aimDeviceInfo.type == (int)AimDeviceType.ARTEMIS)
  277. {
  278. AutoResetView.DoIdentity();
  279. }
  280. else
  281. {
  282. //准心开关
  283. CrossBtnEvent();
  284. }
  285. }
  286. else
  287. {
  288. if (SB_EventSystem.ins && SB_EventSystem.ins.simulateMouseIsAwaked)
  289. {
  290. //模拟鼠标弹出时候
  291. InfraredGuider infraredGuider = FindAnyObjectByType<InfraredGuider>();
  292. if (infraredGuider != null)
  293. {
  294. //待检测到用户操作了两次单击按键功能,进入下一步
  295. if (GameMgr.ButtonCount == 1)
  296. {
  297. GameMgr.ButtonCount = 0;
  298. infraredGuider.OnStep2ShootTest();
  299. }
  300. else
  301. {
  302. GameMgr.ButtonCount++;
  303. }
  304. }
  305. else
  306. {
  307. //视角回正
  308. DoIdentity();
  309. //鼠标居中自然会居中
  310. }
  311. }
  312. else
  313. {
  314. if (aimDeviceInfo.type == (int)AimDeviceType.NONE ||
  315. aimDeviceInfo.type == (int)AimDeviceType.HOUYI ||
  316. aimDeviceInfo.type == (int)AimDeviceType.HOUYI2 ||
  317. aimDeviceInfo.type == (int)AimDeviceType.ARTEMIS)
  318. {
  319. AutoResetView.DoIdentity();
  320. }
  321. else
  322. {
  323. //准心开关
  324. CrossBtnEvent();
  325. }
  326. }
  327. }
  328. }
  329. else if (bytes[0] == 0x66 && bytes[1] == 0x32)
  330. {
  331. //红外部分
  332. if (GlobalData.MyDeviceMode == DeviceMode.Gun || BluetoothAim.ins && BluetoothAim.ins.isMainConnectToInfraredDevice())
  333. { //‘校准'功能的调用,使用原来调出光标的功能键;即在HOUYI Pro使用长按视角归位键;在ARTEMIS Pro使用快速双击按键
  334. AutoResetView.DoIdentity();
  335. }
  336. else if (SB_EventSystem.ins)
  337. {
  338. // if (SB_EventSystem.ins && !CommonConfig.SpecialVersion1) {
  339. //唤起/隐藏虚拟鼠标
  340. SB_EventSystem.ins.AwakenSimulateMouse();
  341. }
  342. }
  343. else if (bytes[1] == 10)
  344. {
  345. //显示电量
  346. DeviceBatteryView.ins.RenderBattery(1, bytes[0]);
  347. //DeviceView.ins.RenderBattery(1, bytes[0]);
  348. }
  349. }
  350. else if (bytes[0] == 0x5b)
  351. {
  352. //红外射击检测
  353. ShootCheck.ins.ShootByInfrared(bytes);
  354. }
  355. else if (bytes[0] == 0x5C)
  356. {
  357. //00 弹夹分离,01 上弹夹
  358. ShootCheck.ins.UpdateTheMagazine(bytes);
  359. }
  360. else if (bytes[0] == 0x5E)
  361. {
  362. Debug.Log("接收到系统数据:" + BitConverter.ToString(bytes));
  363. //设备类型
  364. switch (bytes[1])
  365. {
  366. case 0x01:
  367. Debug.Log("设备类型:HOUYI Pro");
  368. break;
  369. case 0x02:
  370. Debug.Log("设备类型:ARTEMIS Pro");
  371. break;
  372. case 0x03:
  373. Debug.Log("设备类型:Pistol 1");
  374. break;
  375. }
  376. // 系统类型
  377. switch (bytes[2])
  378. {
  379. case 0x01:
  380. Debug.Log("系统类型:移动手机");
  381. break;
  382. case 0x02:
  383. Debug.Log("系统类型:PC电脑");
  384. break;
  385. case 0x03:
  386. Debug.Log("系统类型:VR设备");
  387. break;
  388. }
  389. }
  390. return;
  391. }
  392. //if (InfraredDemo.running)
  393. //{
  394. // BluetoothAim.ins.WriteData("4"); //关闭九轴
  395. // return;
  396. //}
  397. if (!bRuning9Axis())
  398. {
  399. return;
  400. }
  401. m_axisHandler.Update(bytes);
  402. if (BowQuatDebug.ins) BowQuatDebug.ins.ShowModuleQuat(newRotation.eulerAngles);
  403. if (SB_EventSystem.ins && SB_EventSystem.ins.simulateMouseIsAwaked) SB_EventSystem.ins.MoveSimulateMouse(newRotation);
  404. }
  405. public byte[] InsertByteAtBeginning(byte[] originalArray, byte newByte)
  406. {
  407. byte[] newArray = new byte[originalArray.Length + 1];
  408. newArray[0] = newByte;
  409. Array.Copy(originalArray, 0, newArray, 1, originalArray.Length);
  410. return newArray;
  411. }
  412. private bool m_magCompleted;
  413. public void CorrectMagCompleted(bool value) { m_magCompleted = value; }
  414. private bool m_ban9AxisCalculate = false;
  415. public void Ban9AxisCalculate(bool ban)
  416. {
  417. // m_ban9AxisCalculate = ban;
  418. // if (!ban)
  419. // {
  420. // SetMsOldDefault();
  421. // if (m_controlObj) m_controlObj.localRotation = newRotation;
  422. // }
  423. }
  424. public void SetMsOldDefault()
  425. {
  426. if (m_axisHandler.GetType() == typeof(Axis9NopackHandler))
  427. (m_axisHandler as Axis9NopackHandler).msOld = default;
  428. }
  429. public void DoIdentity()
  430. {
  431. //if (InfraredDemo.running) return;
  432. m_axisHandler.DoIdentity();
  433. if (!bRuning9Axis()) return;
  434. if (m_controlObj) m_controlObj.localRotation = newRotation;
  435. }
  436. public void NotifyAxisOnShot() { m_axisHandler.NotifyAxisOnShot(); }
  437. public void CalibrateGyr(bool calibration) { m_axisHandler.CalibrateGyr(calibration); }
  438. public void InitGyr(string record) { m_axisHandler.InitGyr(record); }
  439. public void InitMag(string record) { m_axisHandler.InitMag(record); }
  440. public void ResetGyr() { m_axisHandler.ResetGyr(); }
  441. public void ResetMag() { m_axisHandler.ResetMag(); }
  442. public void ApplyImpreciseMag() { m_axisHandler.ApplyImpreciseMag(); }
  443. public bool IsGyrCompleted() { return m_axisHandler.IsGyrCompleted(); }
  444. public bool IsMagCompleted() { return m_axisHandler.IsMagCompleted(); }
  445. public IEnumerator SaveGyr() { return m_axisHandler.SaveGyr(); }
  446. public IEnumerator SaveMag() { return m_axisHandler.SaveMag(); }
  447. public void ResumeCalibrateRecord(string record) { m_axisHandler.ResumeCalibrateRecord(record); }
  448. #region 获取一个连接的设备下,对应的 Archery 是运行9轴的代码处理位置信息判断
  449. public bool bRuning9Axis() {
  450. //连接的设备下,对应的 Archery 是运行9轴的代码处理位置信息判断
  451. //弓箭类型,但是不是HOUYI Pro 情况下。运行9轴代码
  452. bool bRuning = GlobalData.MyDeviceMode == DeviceMode.Archery && !BluetoothAim.ins.isMainConnectToInfraredDevice();
  453. return bRuning;
  454. }
  455. #endregion
  456. /// <summary>
  457. /// 操作准心开关事件
  458. /// </summary>
  459. private void CrossBtnEvent()
  460. {
  461. Debug.Log("CrossBtnEvent");
  462. //准心开关
  463. if (GameAssistUI.ins)
  464. {
  465. InfraredGuider infraredGuider = FindAnyObjectByType<InfraredGuider>();
  466. if (infraredGuider == null)
  467. {
  468. //显示控制准心按钮
  469. Button crossHairBtn = GameAssistUI.ins.transform.Find("Button5").GetComponent<Button>();
  470. crossHairBtn.onClick.Invoke();
  471. }
  472. //if (GameMgr.bShowDistance)
  473. //{
  474. // //显示控制准心按钮
  475. // Button crossHairBtn = GameAssistUI.ins.transform.Find("Button5").GetComponent<Button>();
  476. // crossHairBtn.onClick.Invoke();
  477. //}
  478. //else {
  479. // //校准
  480. // InfraredDemo._ins?.OnClick_SetAdjustPointsOffset();
  481. //}
  482. }
  483. else if (DuckHunter.GameUI.Instance)
  484. {
  485. //显示控制准心按钮
  486. Button crossHairBtn = DuckHunter.GameUI.Instance.transform.Find("BtnCrosshair").GetComponent<Button>();
  487. crossHairBtn.onClick.Invoke();
  488. }
  489. else if (HyperspaceGame.UIManager._ins) {
  490. //打枪
  491. Button crossHairBtn = HyperspaceGame.UIManager._ins.transform.Find("BtnCrosshair").GetComponent<Button>();
  492. crossHairBtn.onClick.Invoke();
  493. }
  494. else
  495. {
  496. if (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name.StartsWith("FruitMaster")){
  497. //水果
  498. Button crossHairBtn = GameObject.Find("PermanentCanvas/CrossHair_Btn").GetComponent<Button>();
  499. crossHairBtn.onClick.Invoke();
  500. }
  501. }
  502. }
  503. /// <summary>
  504. /// 退出进入游戏事件
  505. /// </summary>
  506. public void ExitIntoEvent()
  507. {
  508. string sceneName = SceneManager.GetActiveScene().name;
  509. if (sceneName == "Home")
  510. {
  511. //进入游戏
  512. //EnterTheGame();
  513. return;
  514. }
  515. switch (sceneName)
  516. {
  517. //退出游戏
  518. case "Game":
  519. GameAssistUI.ins.onBtnBack();
  520. break;
  521. case "GameChallenge":
  522. GameAssistUI.ins.onBtnBack();
  523. break;
  524. case "GameDouble":
  525. GameAssistUI.ins.onBtnBack();
  526. break;
  527. case "Hyperspace03":
  528. HyperspaceGame.UIManager._ins.OnShutDown();
  529. break;
  530. case "Hyperspace02":
  531. HyperspaceGame.UIManager._ins.OnShutDown();
  532. break;
  533. case "Hyperspace01":
  534. HyperspaceGame.UIManager._ins.OnShutDown();
  535. break;
  536. case "FruitMaster":
  537. GamingManager.gaming.onShowResultView();
  538. break;
  539. case "WildAttack":
  540. UIManager.GetInstance().onShowResultView();
  541. break;
  542. case "DuckHunter":
  543. GameUI.Instance.onShowResultView();
  544. break;
  545. }
  546. }
  547. public int gameNum = 0;
  548. void EnterTheGame()
  549. {
  550. if (gameNum == 0)
  551. {
  552. HomeView_ChallengeOption.homeView_.OnSelectionChanged(HomeView_ChallengeOption.homeView_.gameIndex, true);
  553. gameNum += 1;
  554. }
  555. if(gameNum == 1)
  556. {
  557. Debug.Log("进入单人游戏模式");
  558. ModeSelectView.ins.OnChangeButton(0);
  559. gameNum = 0;
  560. }
  561. }
  562. }