using System; using UnityEngine; using UnityEngine.UI; public class ShootCheck : MonoBehaviour { float[] accList = new float[30]; int dataCount = 0; float gravity = 0; float maxAcc = 0; bool hasReachShootThreshold = false; bool locked = false; int hitCount = 0; [SerializeField] Text text; public float shootSpeed; public static ShootCheck ins; void Start() { ins = this; // BluetoothClient.onDataReceived = OnDataReceived; } void OnDestroy() { ins = null; } float[] ays = new float[4]; public void OnDataReceived(byte[] bytes) { ays[0] = ToAcceleratedSpeed(bytes[7], bytes[8]); ays[1] = ToAcceleratedSpeed(bytes[17], bytes[18]); ays[2] = ToAcceleratedSpeed(bytes[27], bytes[28]); ays[3] = ToAcceleratedSpeed(bytes[37], bytes[38]); foreach (float ay in ays) { try { if (ins.check(ay)) { if (ArmBow.ins != null) { ArmBow.ins.ADS_fire(); } } } catch (Exception e) { Debug.Log(e.Message); } } } float ToAcceleratedSpeed(byte b1, byte b2) { int value = TwoByteToInt(b1, b2); return (float)value / 32768 * 16; } int TwoByteToInt(byte b1, byte b2) { ushort twoByte = (ushort)(b1 * 256 + b2); short shortNum = (short)twoByte; return (int)shortNum; } int afterReachShootFrameCount = 0; int steadyFrameCount = 6; bool check(float acc) { DebugLine.show(acc); DebugLine.showSteady(gravity); for (int i = accList.Length - 1; i > 0; i--) { accList[i] = accList[i - 1]; } accList[0] = acc; dataCount++; if (locked) { return false; } if (hasReachShootThreshold) { if (acc <= gravity) { hitCount++; shootSpeed = maxAcc - gravity; Log("第" + hitCount + "次识别射箭\n过滤正轴重力" + gravity.ToString("#0.000") + "后\n所得最大加速度峰值" + (maxAcc - gravity).ToString("#0.000") + "\n有效帧数" + afterReachShootFrameCount); maxAcc = 0; afterReachShootFrameCount = 0; hasReachShootThreshold = false; Dolock(); Invoke("Unlock", 0.8f); return true; } else if (acc > maxAcc) { maxAcc = acc; } afterReachShootFrameCount++; if (afterReachShootFrameCount >= 20) { maxAcc = 0; afterReachShootFrameCount = 0; hasReachShootThreshold = false; Log("不符合短时间爆发加速"); } return false; } if (dataCount > steadyFrameCount) { float totalAcc = 0; for (int i = 0; i < steadyFrameCount; i++) { totalAcc += accList[i]; } float rangeAcc = totalAcc / steadyFrameCount; float squareAcc = 0; for (int i = 0; i < steadyFrameCount; i++) { squareAcc += (float) Mathf.Pow(accList[i] - rangeAcc, 2); } squareAcc /= steadyFrameCount; if (squareAcc < 0.00012) { gravity = Mathf.Clamp(rangeAcc, -0.981f, 0.981f); } if (acc - gravity > 3) { // for (int i = 1; i < dataCount && i < 15; i++) // { // if (accList[i] - gravity < - 1) // { // Dolock(); // Invoke("Unlock", 0.2f); // return false; // } // } hasReachShootThreshold = true; maxAcc = acc; } } return false; } void Dolock() { this.locked = true; } void Unlock() { this.locked = false; } void Log(string text) { if (this.text != null) { this.text.text = text; } else { Debug.Log(text); } } }