using ArduinoBluetoothAPI; using System; using UnityEngine; using System.Collections.Generic; using UnityEngine.UI; using DG.Tweening; /* 蓝牙瞄准模块 */ public class HRB_Bluetooth : MonoBehaviour { readonly string targetDeviceName = "Bbow_20210501"; string targetDeviceService { get { if (CommonConfig.devicePlan == 0 || CommonConfig.devicePlan == 3) { #if UNITY_ANDROID return "0000fff0"; #else return "fff0"; #endif } return "6e400001"; } } string targetDeviceCharacteristicWrite { get { if (CommonConfig.devicePlan == 0 || CommonConfig.devicePlan == 3) { #if UNITY_ANDROID return "0000fff2"; #else return "fff2"; #endif } return "6e400002"; } } string targetDeviceCharacteristicNotify { get { if (CommonConfig.devicePlan == 0 || CommonConfig.devicePlan == 3) { #if UNITY_ANDROID return "0000fff1"; #else return "fff1"; #endif } return "6e400003"; } } BluetoothHelper bluetoothHelper; BluetoothHelperCharacteristic characteristicWrite; BluetoothHelperService bluetoothService; string deviceName = ""; bool canConnect = true; [SerializeField] Text textUI; public BluetoothStatusEnum status = BluetoothStatusEnum.Connect; public Action onFindTargetDevice; void OnDestroy() { DisconnectBleHelper(); } private bool userDoConnect = false; private bool doConnect = false; public Func action_DoConnectInterceptor; public void DoConnect() { if (action_DoConnectInterceptor != null) { if (action_DoConnectInterceptor.Invoke()) return; } if (status == BluetoothStatusEnum.Connect) { userDoConnect = true; doConnect = true; SetStatus(BluetoothStatusEnum.Connecting); } else if (status == BluetoothStatusEnum.ConnectSuccess) { userDoConnect = false; doConnect = false; OnDisconnect(); DisconnectBleHelper(); } } void OnDisconnect() { canConnect = true; SetStatus(BluetoothStatusEnum.ConnectFail); BowCamera.isTouchMode = true; if (AimHandler.ins) AimHandler.ins.SetMsOldDefault(); } void Update() { if (userDoConnect && status == BluetoothStatusEnum.Connect) { DoConnect(); } if (doConnect) Connect(); } void SetStatus(BluetoothStatusEnum statusValue) { status = statusValue; if (status == BluetoothStatusEnum.ConnectFail) { Sequence sequence = DOTween.Sequence(); sequence.AppendInterval(2f); sequence.AppendCallback(delegate () { if (status == BluetoothStatusEnum.ConnectFail) { status = BluetoothStatusEnum.Connect; } }); sequence.SetUpdate(true); SimulateMouseController.ins?.SetBleConnected(false); } else if (status == BluetoothStatusEnum.ConnectSuccess) { SimulateMouseController.ins?.SetBleConnected(true); } } void DisconnectBleHelper() { if (bluetoothHelper != null) bluetoothHelper.Disconnect(); } void Connect() { if (BluetoothShoot.scanLock) { return; } if (!canConnect) { return; } doConnect = false; canConnect = false; SetStatus(BluetoothStatusEnum.Connecting); ConnectBleHelper(); } void ConnectBleHelper() { #if UNITY_ANDROID PopupMgr.ins.ClearAllTip(); if (BluetoothHelperAndroid.IsBluetoothEnabled() == false) { HandleConnectException(TextAutoLanguage2.GetTextByKey("ble-exception1")); return; } if (BluetoothHelperAndroid.RequestBluetoothPermissions(ConnectBleHelper, (permission) => { if (permission.Contains("LOCATION")) { HandleConnectException(TextAutoLanguage2.GetTextByKey("ble-exception2")); } else if (permission.Contains("BLUETOOTH")) { HandleConnectException(TextAutoLanguage2.GetTextByKey("ble-exception3")); } })) return; #endif try { BluetoothHelper.BLE = true; bluetoothHelper = BluetoothHelper.GetNewInstance(); bluetoothHelper.OnConnected += (BluetoothHelper helper) => { Log("连接成功\n" + helper.getDeviceName()); SetStatus(BluetoothStatusEnum.ConnectSuccess); BowCamera.isTouchMode = false; foreach (BluetoothHelperService service in helper.getGattServices()) { if (service.getName().ToLower().StartsWith(targetDeviceService)) { bluetoothService = service; foreach (BluetoothHelperCharacteristic characteristic in service.getCharacteristics()) { if (characteristic.getName().ToLower().StartsWith(targetDeviceCharacteristicWrite)) { characteristicWrite = characteristic; } else if (characteristic.getName().ToLower().StartsWith(targetDeviceCharacteristicNotify)) { BluetoothHelperCharacteristic ch = new BluetoothHelperCharacteristic(characteristic.getName()); ch.setService(bluetoothService.getName()); bluetoothHelper.Subscribe(ch); } } } } }; bluetoothHelper.OnConnectionFailed += (BluetoothHelper helper) => { Log("连接失败\n" + helper.getDeviceName()); OnDisconnect(); }; bluetoothHelper.OnCharacteristicChanged += (helper, value, characteristic) => { if (status != BluetoothStatusEnum.ConnectSuccess) return; }; int scanCount = 0; bluetoothHelper.OnScanEnded += (BluetoothHelper helper, LinkedList nearbyDevices) => { foreach (BluetoothDevice device in nearbyDevices) { Log("发现设备 " + device.DeviceName); if (device.DeviceName == targetDeviceName) { deviceName = device.DeviceName; // bluetoothHelper.setDeviceName(deviceName); // bluetoothHelper.Connect(); Log("匹配设备 " + device.DeviceName); onFindTargetDevice?.Invoke(); return; } } if (scanCount < 3) { //如果没扫描到,则重新扫描,达到延迟提示失败的效果 scanCount++; bluetoothHelper.ScanNearbyDevices(); } else { canConnect = true; Log("没有发现设备"); SetStatus(BluetoothStatusEnum.ConnectFail); } }; bluetoothHelper.ScanNearbyDevices(); Log("正在扫描设备"); } catch (Exception e) { Debug.LogError(e); HandleConnectException(TextAutoLanguage2.GetTextByKey("ble-please-open-ble")); } } void HandleConnectException(string errorText) { canConnect = true; status = BluetoothStatusEnum.Connect; userDoConnect = false; PopupMgr.ins.ShowTip(errorText); } void Log(string text) { if (textUI) textUI.text = text; Debug.Log(string.Format("[{0}]{1}", typeof(HRB_Bluetooth).Name, text)); } }