using UnityEngine; namespace SmartBowSDK { /// /// 射箭检测器 /// public class ShootChecker_SDK : MonoBehaviour { public SmartBowHelper smartBowHelper; /// /// 游戏里箭的速度 /// public float gameArrowSpeed = 0; /// /// 游戏里箭的重量 /// public float gameArrowWeight = 20; /// /// 现实里箭的重量 /// public float solidArrowWeight = 75; /// /// 上一次的射击数据ID /// private int _lastShootID = -1; //记录当前的蓝牙设备信息 private BluetoothDeviceType bluetoothDeviceType = BluetoothDeviceType.NONE; //记录连接的设备系统信息 private ConnectPlatform connectPlatform = ConnectPlatform.NONE; /// /// 当收到红外数据时 /// /// public void OnInfraredDataReceived(byte[] bytes) { //序号 int id = bytes[1]; if (id == _lastShootID) return; //因为硬件为了避免丢包,会连续发几条相同射击通知过来 _lastShootID = id; //时区1耗时 float time1 = bytes[2] * 0.1f; //时区2耗时 float time2 = bytes[3] * 0.1f; //时区耗时总和 float totalTime = time1 + time2; //校验和 int sumCheck = (bytes[0] + bytes[1] + bytes[2] + bytes[3]) & 0xff; //校验和比较结果 bool sumCheckRes = sumCheck == bytes[4]; //实体箭速度 float solidArrowSpeed = 0.05f / (totalTime / 1000f); //通过动能定理求箭的速度(实体箭质量*实体箭速度^2=游戏中箭的质量*游戏中箭的速度^2) gameArrowSpeed = Mathf.Sqrt(solidArrowSpeed * solidArrowSpeed * solidArrowWeight / gameArrowWeight); //打印 string logInfo = $"序号{id},时区1:{time1}毫秒,时区2:{time2}毫秒,校验:{sumCheckRes},实体箭速度:{solidArrowSpeed}m/s,游戏箭速度:{gameArrowSpeed}m/s"; SmartBowLogger.Log(this, logInfo); //收到正确的射箭数据,就回复硬件,否则n毫秒后硬件会认为丢包而进行重传 if (sumCheckRes) smartBowHelper.bluetoothAim.ReplyInfraredShoot(); //通知九轴算法,因为射箭抖动会使算法计算的姿态角产生误差 smartBowHelper.aimHandler.NotifyAxisOnShot(); smartBowHelper.InvokeOnShooting(gameArrowSpeed); } /// /// 回去枪指令 /// /// public void ReplyGun(byte[] bytes) { byte[] response = BluetoothDecryptor.GetResponse(bytes); smartBowHelper.bluetoothAim.ReplyByte(response); } /// /// 枪的弹夹状态 /// 0x00 弹夹分离,0x01 上弹夹 /// /// public void UpdateTheMagazine(byte[] bytes) { SmartBowLogger.Log(this, "切换弹夹后:" + System.BitConverter.ToString(bytes)); BluetoothDeviceType temp = bluetoothDeviceType != BluetoothDeviceType.NONE ? bluetoothDeviceType : BluetoothDeviceType.Pistol1; if (bytes[1] == 0x00) { smartBowHelper.InvokeOnBleDevice(temp, BluetoothDeviceStatus.MagazineSeparation); } else if (bytes[1] == 0x01) { smartBowHelper.InvokeOnBleDevice(temp, BluetoothDeviceStatus.MagazineLoading); } } /// /// 0x00 未上膛,0x01 已上膛 /// /// public void UpdateChamberState(byte[] bytes) { SmartBowLogger.Log(this, "操作上膛状态:" + System.BitConverter.ToString(bytes)); BluetoothDeviceType temp = bluetoothDeviceType != BluetoothDeviceType.NONE ? bluetoothDeviceType : BluetoothDeviceType.Pistol1; if (bytes[1] == 0x00) { smartBowHelper.InvokeOnBleDevice(temp, BluetoothDeviceStatus.ChamberEmpty); } else if (bytes[1] == 0x01) { smartBowHelper.InvokeOnBleDevice(temp, BluetoothDeviceStatus.Chambered); } } /// /// 记录当前获得的设备连接数据 /// /// public void UpdateDeviceAndSysInfo(byte[] bytes) { //Debug.Log("接收到系统数据:" + System.BitConverter.ToString(bytes)); //设备类型 switch (bytes[1]) { case 0x01: bluetoothDeviceType = BluetoothDeviceType.HOUYIPro; break; case 0x02: bluetoothDeviceType = BluetoothDeviceType.ARTEMISPro; break; case 0x03: bluetoothDeviceType = BluetoothDeviceType.PistolM9; break; case 0x04: bluetoothDeviceType = BluetoothDeviceType.APOLLO; break; case 0x05: bluetoothDeviceType = BluetoothDeviceType.PistolM17; break; case 0x06: bluetoothDeviceType = BluetoothDeviceType.RifleM416; break; } // 系统类型 switch (bytes[2]) { case 0x01: connectPlatform = ConnectPlatform.PHONE; break; case 0x02: connectPlatform = ConnectPlatform.PC; break; case 0x03: connectPlatform = ConnectPlatform.VR; break; } SmartBowLogger.Log(this, "设备类型:" + bluetoothDeviceType.ToString()); SmartBowLogger.Log(this, "系统类型:" + connectPlatform.ToString()); //初始化时候回调数据 smartBowHelper.InvokeOnDeviceAndSystemInfoEvent(connectPlatform, bluetoothDeviceType); } } }