using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using SmartBowSDK; using InfraredManager; using ZIM; public class InfraredDemo : MonoBehaviour { void Start() { InitBluetoothModule(); InitInfraredCamera(); } void Update() { UpdateBluetoothModule(); UpdateInfraredCamera(); } #region 红外摄像 [SerializeField] RawImage _cameraRender; [SerializeField] RawImage _imageScreenLocateManual; [SerializeField] List _crosshairsInCamera; [SerializeField] Slider _sliderBrightness; [SerializeField] Slider _sliderSaturation; [SerializeField] Slider _sliderContrast; [SerializeField] Slider _sliderShakeFilter; [SerializeField] Button _btnReset; [SerializeField] Button _btnScreenLocateManual; [SerializeField] Dropdown _dropdownResolution; [SerializeField] Text _fpsText; int frames; float lastCheckTime; List _screenLocatePoints = new(); public ParamFloatValue brightness = new ParamFloatValue("ic_brightness", 1.0f); public ParamFloatValue saturation = new ParamFloatValue("ic_saturation", 1.0f); public ParamFloatValue contrast = new ParamFloatValue("ic_contrast", 1.0f); public ParamFloatValue shakeFilterValue = new ParamFloatValue("ic_shakeFilterValue", 3.0f); public ParamFloatValue resoution = new ParamFloatValue("ic_resoution", 0); void InitInfraredCamera() { //SDK创建 InfraredCameraHelper.GetInstance().Create(); InfraredCameraHelper.GetInstance().OnPositionUpdate += (Vector2 point) => { Ray ray = Camera.main.ScreenPointToRay(point); Vector3 rayEndPoint = ray.GetPoint(200); Bow.Instance.transform.LookAt(rayEndPoint); }; //参数面板 SetBrightness(brightness.Get()); SetSaturation(saturation.Get()); SetContrast(contrast.Get()); SetShakeFilterValue(shakeFilterValue.Get()); _sliderBrightness.onValueChanged.AddListener(SetBrightness); _sliderSaturation.onValueChanged.AddListener(SetSaturation); _sliderContrast.onValueChanged.AddListener(SetContrast); _sliderShakeFilter.onValueChanged.AddListener(SetShakeFilterValue); //功能按钮 _btnReset.onClick.AddListener(OnClick_Reset); _btnScreenLocateManual.onClick.AddListener(OnClick_ScreenLocateManual); //分辨率 SetResolution((int)resoution.Get()); _dropdownResolution.onValueChanged.AddListener(v => { SetResolution(v); StartCoroutine(RestartOrKillApp()); }); } IEnumerator RestartOrKillApp() { yield return new WaitForSeconds(0.3f); if (Application.isEditor) yield break; if (Application.platform == RuntimePlatform.Android) { using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) { const int kIntent_FLAG_ACTIVITY_CLEAR_TASK = 0x00008000; const int kIntent_FLAG_ACTIVITY_NEW_TASK = 0x10000000; var currentActivity = unityPlayer.GetStatic("currentActivity"); var pm = currentActivity.Call("getPackageManager"); var intent = pm.Call("getLaunchIntentForPackage", Application.identifier); intent.Call("setFlags", kIntent_FLAG_ACTIVITY_NEW_TASK | kIntent_FLAG_ACTIVITY_CLEAR_TASK); currentActivity.Call("startActivity", intent); currentActivity.Call("finish"); var process = new AndroidJavaClass("android.os.Process"); int pid = process.CallStatic("myPid"); process.CallStatic("killProcess", pid); } } else Application.Quit(); } void SetBrightness(float v) { brightness.Set(v); _sliderBrightness.SetValueWithoutNotify(brightness.Get()); _sliderBrightness.transform.Find("Value").GetComponent().text = brightness.Get().ToString("f1"); InfraredCameraHelper.GetInstance().SetBrightness(brightness.Get()); } void UpdateInfraredCamera() { //渲染相机画面 _cameraRender.texture = InfraredCameraHelper.GetInstance().GetCameraTexture(); _cameraRender.material = InfraredCameraHelper.GetInstance().GetCameraMaterial(); //手动定位 if (InfraredCameraHelper.GetInstance().IsScreenLocateManualDoing()) { //引导提示 string tipText = "单击屏幕 左下角"; if (_screenLocatePoints.Count == 1) tipText = "单击屏幕 右下角"; if (_screenLocatePoints.Count == 2) tipText = "单击屏幕 右上角"; if (_screenLocatePoints.Count == 3) tipText = "单击屏幕 左上角"; _imageScreenLocateManual.transform.Find("Text").GetComponent().text = tipText; //点击检测 if (Input.GetMouseButtonDown(0)) { Vector2 mouse = Input.mousePosition; float u = Mathf.Clamp01(mouse.x / Screen.width); float v = Mathf.Clamp01(mouse.y / Screen.height); float texWidth = _imageScreenLocateManual.texture.width; float texHeight = _imageScreenLocateManual.texture.height; Vector2 texPoint = new Vector2(u * texWidth, v * texHeight); _screenLocatePoints.Add(texPoint); } //定位点显示 Transform pointsTF = _imageScreenLocateManual.transform.Find("Points"); for (int i = 0; i < pointsTF.childCount; i++) { Transform pointTF = pointsTF.GetChild(i); if (i < _screenLocatePoints.Count) { float texWidth = _imageScreenLocateManual.texture.width; float texHeight = _imageScreenLocateManual.texture.height; Vector2 texSize = new Vector2(texWidth, texHeight); Vector2 pos = _screenLocatePoints[i]; pointTF.localPosition = pos.pixelToLocalPosition_AnchorCenter(texSize, _imageScreenLocateManual.rectTransform.rect); pointTF.gameObject.SetActive(true); } else pointTF.gameObject.SetActive(false); } //完成定位 if (_screenLocatePoints.Count == 4) { _imageScreenLocateManual.gameObject.SetActive(false); InfraredCameraHelper.GetInstance().QuitScreenLocateManual(_screenLocatePoints); Transform pointsTF2 = _cameraRender.transform.Find("Points"); if (pointsTF2.childCount == _screenLocatePoints.Count) { float texWidth = _imageScreenLocateManual.texture.width; float texHeight = _imageScreenLocateManual.texture.height; Vector2 texSize = new Vector2(texWidth, texHeight); for (int i = 0; i < pointsTF2.childCount; i++) { Transform pointTF = pointsTF2.GetChild(i); Vector2 pos = _screenLocatePoints[i]; pointTF.localPosition = pos.pixelToLocalPosition_AnchorCenter(texSize, _cameraRender.rectTransform.rect); pointTF.gameObject.SetActive(true); } } } } //在相机画面显示准心 if (ScreenLocate.Main) { var _sl = ScreenLocate.Main; var buffer = _sl.infraredSpotBuffer; if (buffer != null) { for (int i = 0; i < buffer.Length; i++) { if (buffer[i].CameraLocation != null) { // 检测到光点 var pos = buffer[i].CameraLocation.Value.pixelToLocalPosition_AnchorCenter(_sl.mUVCCameraInfo.Size, _cameraRender.rectTransform.rect); _crosshairsInCamera[i].gameObject.SetActive(true); _crosshairsInCamera[i].anchoredPosition = pos; } else _crosshairsInCamera[i].gameObject.SetActive(false); } } } //性能检测 ++frames; float timeNow = Time.realtimeSinceStartup; const float UpdateInterval = 0.5f; if (timeNow > lastCheckTime + UpdateInterval) { float fps = (float)(frames / (timeNow - lastCheckTime)); frames = 0; lastCheckTime = timeNow; _fpsText.text = "FPS:" + fps.ToString("f2"); } } void SetSaturation(float v) { saturation.Set(v); _sliderSaturation.SetValueWithoutNotify(saturation.Get()); _sliderSaturation.transform.Find("Value").GetComponent().text = saturation.Get().ToString("f1"); InfraredCameraHelper.GetInstance().SetSaturation(saturation.Get()); } void SetContrast(float v) { contrast.Set(v); _sliderContrast.SetValueWithoutNotify(contrast.Get()); _sliderContrast.transform.Find("Value").GetComponent().text = contrast.Get().ToString("f1"); InfraredCameraHelper.GetInstance().SetContrast(contrast.Get()); } void SetShakeFilterValue(float v) { shakeFilterValue.Set(v); _sliderShakeFilter.SetValueWithoutNotify(shakeFilterValue.Get()); _sliderShakeFilter.transform.Find("Value").GetComponent().text = shakeFilterValue.Get().ToString("f1"); InfraredCameraHelper.GetInstance().SetShakeFilterValue(shakeFilterValue.Get()); } void SetResolution(int optionIndex) { resoution.Set(optionIndex); _dropdownResolution.SetValueWithoutNotify(optionIndex); switch (optionIndex) { case 0: InfraredCameraHelper.GetInstance().SetCameraResolution(1280, 720); break; case 1: InfraredCameraHelper.GetInstance().SetCameraResolution(640, 360); break; case 2: InfraredCameraHelper.GetInstance().SetCameraResolution(320, 240); break; } } void OnClick_Reset() { SetBrightness(1); SetSaturation(1); SetContrast(1); SetShakeFilterValue(3); } void OnClick_ScreenLocateManual() { if (InfraredCameraHelper.GetInstance().IsScreenLocateManualDoing()) return; Texture2D texture2D = InfraredCameraHelper.GetInstance().EnterScreenLocateManual(); if (texture2D == null) { InfraredCameraHelper.GetInstance().QuitScreenLocateManual(null); return; } _imageScreenLocateManual.texture = texture2D; _screenLocatePoints.Clear(); _imageScreenLocateManual.gameObject.SetActive(true); } #endregion #region 蓝牙模块 [SerializeField] Button _btnConnect; [SerializeField] Text _textMacAddress; [SerializeField] Text _textBattery; void InitBluetoothModule() { SmartBowHelper.GetInstance().OnBluetoothModuleInited += OnBluetoothModuleInited; SmartBowHelper.GetInstance().OnBluetoothError += OnBluetoothError; SmartBowHelper.GetInstance().OnShooting += OnShooting; _btnConnect.onClick.AddListener(OnClick_Connect); } void UpdateBluetoothModule() { //更新显示蓝牙状态 BluetoothStatusEnum bluetoothStatus = SmartBowHelper.GetInstance().GetBluetoothStatus(); Text btnConnectText = _btnConnect.GetComponentInChildren(); if (bluetoothStatus == BluetoothStatusEnum.None) btnConnectText.text = "未连接(点击连接)"; if (bluetoothStatus == BluetoothStatusEnum.Connecting) btnConnectText.text = "连接中"; if (bluetoothStatus == BluetoothStatusEnum.Connected) { if (SmartBowHelper.GetInstance().IsBluetoothModuleInited()) btnConnectText.text = "已连接(点击断开)"; else btnConnectText.text = "已连接(正在初始化)"; } //更新显示电量 int battery = SmartBowHelper.GetInstance().GetBattery(); _textBattery.text = battery > 0 ? $"电量值:{battery}" : "未获得电量值"; //更新显示Mac地址 string macAddress = SmartBowHelper.GetInstance().GetMacAddress(); _textMacAddress.text = macAddress != null ? $"Mac地址:{macAddress}" : "未获得Mac地址"; } void OnBluetoothModuleInited() { SmartBowHelper.GetInstance().StartShootingSensor(); } void OnBluetoothError(BluetoothError error, string message) { Debug.Log("OnBluetoothError:" + error); if (error == BluetoothError.ScanNotFoundTargetDevice) { TipText.Show("连接失败,未发现目标设备!"); return; } TipText.Show(message); } void OnShooting(float speed) { Bow.Instance.Shoot(); } void OnClick_Connect() { if (SmartBowHelper.GetInstance().GetBluetoothStatus() == BluetoothStatusEnum.Connecting) return; if (SmartBowHelper.GetInstance().GetBluetoothStatus() == BluetoothStatusEnum.None) { SmartBowHelper.GetInstance().Connect("test", 1); return; } if (SmartBowHelper.GetInstance().GetBluetoothStatus() == BluetoothStatusEnum.Connected) { SmartBowHelper.GetInstance().Disconnect(); return; } } #endregion } public class ParamFloatValue { private string _saveKey; private float _valueDefault; private bool _valueLoaded; private float _value; public ParamFloatValue(string saveKey, float valueDefault) { _saveKey = saveKey; _valueDefault = valueDefault; } public float Get() { if (!_valueLoaded) _value = PlayerPrefs.GetFloat(_saveKey, _valueDefault); return _value; } public void Set(float value) { _value = value; PlayerPrefs.SetFloat(_saveKey, _value); PlayerPrefs.Save(); } }