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; public 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; public WebSocket webSocket; void Awake() { ins = this; } //用户输入时的变化 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"; if (serverIP.Length == 0) serverIP = "192.168.101.14"; 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) { // if (LoginMgr.myUserInfo.arrowAccValue == 16) // { // cmd.a = "y"; // } // else // { // cmd.a = "x"; // } // 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) { 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 / 6; i++) { float acc = ToAcceleratedSpeed(bytes[i * 6 + 4], bytes[i * 6 + 5]); string t = "(采样时间:"+(int)bytes[i * 6 + 0] + "分"+ (int)bytes[i * 6 + 1]+"秒"+ TwoByteToInt(bytes[i * 6 + 2], bytes[i * 6 + 3])+"毫秒)" ; str2 += "加速度:"+ acc + t + "\n"; if (ins.check(0, acc, 0, t) && ArmBow.ins) { ArmBow.ins.ADS_fire(true); } } } 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(true); } } } 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; return (float)value / 32768; } 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, acc, 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; string strShootSpeed = "弓轨速度: " + shootSpeed + " 帧数: " + keyAccList.Count + "\n"; // shootSpeed = Mathf.Sqrt(shootSpeed * shootSpeed * arrowWeight / LoginMgr.myUserInfo.actualArrowWeight); strShootSpeed += "箭的速度: " + shootSpeed + "\n"; string str1 = strShootSpeed + "/////////检测到射出的数据////////////:\n"; for (int i=0;i OnGameShoot; void Dolock() { locked = true; } void Unlock() { locked = false; } void Log(string text) { if (this.text) { this.text.text = text; } else { Debug.Log(text); } } } [Serializable] public class CMD { // public string ax = "y"; // public int a = 6000; // public int r = 2; public string a = "y"; public int a1 = 3; public int a2 = -3; public int r = 2; public float getAcc() { return a1; } }