ShootCheck.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. using System;
  2. using UnityEngine;
  3. using UnityEngine.UI;
  4. public class ShootCheck : MonoBehaviour
  5. {
  6. float[] accList = new float[30];
  7. int dataCount = 0;
  8. float gravity = 0;
  9. float maxAcc = 0;
  10. bool hasReachShootThreshold = false;
  11. bool locked = false;
  12. int hitCount = 0;
  13. [SerializeField] Text text;
  14. public float shootSpeed;
  15. public static ShootCheck ins;
  16. void Start()
  17. {
  18. ins = this;
  19. BluetoothDispatcher.shoot = OnDataReceived;
  20. }
  21. void OnDestroy()
  22. {
  23. ins = null;
  24. }
  25. float[] ays = new float[4];
  26. public void OnDataReceived(byte[] bytes) {
  27. ays[0] = ToAcceleratedSpeed(bytes[7], bytes[8]);
  28. ays[1] = ToAcceleratedSpeed(bytes[17], bytes[18]);
  29. ays[2] = ToAcceleratedSpeed(bytes[27], bytes[28]);
  30. ays[3] = ToAcceleratedSpeed(bytes[37], bytes[38]);
  31. foreach (float ay in ays)
  32. {
  33. try
  34. {
  35. if (ins.check(ay))
  36. {
  37. if (ArmBow.ins != null)
  38. {
  39. ArmBow.ins.ADS_fire();
  40. }
  41. }
  42. }
  43. catch (Exception e)
  44. {
  45. Debug.Log(e.Message);
  46. }
  47. }
  48. }
  49. float ToAcceleratedSpeed(byte b1, byte b2)
  50. {
  51. int value = TwoByteToInt(b1, b2);
  52. return (float)value / 32768 * 16;
  53. }
  54. int TwoByteToInt(byte b1, byte b2)
  55. {
  56. ushort twoByte = (ushort)(b1 * 256 + b2);
  57. short shortNum = (short)twoByte;
  58. return (int)shortNum;
  59. }
  60. int afterReachShootFrameCount = 0;
  61. int steadyFrameCount = 6;
  62. bool check(float acc)
  63. {
  64. DebugLine.show(acc);
  65. DebugLine.showSteady(gravity);
  66. for (int i = accList.Length - 1; i > 0; i--)
  67. {
  68. accList[i] = accList[i - 1];
  69. }
  70. accList[0] = acc;
  71. dataCount++;
  72. if (locked)
  73. {
  74. return false;
  75. }
  76. if (hasReachShootThreshold) {
  77. if (acc <= gravity) {
  78. hitCount++;
  79. shootSpeed = maxAcc - gravity;
  80. Log("第" + hitCount + "次识别射箭\n过滤正轴重力" + gravity.ToString("#0.000") + "后\n所得最大加速度峰值" + (maxAcc - gravity).ToString("#0.000") + "\n有效帧数" + afterReachShootFrameCount);
  81. maxAcc = 0;
  82. afterReachShootFrameCount = 0;
  83. hasReachShootThreshold = false;
  84. Dolock();
  85. Invoke("Unlock", 0.8f);
  86. return true;
  87. } else if (acc > maxAcc) {
  88. maxAcc = acc;
  89. }
  90. afterReachShootFrameCount++;
  91. if (afterReachShootFrameCount >= 20)
  92. {
  93. maxAcc = 0;
  94. afterReachShootFrameCount = 0;
  95. hasReachShootThreshold = false;
  96. Log("不符合短时间爆发加速");
  97. }
  98. return false;
  99. }
  100. if (dataCount > steadyFrameCount)
  101. {
  102. float totalAcc = 0;
  103. for (int i = 0; i < steadyFrameCount; i++)
  104. {
  105. totalAcc += accList[i];
  106. }
  107. float rangeAcc = totalAcc / steadyFrameCount;
  108. float squareAcc = 0;
  109. for (int i = 0; i < steadyFrameCount; i++)
  110. {
  111. squareAcc += (float) Mathf.Pow(accList[i] - rangeAcc, 2);
  112. }
  113. squareAcc /= steadyFrameCount;
  114. if (squareAcc < 0.00012)
  115. {
  116. gravity = Mathf.Clamp(rangeAcc, -0.981f, 0.981f);
  117. }
  118. if (acc - gravity > 3)
  119. {
  120. // for (int i = 1; i < dataCount && i < 15; i++)
  121. // {
  122. // if (accList[i] - gravity < - 1)
  123. // {
  124. // Dolock();
  125. // Invoke("Unlock", 0.2f);
  126. // return false;
  127. // }
  128. // }
  129. hasReachShootThreshold = true;
  130. maxAcc = acc;
  131. }
  132. }
  133. return false;
  134. }
  135. void Dolock()
  136. {
  137. this.locked = true;
  138. }
  139. void Unlock()
  140. {
  141. this.locked = false;
  142. }
  143. void Log(string text)
  144. {
  145. if (this.text != null)
  146. {
  147. this.text.text = text;
  148. } else {
  149. Debug.Log(text);
  150. }
  151. }
  152. }