ShootCheck.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using UnityEngine.UI;
  6. using ArduinoBluetoothAPI;
  7. using DG.Tweening;
  8. using UnityEngine.SceneManagement;
  9. using System.Linq;
  10. using BestHTTP.WebSocket;
  11. using SmartBowSDK;
  12. /* 射箭检测 */
  13. public class ShootCheck : MonoBehaviour
  14. {
  15. [SerializeField] Text text;
  16. public float shootSpeed;
  17. public static ShootCheck ins;
  18. void Awake()
  19. {
  20. ins = this;
  21. }
  22. [SerializeField] InputField ArmBowInputField = default;
  23. public void SetShootBackTime()
  24. {
  25. ArmBow.ins.shootBackTime = int.Parse(ArmBowInputField.text);
  26. }
  27. [NonSerialized] public byte byteTime1;
  28. [NonSerialized] public byte byteTime2;
  29. //目前只处理m4
  30. private int _lastHandledId = -1;
  31. private float _lastHandledTime = 0f;
  32. private const float duplicateIgnoreWindow = 0.1f; // 可调:忽略窗口(单位秒)
  33. /**通过红外线数据进行射击 */
  34. public void ShootByInfrared(byte[] bytes) {
  35. int id = bytes[1]; //序号
  36. float now = Time.time;
  37. // 判断是否是重复射击
  38. if (id == _lastHandledId && (now - _lastHandledTime) < duplicateIgnoreWindow)
  39. {
  40. // 相同序号 + 窗口时间内,不处理
  41. return;
  42. }
  43. // 记录本次处理状态
  44. _lastHandledId = id;
  45. _lastHandledTime = now;
  46. byteTime1 = bytes[2];
  47. byteTime1 = bytes[3];
  48. float time1 = bytes[2] * 0.1f; //时区1耗时
  49. float time2 = bytes[3] * 0.1f; //时区2耗时
  50. float totalTime = time1 + time2;
  51. // if (totalTime <= 0) {
  52. // totalTime = 0.3f;
  53. // }
  54. //校验和
  55. int sumCheck = bytes[0] + bytes[1] + bytes[2] + bytes[3];
  56. sumCheck &= 0xff;
  57. //校验和比较结果
  58. bool sumCheckRes = sumCheck == bytes[4];
  59. //弓轨速度
  60. float speed = 0.05f / (totalTime / 1000f);
  61. //通过动能定理求箭的速度(实体箭质量*实体箭速度^2=游戏中箭的质量*游戏中箭的速度^2)
  62. shootSpeed = Mathf.Sqrt(speed * speed * CommonConfig.arrowWeight / UserSettings.ins.actualArrowWeight);
  63. //打印
  64. string logTxt = $"序号{id},时区1:{time1}毫秒,时区2:{time2}毫秒,校验:{sumCheckRes},弓轨速度:{speed}m/s,箭的速度:{shootSpeed}m/s";
  65. if (DebugForDevice.ins) DebugForDevice.ins.LogInfrared(logTxt);
  66. //Debug.Log(logTxt);
  67. if (SB_EventSystem.ins && SB_EventSystem.ins.simulateMouseIsAwaked) {
  68. SB_EventSystem.ins.ClickMouse();
  69. } else if (ArmBow.ins) {
  70. ArmBow.ins.ADS_fire(true);
  71. } else if (DuckHunter.SmartBowController.Instance) {
  72. //野鸭射击
  73. DuckHunter.SmartBowController.Instance.OnShooting(shootSpeed);
  74. } else if (WildAttack.SmartBowController.Instance)
  75. {
  76. //荒野射击
  77. WildAttack.SmartBowController.Instance.OnShooting(shootSpeed);
  78. } else if (GameController.ins && GameController.ins.GetArmBowDoublePlayer(PlayerType.FirstPlayer) != null) {
  79. //本地双人模式下处理1p,2P 在 BluetoothAim 类处理
  80. GameController.ins.GetArmBowDoublePlayer(PlayerType.FirstPlayer).ADS_fire(true, shootSpeed);
  81. } else if (GeneratingTarget.gm != null) {
  82. //移动目标
  83. GeneratingTarget.gm.Shooting(true);
  84. }
  85. else {
  86. OnGameShoot?.Invoke(shootSpeed);
  87. }
  88. }
  89. public Action<float> OnGameShoot;
  90. //分离弹夹事件
  91. public Action OnGameUpdateTheMagazine;
  92. //弹夹状态
  93. public BluetoothDeviceStatus bluetoothDeviceStatus = BluetoothDeviceStatus.MagazineLoading;
  94. /// <summary>
  95. /// 0x00 - 弹夹分离 0x01 - 弹夹上膛
  96. /// </summary>
  97. /// <param name="bytes"></param>
  98. public void UpdateTheMagazine(byte[] bytes) {
  99. BluetoothDeviceType temp = bluetoothDeviceType != BluetoothDeviceType.NONE ?
  100. bluetoothDeviceType : BluetoothDeviceType.Pistol1;
  101. if (bytes[1] == 0x00) {
  102. //添加一个同步状态
  103. BluetoothAim.ins.InvokeOnBleDevice(temp, BluetoothDeviceStatus.MagazineSeparation);
  104. Debug.Log("弹夹分离:" + BitConverter.ToString(bytes));
  105. bluetoothDeviceStatus = BluetoothDeviceStatus.MagazineSeparation;
  106. if (GeneratingTarget.gm) {
  107. //Hyperspace
  108. GeneratingTarget.gm.OnSeparation();
  109. }
  110. } else if ( bytes[1] == 0x01){
  111. //添加一个同步状态
  112. BluetoothAim.ins.InvokeOnBleDevice(temp, BluetoothDeviceStatus.MagazineLoading);
  113. //播放上弹夹时候的声音
  114. AudioMgr.ins.PlayBeLoaded();
  115. Debug.Log("弹夹上膛:" + BitConverter.ToString(bytes));
  116. bluetoothDeviceStatus = BluetoothDeviceStatus.MagazineLoading;
  117. if (Billboard.ins)
  118. {
  119. Billboard.ins.bulletManager.ResetBullets(); //game
  120. }
  121. else if (GeneratingTarget.gm)
  122. { //Hyperspace
  123. GeneratingTarget.gm.OnLoading();
  124. }
  125. else
  126. {
  127. OnGameUpdateTheMagazine?.Invoke(); //水果在gamingmanager
  128. }
  129. }
  130. }
  131. //记录当前的蓝牙设备信息
  132. private BluetoothDeviceType bluetoothDeviceType = BluetoothDeviceType.NONE;
  133. //记录连接的设备系统信息
  134. private ConnectPlatform connectPlatform = ConnectPlatform.NONE;
  135. /// <summary>
  136. /// 0x00 未上膛,0x01 已上膛
  137. /// </summary>
  138. /// <param name="bytes"></param>
  139. public void UpdateChamberState(byte[] bytes)
  140. {
  141. Debug.Log("操作上膛状态:" + BitConverter.ToString(bytes));
  142. BluetoothDeviceType temp = bluetoothDeviceType != BluetoothDeviceType.NONE ?
  143. bluetoothDeviceType : BluetoothDeviceType.Pistol1;
  144. if (bytes[1] == 0x00)
  145. {
  146. BluetoothAim.ins.InvokeOnBleDevice(temp, BluetoothDeviceStatus.ChamberEmpty);
  147. }
  148. else if (bytes[1] == 0x01)
  149. {
  150. BluetoothAim.ins.InvokeOnBleDevice(temp, BluetoothDeviceStatus.Chambered);
  151. }
  152. }
  153. /// <summary>
  154. /// 记录当前获得的设备连接数据
  155. /// </summary>
  156. /// <param name="bytes"></param>
  157. public void UpdateDeviceAndSysInfo(byte[] bytes)
  158. {
  159. //Debug.Log("接收到系统数据:" + System.BitConverter.ToString(bytes));
  160. //设备类型
  161. switch (bytes[1])
  162. {
  163. case 0x01:
  164. bluetoothDeviceType = BluetoothDeviceType.HOUYIPro;
  165. break;
  166. case 0x02:
  167. bluetoothDeviceType = BluetoothDeviceType.ARTEMISPro;
  168. break;
  169. case 0x03:
  170. bluetoothDeviceType = BluetoothDeviceType.PistolM9;
  171. break;
  172. case 0x04:
  173. bluetoothDeviceType = BluetoothDeviceType.APOLLO;
  174. break;
  175. case 0x05:
  176. bluetoothDeviceType = BluetoothDeviceType.PistolM17;
  177. break;
  178. case 0x06:
  179. bluetoothDeviceType = BluetoothDeviceType.RifleM416;
  180. break;
  181. }
  182. // 系统类型
  183. switch (bytes[2])
  184. {
  185. case 0x01:
  186. connectPlatform = ConnectPlatform.PHONE;
  187. break;
  188. case 0x02:
  189. connectPlatform = ConnectPlatform.PC;
  190. break;
  191. case 0x03:
  192. connectPlatform = ConnectPlatform.VR;
  193. break;
  194. }
  195. Debug.Log("设备类型:" + bluetoothDeviceType.ToString());
  196. Debug.Log("系统类型:" + connectPlatform.ToString());
  197. //初始化时候回调数据
  198. BluetoothAim.ins.InvokeOnDeviceAndSystemInfoEvent(connectPlatform, bluetoothDeviceType);
  199. }
  200. void Log(string text)
  201. {
  202. if (this.text)
  203. {
  204. this.text.text = text;
  205. } else {
  206. Debug.Log(text);
  207. }
  208. }
  209. }