AimHandler.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. using System;
  2. using UnityEngine;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using UnityEngine.UI;
  6. public enum AimDeviceType {
  7. NONE = -1,
  8. HOUYI = 0,
  9. HOUYI2 = 1,
  10. ARTEMIS = 2,
  11. HOUYIPRO = 3,
  12. //枪械类
  13. Gun = 4,
  14. }
  15. [Serializable]//需要在转换为json格式的类的上方添加序列化
  16. public class AimDeviceInfo
  17. {
  18. public int id;
  19. public int type = -1;//类型 AimDeviceType
  20. public int pos; //位置
  21. public bool bInitMac = false; //是否初始化Mac
  22. public string mac; //记录当前
  23. public AimDeviceInfo(int _id) {
  24. this.id = _id;
  25. }
  26. public void setInitMac(string macTemp) {
  27. bInitMac = true;
  28. mac = macTemp;
  29. }
  30. public void resetInitMac() {
  31. bInitMac = false;
  32. mac = "";
  33. }
  34. }
  35. [Serializable]
  36. public class AimDeviceInfos
  37. {
  38. public List<AimDeviceInfo> arry;
  39. }
  40. /* 瞄准处理器 */
  41. public class AimHandler : MonoBehaviour
  42. {
  43. CameraToLook m_controlObj {
  44. get {
  45. return CameraToLook.ins;
  46. }
  47. }
  48. //记录一个设备
  49. public AimDeviceInfo aimDeviceInfo = null;
  50. public AimDeviceInfo tempAimDeviceInfo = null;//临时处理值。最后赋值给aimDeviceInfo
  51. public AimDeviceInfos aimDeviceInfos = new AimDeviceInfos();
  52. int deviceSelectIndex = 0;//默认选中第一个设备(1p)
  53. public Action aimDeviceInfoChangeEvent;
  54. public int DeviceType
  55. {
  56. get
  57. {
  58. if (m_axisHandler.GetType() == typeof(Axis9Handler)) return 9;
  59. if (m_axisHandler.GetType() == typeof(Axis663Handler)) return 663;
  60. return 0;
  61. }
  62. }
  63. private AxisBaseHandler m_axisHandler;
  64. //陀螺仪校准进度记录
  65. [NonSerialized] public int gyrCalibrateCompleteCount = 0;
  66. [NonSerialized] public int gyrCalibrateTotalCount = 2000;
  67. public static AimHandler ins;
  68. public bool bInitOne = false;
  69. void Start()
  70. {
  71. ins = this;
  72. BluetoothDispatcher.aim = OnDataReceived;
  73. // m_axisHandler = new Axis9NopackHandler(this); //九轴旧
  74. m_axisHandler = new Axis9Handler(this); //九轴新
  75. // m_axisHandler = new Axis663Handler(this); //双陀螺仪
  76. m_axisHandler.Init();
  77. // StartCoroutine(TestRecord());
  78. }
  79. public void onClearAimDeviceInfosNew()
  80. {
  81. PlayerPrefs.DeleteKey("aim-device-info-" + LoginMgr.myUserInfo.id);
  82. aimDeviceInfos.arry.Clear();
  83. }
  84. public void OnGetAimDeviceInfos() {
  85. string deviceInfo = PlayerPrefs.GetString("aim-device-info-" + LoginMgr.myUserInfo.id, "");
  86. Debug.Log("get deviceSelectIndex:" + deviceInfo);
  87. if (deviceInfo != "")
  88. {
  89. aimDeviceInfos = JsonUtility.FromJson<AimDeviceInfos>(deviceInfo);//这里的类是依据最外层{}决定的
  90. }
  91. aimDeviceInfoChangeEvent?.Invoke();
  92. }
  93. public void OnSaveAimDeviceInfos()
  94. {
  95. aimDeviceInfoChangeEvent?.Invoke();
  96. PlayerPrefs.SetString("aim-device-info-" + LoginMgr.myUserInfo.id, JsonUtility.ToJson(aimDeviceInfos));
  97. }
  98. //创建一个选择值
  99. public void onCreateTempAimDeviceInfo() {
  100. tempAimDeviceInfo = new AimDeviceInfo(deviceSelectIndex);
  101. Debug.Log("onCreateTempAimDeviceInfo deviceSelectIndex:" + deviceSelectIndex);
  102. }
  103. //是否存在AimDeviceInfo,存在更新,不存在创建;
  104. public void onCreateAimDeviceInfoById()
  105. {
  106. OnGetAimDeviceInfos();
  107. //deviceIndex 区分 1p 还是 2p
  108. bool bCanAdd = true;
  109. foreach (AimDeviceInfo p in aimDeviceInfos.arry)
  110. {
  111. if (deviceSelectIndex == p.id)
  112. {
  113. aimDeviceInfo = p;
  114. bCanAdd = false;
  115. }
  116. //Debug.Log("33deviceSelectIndex:" + deviceSelectIndex + ",bCanAdd:" + bCanAdd+ " , id:" + p.id +" , type:"+ p.type);
  117. }
  118. if (bCanAdd)
  119. {
  120. Debug.Log("add deviceSelectIndex:" + deviceSelectIndex);
  121. aimDeviceInfo = new AimDeviceInfo(deviceSelectIndex);
  122. aimDeviceInfos.arry.Add(aimDeviceInfo);
  123. }
  124. OnSaveAimDeviceInfos();
  125. }
  126. public void SetAimDeviceSelectIndex(int selectIndex) {
  127. if (selectIndex < 0) {
  128. Debug.LogWarning("selectIndex不能小于0:"+ selectIndex);
  129. return;
  130. }
  131. deviceSelectIndex = selectIndex;
  132. Debug.Log("SetAimDeviceSelectIndex :" + selectIndex);
  133. }
  134. public void SetTempAimDeviceType(AimDeviceType _aimDeviceType)
  135. {
  136. if (tempAimDeviceInfo == null) return;
  137. tempAimDeviceInfo.type = (int)_aimDeviceType;
  138. }
  139. public void SetAimDeviceType(AimDeviceType _aimDeviceType)
  140. {
  141. if (aimDeviceInfo == null) return;
  142. aimDeviceInfo.type = (int)_aimDeviceType;
  143. _AimDeviceInfosUpdate();
  144. OnSaveAimDeviceInfos();
  145. }
  146. public void SetAimDeviceType(int _aimDeviceType)
  147. {
  148. if (aimDeviceInfo == null) return;
  149. aimDeviceInfo.type = _aimDeviceType;
  150. _AimDeviceInfosUpdate();
  151. OnSaveAimDeviceInfos();
  152. }
  153. //APP连接需进行MAC地址的比对。
  154. //只有再引导初始化页面才保存连接使用的mac地址。
  155. public void SetAimDeviceMac(string _mac) {
  156. if (aimDeviceInfo == null) return;
  157. aimDeviceInfo.setInitMac(_mac);
  158. _AimDeviceInfosUpdate();
  159. OnSaveAimDeviceInfos();
  160. }
  161. //重置mac存储信息
  162. public void ResetAimDeviceMac() {
  163. if (aimDeviceInfo == null) return;
  164. aimDeviceInfo.resetInitMac();
  165. _AimDeviceInfosUpdate();
  166. OnSaveAimDeviceInfos();
  167. }
  168. void _AimDeviceInfosUpdate() {
  169. for (int i = 0; i < aimDeviceInfos.arry.Count; i++)
  170. {
  171. if (aimDeviceInfo.id == aimDeviceInfos.arry[i].id)
  172. {
  173. aimDeviceInfos.arry[i] = aimDeviceInfo;
  174. }
  175. }
  176. }
  177. #region 根据设备1p或者2p 获取HOUYIPRO的状态
  178. public bool isHOUYIPRO(BluetoothPlayer bluetoothPlayer)
  179. {
  180. bool _isHOUYIPRO = false;
  181. foreach (AimDeviceInfo p in AimHandler.ins.aimDeviceInfos.arry)
  182. {
  183. if ((int)bluetoothPlayer == p.id && p.type == (int)AimDeviceType.HOUYIPRO)
  184. {
  185. _isHOUYIPRO = true;
  186. }
  187. }
  188. return _isHOUYIPRO;
  189. }
  190. #endregion
  191. public void ReinitAxisHandler()
  192. {
  193. Debug.Log("ReinitAxisHandler");
  194. m_axisHandler.Init();
  195. }
  196. // System.Collections.IEnumerator TestRecord() {
  197. // while (LoginMgr.myUserInfo.id == 0) yield return null;
  198. // UserComp.Instance.saveMac();
  199. // }
  200. [NonSerialized] private Quaternion newRotation = Quaternion.identity;
  201. public void SetNewRotation(Quaternion quat) {
  202. this.newRotation = quat;
  203. }
  204. public void SetNewRotation(o0.Geometry.Quaternion o0Quat) {
  205. Quaternion quat = o0.Bow.Extension.ToUnityQuaternion(o0Quat);
  206. if (float.IsNaN(quat.x) || float.IsNaN(quat.y) || float.IsNaN(quat.z) || float.IsNaN(quat.w)) {
  207. Debug.LogError($"九轴Rotation存在Nan值,double:{o0Quat.ToString()},float:{quat.ToString()}");
  208. return;
  209. }
  210. if (float.IsInfinity(quat.x) || float.IsInfinity(quat.y) || float.IsInfinity(quat.z) || float.IsInfinity(quat.w)) {
  211. Debug.LogError($"九轴Rotation存在Infinity值,double:{o0Quat.ToString()},float:{quat.ToString()}");
  212. return;
  213. }
  214. this.newRotation = quat;
  215. }
  216. [NonSerialized] public bool lerpForRotation = true;
  217. [NonSerialized] public float lerpTimeRate = 7;
  218. public void Update()
  219. {
  220. //&& !InfraredDemo.running
  221. if (m_controlObj && !m_ban9AxisCalculate && bRuning9Axis())
  222. {
  223. if (lerpForRotation)
  224. m_controlObj.localRotation = Quaternion.Lerp(m_controlObj.localRotation, newRotation, Time.deltaTime * lerpTimeRate);
  225. else
  226. m_controlObj.localRotation = newRotation;
  227. }
  228. if (IsMagCompleted())
  229. {
  230. if (!m_magCompleted)
  231. {
  232. StartCoroutine(SaveMag());
  233. PopupMgr.ins.ShowTipTop(TextAutoLanguage2.GetTextByKey("tip_mag-calibrate_success"));
  234. }
  235. m_magCompleted = true;
  236. } else {
  237. m_magCompleted = false;
  238. }
  239. if (Input.GetKeyDown(KeyCode.Space))
  240. {
  241. AutoResetView.DoIdentity();
  242. }
  243. }
  244. public void OnDataReceived(byte[] bytes)
  245. {
  246. if (bytes.Length != 27 && bytes.Length != 39)
  247. {
  248. if (bytes.Length == 2) {
  249. if (bytes[0] == 0x66 && bytes[1] == 0x31) {
  250. if (bInitOne)
  251. {
  252. bInitOne = false;
  253. if (aimDeviceInfo.type == (int)AimDeviceType.NONE ||
  254. aimDeviceInfo.type == (int)AimDeviceType.HOUYI ||
  255. aimDeviceInfo.type == (int)AimDeviceType.HOUYI2 ||
  256. aimDeviceInfo.type == (int)AimDeviceType.ARTEMIS)
  257. {
  258. AutoResetView.DoIdentity();
  259. }
  260. else {
  261. //准心开关
  262. CrossBtnEvent();
  263. }
  264. }
  265. else {
  266. if (SB_EventSystem.ins && SB_EventSystem.ins.simulateMouseIsAwaked)
  267. {
  268. //视角回正
  269. DoIdentity();
  270. //鼠标居中自然会居中
  271. }
  272. else
  273. {
  274. if (aimDeviceInfo.type == (int)AimDeviceType.NONE ||
  275. aimDeviceInfo.type == (int)AimDeviceType.HOUYI ||
  276. aimDeviceInfo.type == (int)AimDeviceType.HOUYI2 ||
  277. aimDeviceInfo.type == (int)AimDeviceType.ARTEMIS)
  278. {
  279. AutoResetView.DoIdentity();
  280. }
  281. else
  282. {
  283. //准心开关
  284. CrossBtnEvent();
  285. }
  286. }
  287. }
  288. } else if (bytes[0] == 0x66 && bytes[1] == 0x32) {
  289. if (SB_EventSystem.ins) {
  290. // if (SB_EventSystem.ins && !CommonConfig.SpecialVersion1) {
  291. //唤起/隐藏虚拟鼠标
  292. SB_EventSystem.ins.AwakenSimulateMouse();
  293. }
  294. } else if (bytes[1] == 10) {
  295. //显示电量
  296. DeviceBatteryView.ins.RenderBattery(1, bytes[0]);
  297. //DeviceView.ins.RenderBattery(1, bytes[0]);
  298. }
  299. } else if (bytes[0] == 0x5b) {
  300. //红外射击检测
  301. ShootCheck.ins.ShootByInfrared(bytes);
  302. } else if (bytes[0] == 0x5a)
  303. {
  304. //握手成功响应
  305. if (bytes[1] == 0x00 && bytes[2] == 0x00 && bytes[3] == 0x00 && bytes[4] == 0x00)
  306. {
  307. Debug.Log("设备握手连接成功!");
  308. }
  309. else {
  310. //手枪应答
  311. //Debug.Log("瞄准模块数据长度" + bytes.Length);
  312. byte[] response = BluetoothDecryptor.GetResponse(bytes);
  313. BluetoothAim.ins.WriteByteData(response);
  314. }
  315. }
  316. else if (bytes[0] == 0x5C)
  317. {
  318. //00 弹夹分离,01 上弹夹
  319. ShootCheck.ins.UpdateTheMagazine(bytes);
  320. }
  321. return;
  322. }
  323. //if (InfraredDemo.running)
  324. //{
  325. // BluetoothAim.ins.WriteData("4"); //关闭九轴
  326. // return;
  327. //}
  328. if (!bRuning9Axis())
  329. {
  330. return;
  331. }
  332. m_axisHandler.Update(bytes);
  333. if (BowQuatDebug.ins) BowQuatDebug.ins.ShowModuleQuat(newRotation.eulerAngles);
  334. if (SB_EventSystem.ins && SB_EventSystem.ins.simulateMouseIsAwaked) SB_EventSystem.ins.MoveSimulateMouse(newRotation);
  335. }
  336. public byte[] InsertByteAtBeginning(byte[] originalArray, byte newByte)
  337. {
  338. byte[] newArray = new byte[originalArray.Length + 1];
  339. newArray[0] = newByte;
  340. Array.Copy(originalArray, 0, newArray, 1, originalArray.Length);
  341. return newArray;
  342. }
  343. private bool m_magCompleted;
  344. public void CorrectMagCompleted(bool value) { m_magCompleted = value; }
  345. private bool m_ban9AxisCalculate = false;
  346. public void Ban9AxisCalculate(bool ban)
  347. {
  348. // m_ban9AxisCalculate = ban;
  349. // if (!ban)
  350. // {
  351. // SetMsOldDefault();
  352. // if (m_controlObj) m_controlObj.localRotation = newRotation;
  353. // }
  354. }
  355. public void SetMsOldDefault()
  356. {
  357. if (m_axisHandler.GetType() == typeof(Axis9NopackHandler))
  358. (m_axisHandler as Axis9NopackHandler).msOld = default;
  359. }
  360. public void DoIdentity()
  361. {
  362. //if (InfraredDemo.running) return;
  363. m_axisHandler.DoIdentity();
  364. if (!bRuning9Axis()) return;
  365. if (m_controlObj) m_controlObj.localRotation = newRotation;
  366. }
  367. public void NotifyAxisOnShot() { m_axisHandler.NotifyAxisOnShot(); }
  368. public void CalibrateGyr(bool calibration) { m_axisHandler.CalibrateGyr(calibration); }
  369. public void InitGyr(string record) { m_axisHandler.InitGyr(record); }
  370. public void InitMag(string record) { m_axisHandler.InitMag(record); }
  371. public void ResetGyr() { m_axisHandler.ResetGyr(); }
  372. public void ResetMag() { m_axisHandler.ResetMag(); }
  373. public void ApplyImpreciseMag() { m_axisHandler.ApplyImpreciseMag(); }
  374. public bool IsGyrCompleted() { return m_axisHandler.IsGyrCompleted(); }
  375. public bool IsMagCompleted() { return m_axisHandler.IsMagCompleted(); }
  376. public IEnumerator SaveGyr() { return m_axisHandler.SaveGyr(); }
  377. public IEnumerator SaveMag() { return m_axisHandler.SaveMag(); }
  378. public void ResumeCalibrateRecord(string record) { m_axisHandler.ResumeCalibrateRecord(record); }
  379. #region 获取一个连接的设备下,对应的 Archery 是运行9轴的代码处理位置信息判断
  380. public bool bRuning9Axis() {
  381. //连接的设备下,对应的 Archery 是运行9轴的代码处理位置信息判断
  382. //弓箭类型,但是不是HOUYI Pro 情况下。运行9轴代码
  383. bool bRuning = GlobalData.MyDeviceMode == DeviceMode.Archery && !BluetoothAim.ins.isMainConnectToHOUYIPRO();
  384. return bRuning;
  385. }
  386. #endregion
  387. /// <summary>
  388. /// 操作准心开关事件
  389. /// </summary>
  390. private void CrossBtnEvent()
  391. {
  392. //准心开关
  393. if (GameAssistUI.ins)
  394. {
  395. //显示控制准心按钮
  396. Button crossHairBtn = GameAssistUI.ins.transform.Find("Button5").GetComponent<Button>();
  397. // 检查是否有注册的监听器
  398. if (crossHairBtn.onClick.GetPersistentEventCount() > 0)
  399. {
  400. crossHairBtn.onClick.Invoke();
  401. }
  402. }
  403. else if (DuckHunter.GameUI.Instance)
  404. {
  405. //显示控制准心按钮
  406. Button crossHairBtn = DuckHunter.GameUI.Instance.transform.Find("BtnCrosshair").GetComponent<Button>();
  407. // 检查是否有注册的监听器
  408. if (crossHairBtn.onClick.GetPersistentEventCount() > 0)
  409. {
  410. crossHairBtn.onClick.Invoke();
  411. }
  412. }
  413. else
  414. {
  415. //水果
  416. Button crossHairBtn = GameObject.Find("PermanentCanvas/CrossHair_Btn").GetComponent<Button>();
  417. // 检查是否有注册的监听器
  418. if (crossHairBtn.onClick.GetPersistentEventCount() > 0)
  419. {
  420. crossHairBtn.onClick.Invoke();
  421. }
  422. }
  423. }
  424. }