using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using ArduinoBluetoothAPI; using DG.Tweening; using UnityEngine.SceneManagement; using System.Linq; using BestHTTP.WebSocket; public class ShootCheck : MonoBehaviour { [SerializeField] Text text; CMD cmd = new CMD(); bool locked = false; float maxAcc = 0; Queue keyAccList = new Queue(); Queue keyTimeList = new Queue(); public float shootSpeed; public static ShootCheck ins; [SerializeField] InputField ipInputField = default; WebSocket webSocket; void Start() { ins = this; BluetoothDispatcher.shoot = OnDataReceived; } //用户输入时的变化 public void ChangedValue(string value) { ipInputField.ActivateInputField(); Debug.Log("输入了"+value); } public void EndValue(string value) { Debug.Log("最终内容"+value); } //socket public void StartSocket() { //socket string ipStr = ipInputField.text;//ipInputField.GetComponentInChildren(); string serverIP = ipStr; // serverIP = "172.16.20.57"; string address = "ws://" + serverIP + ":8088/Ble/"; webSocket = new WebSocket(new Uri(address)); #if !UNITY_WEBGL webSocket.StartPingThread = true; #endif // Subscribe to the WS events webSocket.OnOpen += OnOpen; webSocket.OnMessage += OnMessageRecv; webSocket.OnBinary += OnBinaryRecv; webSocket.OnClosed += OnClosed; webSocket.OnError += OnError; // Debug.Log("OnOpen: "); // Start connecting to the server webSocket.Open(); } public void Destroy() { if (webSocket != null) { webSocket.Close(); webSocket = null; } } void OnOpen(WebSocket ws) { Debug.Log("OnOpen: "); webSocket.Send("unity"); } void OnMessageRecv(WebSocket ws, string message) { Debug.LogFormat("OnMessageRecv: msg={0}", message); } void OnBinaryRecv(WebSocket ws, byte[] data) { Debug.LogFormat("OnBinaryRecv: len={0}", data.Length); } void OnClosed(WebSocket ws, UInt16 code, string message) { Debug.LogFormat("OnClosed: code={0}, msg={1}", code, message); webSocket = null; } void OnError(WebSocket ws, Exception ex) { string errorMsg = string.Empty; #if !UNITY_WEBGL || UNITY_EDITOR if (ws.InternalRequest.Response != null) { errorMsg = string.Format("Status Code from Server: {0} and Message: {1}", ws.InternalRequest.Response.StatusCode, ws.InternalRequest.Response.Message); } #endif Debug.LogFormat("OnError: error occured: {0}\n", (ex != null ? ex.Message : "Unknown Error " + errorMsg)); webSocket = null; } //socket [SerializeField] InputField ArmBowInputField = default; public void SetShootBackTime() { ArmBow.ins.shootBackTime=int.Parse(ArmBowInputField.text); } public void OnBluetoothReady(BluetoothShoot bluetoothShoot) { bluetoothShoot.WriteData(JsonUtility.ToJson(cmd).Replace("\"", "")); Sequence sequence = DOTween.Sequence(); sequence.PrependInterval(1).AppendCallback(delegate() { canAdjustNormalOrHightMode = true; AdjustNormalOrHightMode(); }); sequence.SetUpdate(true); } //===普通模式和高速模式的切换=== public bool canAdjustNormalOrHightMode = false; public int transportMode = 0; public void AdjustNormalOrHightMode() { if (!canAdjustNormalOrHightMode) return; try { // string sceneName = SceneManager.GetActiveScene().name; // if (sceneName == "Game") // { // transportMode = 1; // BluetoothShoot.ins.WriteData("HA"); // } // else // { // transportMode = 0; // BluetoothShoot.ins.WriteData("NA"); // } transportMode = 0; BluetoothShoot.ins.WriteData("NA"); } catch (Exception) {} } public void OnDataReceived(byte[] bytes) { if (bytes.Length == 2) { DeviceBatteryView.ins.RenderBattery(2, bytes[0]); return; } string str1 = "byte="; if (webSocket != null) { for (int i = 0; i < bytes.Length-1; i++) { str1+= bytes[i]; } // webSocket.Send(str2); } string str2 = ""; if (transportMode == 0) { for (int i = 0; i < (bytes.Length -2 ) /6; i++) { float acc = ToAcceleratedSpeed(bytes[i * 6 + 5], bytes[i * 6 + 6]); string t = "(采样时间:"+(int)bytes[i * 6 + 3] + "分"+ (int)bytes[i * 6 + 4]+"秒"+ TwoByteToInt(bytes[i * 6 + 1], bytes[i * 6 + 2])+"毫秒)" ; str2 += "加速度:"+ acc + t + "\n"; if (ins.check(0, acc, 0, t) && ArmBow.ins) { ArmBow.ins.ADS_fire(); } } } else if (transportMode == 1) { for (int i = 0; i < bytes.Length / 11; i++) { float ax = ToAcceleratedSpeed(bytes[i * 11 + 5], bytes[i * 11 + 6]); float ay = ToAcceleratedSpeed(bytes[i * 11 + 7], bytes[i * 11 + 8]); float az = ToAcceleratedSpeed(bytes[i * 11 + 9], bytes[i * 11 + 10]); string t = "(采样时间:"+(int)bytes[i * 11 + 3] + "分"+ (int)bytes[i * 11 + 4]+"秒"+ TwoByteToInt(bytes[i * 11 + 1], bytes[i * 11 + 2])+"毫秒)" ; str2 += "加速度:"+ay+t+"\n"; if (ins.check(ax, ay, az, t) && ArmBow.ins) { ArmBow.ins.ADS_fire(); } } } if (webSocket != null) { string str3 = str1+"\n"+str2; webSocket.Send(str3); } } float ToAcceleratedSpeed(byte b1, byte b2) { int value = TwoByteToInt(b1, b2); return (float)value / 32768 * LoginMgr.myUserInfo.arrowAccValue; } int TwoByteToInt(byte b1, byte b2) { ushort twoByte = (ushort)(b1 * 256 + b2); short shortNum = (short)twoByte; return (int)shortNum; } bool check(float ax, float ay, float az, string t) { float acc = ay; DebugLine.show(acc); //这个不需要注释,静态函数内置判断 if (locked) { return false; } if (acc > cmd.getAcc()) { if (acc > maxAcc) { maxAcc = acc; } if (acc > 15.9f && LoginMgr.myUserInfo.arrowAccValue == 16) { double p1 = -1.56729339506415; double p2 = 0.0397744840580165; double p3 = 4.73453844008481; float x = (keyAccList.Count + 1) * 2; //单位毫秒 double y = 1.0 / (p1+p2*Mathf.Pow(x, 0.5f)*Mathf.Log(x)+p3/Mathf.Pow(x, 0.5f)); acc = (float) y; } Vector3 keyAcc = new Vector3(ax, ay, az); keyAccList.Enqueue(keyAcc); keyTimeList.Enqueue(t); return false; } else if (acc < cmd.getAcc() && maxAcc != 0) { //积分求初速度 shootSpeed = 0; float lasKeytAcc = 0; int keyAccIndex = 0; float timeInterval = 0.002f; float totalAx = 0; float totalAy = 0; float totalAz = 0; foreach (var keyAcc in keyAccList) { totalAx += Mathf.Abs(keyAcc.x); totalAy += Mathf.Abs(keyAcc.y); totalAz += Mathf.Abs(keyAcc.z); if (keyAccIndex > 0) { shootSpeed += keyAcc.y * timeInterval; shootSpeed -= (keyAcc.y - lasKeytAcc) * timeInterval / 2; } else if (keyAccIndex == 0 && keyAccList.Count == 1) { shootSpeed = keyAcc.y * timeInterval; } lasKeytAcc = keyAcc.y; keyAccIndex++; } //是不是合法射出 bool isLegalShoot = totalAy > totalAx && totalAy > totalAz; if (isLegalShoot) { //加速度acc的单位是g,最后需要乘上 shootSpeed *= 9.80665f; //积分出来的值还是太小,需要一个倍率 shootSpeed *= 20; shootSpeed = 60; string strShootSpeed = "初速度: " + shootSpeed + " 帧数: " + keyAccList.Count + "\n"; string str1 = strShootSpeed + "/////////检测到射出的数据////////////:\n"; for (int i=0;i