InfraredDemo.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5. using SmartBowSDK;
  6. using InfraredManager;
  7. using ZIM;
  8. public class InfraredDemo : MonoBehaviour
  9. {
  10. void Start()
  11. {
  12. InitBluetoothModule();
  13. InitInfraredCamera();
  14. }
  15. void Update()
  16. {
  17. UpdateBluetoothModule();
  18. UpdateInfraredCamera();
  19. }
  20. #region 红外摄像
  21. [SerializeField] RawImage _cameraRender;
  22. [SerializeField] RawImage _imageScreenLocateManual;
  23. [SerializeField] List<RectTransform> _crosshairsInCamera;
  24. [SerializeField] Slider _sliderBrightness;
  25. [SerializeField] Slider _sliderSaturation;
  26. [SerializeField] Slider _sliderContrast;
  27. [SerializeField] Slider _sliderShakeFilter;
  28. [SerializeField] Button _btnReset;
  29. [SerializeField] Button _btnScreenLocateManual;
  30. [SerializeField] Dropdown _dropdownResolution;
  31. [SerializeField] Text _fpsText;
  32. int frames;
  33. float lastCheckTime;
  34. List<Vector2> _screenLocatePoints = new();
  35. public ParamFloatValue brightness = new ParamFloatValue("ic_brightness", 1.0f);
  36. public ParamFloatValue saturation = new ParamFloatValue("ic_saturation", 1.0f);
  37. public ParamFloatValue contrast = new ParamFloatValue("ic_contrast", 1.0f);
  38. public ParamFloatValue shakeFilterValue = new ParamFloatValue("ic_shakeFilterValue2", 6.0f);
  39. public ParamFloatValue resoution = new ParamFloatValue("ic_resoution2", 2);
  40. void InitInfraredCamera()
  41. {
  42. //SDK创建
  43. InfraredCameraHelper.GetInstance().Create();
  44. InfraredCameraHelper.GetInstance().OnPositionUpdate += (Vector2 point) =>
  45. {
  46. Ray ray = Camera.main.ScreenPointToRay(point);
  47. Vector3 rayEndPoint = ray.GetPoint(200);
  48. Bow.Instance.transform.LookAt(rayEndPoint);
  49. };
  50. //参数面板
  51. SetBrightness(brightness.Get());
  52. SetSaturation(saturation.Get());
  53. SetContrast(contrast.Get());
  54. SetShakeFilterValue(shakeFilterValue.Get());
  55. _sliderBrightness.onValueChanged.AddListener(SetBrightness);
  56. _sliderSaturation.onValueChanged.AddListener(SetSaturation);
  57. _sliderContrast.onValueChanged.AddListener(SetContrast);
  58. _sliderShakeFilter.onValueChanged.AddListener(SetShakeFilterValue);
  59. //功能按钮
  60. _btnReset.onClick.AddListener(OnClick_Reset);
  61. _btnScreenLocateManual.onClick.AddListener(OnClick_ScreenLocateManual);
  62. //分辨率
  63. SetResolution((int)resoution.Get());
  64. _dropdownResolution.onValueChanged.AddListener(v =>
  65. {
  66. SetResolution(v);
  67. StartCoroutine(RestartOrKillApp());
  68. });
  69. }
  70. IEnumerator RestartOrKillApp()
  71. {
  72. yield return new WaitForSeconds(0.3f);
  73. if (Application.isEditor) yield break;
  74. if (Application.platform == RuntimePlatform.Android)
  75. {
  76. using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
  77. {
  78. const int kIntent_FLAG_ACTIVITY_CLEAR_TASK = 0x00008000;
  79. const int kIntent_FLAG_ACTIVITY_NEW_TASK = 0x10000000;
  80. var currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
  81. var pm = currentActivity.Call<AndroidJavaObject>("getPackageManager");
  82. var intent = pm.Call<AndroidJavaObject>("getLaunchIntentForPackage", Application.identifier);
  83. intent.Call<AndroidJavaObject>("setFlags", kIntent_FLAG_ACTIVITY_NEW_TASK | kIntent_FLAG_ACTIVITY_CLEAR_TASK);
  84. currentActivity.Call("startActivity", intent);
  85. currentActivity.Call("finish");
  86. var process = new AndroidJavaClass("android.os.Process");
  87. int pid = process.CallStatic<int>("myPid");
  88. process.CallStatic("killProcess", pid);
  89. }
  90. }
  91. else Application.Quit();
  92. }
  93. void SetBrightness(float v)
  94. {
  95. brightness.Set(v);
  96. _sliderBrightness.SetValueWithoutNotify(brightness.Get());
  97. _sliderBrightness.transform.Find("Value").GetComponent<Text>().text = brightness.Get().ToString("f1");
  98. InfraredCameraHelper.GetInstance().SetBrightness(brightness.Get());
  99. }
  100. void UpdateInfraredCamera()
  101. {
  102. //渲染相机画面
  103. _cameraRender.texture = InfraredCameraHelper.GetInstance().GetCameraTexture();
  104. _cameraRender.material = InfraredCameraHelper.GetInstance().GetCameraMaterial();
  105. //手动定位
  106. if (InfraredCameraHelper.GetInstance().IsScreenLocateManualDoing())
  107. {
  108. //引导提示
  109. string tipText = "单击屏幕 左下角";
  110. if (_screenLocatePoints.Count == 1) tipText = "单击屏幕 右下角";
  111. if (_screenLocatePoints.Count == 2) tipText = "单击屏幕 右上角";
  112. if (_screenLocatePoints.Count == 3) tipText = "单击屏幕 左上角";
  113. _imageScreenLocateManual.transform.Find("Text").GetComponent<Text>().text = tipText;
  114. //点击检测
  115. if (Input.GetMouseButtonDown(0))
  116. {
  117. Vector2 mouse = Input.mousePosition;
  118. float u = Mathf.Clamp01(mouse.x / Screen.width);
  119. float v = Mathf.Clamp01(mouse.y / Screen.height);
  120. float texWidth = _imageScreenLocateManual.texture.width;
  121. float texHeight = _imageScreenLocateManual.texture.height;
  122. Vector2 texPoint = new Vector2(u * texWidth, v * texHeight);
  123. _screenLocatePoints.Add(texPoint);
  124. }
  125. //定位点显示
  126. Transform pointsTF = _imageScreenLocateManual.transform.Find("Points");
  127. for (int i = 0; i < pointsTF.childCount; i++)
  128. {
  129. Transform pointTF = pointsTF.GetChild(i);
  130. if (i < _screenLocatePoints.Count)
  131. {
  132. float texWidth = _imageScreenLocateManual.texture.width;
  133. float texHeight = _imageScreenLocateManual.texture.height;
  134. Vector2 texSize = new Vector2(texWidth, texHeight);
  135. Vector2 pos = _screenLocatePoints[i];
  136. pointTF.localPosition = pos.pixelToLocalPosition_AnchorCenter(texSize, _imageScreenLocateManual.rectTransform.rect);
  137. pointTF.gameObject.SetActive(true);
  138. }
  139. else pointTF.gameObject.SetActive(false);
  140. }
  141. //完成定位
  142. if (_screenLocatePoints.Count == 4)
  143. {
  144. _imageScreenLocateManual.gameObject.SetActive(false);
  145. InfraredCameraHelper.GetInstance().QuitScreenLocateManual(_screenLocatePoints);
  146. Transform pointsTF2 = _cameraRender.transform.Find("Points");
  147. if (pointsTF2.childCount == _screenLocatePoints.Count)
  148. {
  149. float texWidth = _imageScreenLocateManual.texture.width;
  150. float texHeight = _imageScreenLocateManual.texture.height;
  151. Vector2 texSize = new Vector2(texWidth, texHeight);
  152. for (int i = 0; i < pointsTF2.childCount; i++)
  153. {
  154. Transform pointTF = pointsTF2.GetChild(i);
  155. Vector2 pos = _screenLocatePoints[i];
  156. pointTF.localPosition = pos.pixelToLocalPosition_AnchorCenter(texSize, _cameraRender.rectTransform.rect);
  157. pointTF.gameObject.SetActive(true);
  158. }
  159. }
  160. }
  161. }
  162. //在相机画面显示准心
  163. if (ScreenLocate.Main)
  164. {
  165. var _sl = ScreenLocate.Main;
  166. var buffer = _sl.infraredSpotBuffer;
  167. if (buffer != null)
  168. {
  169. for (int i = 0; i < buffer.Length; i++)
  170. {
  171. if (buffer[i].CameraLocation != null)
  172. {
  173. // 检测到光点
  174. var pos = buffer[i].CameraLocation.Value.pixelToLocalPosition_AnchorCenter(_sl.mUVCCameraInfo.Size, _cameraRender.rectTransform.rect);
  175. _crosshairsInCamera[i].gameObject.SetActive(true);
  176. _crosshairsInCamera[i].anchoredPosition = pos;
  177. }
  178. else
  179. _crosshairsInCamera[i].gameObject.SetActive(false);
  180. }
  181. }
  182. }
  183. //性能检测
  184. ++frames;
  185. float timeNow = Time.realtimeSinceStartup;
  186. const float UpdateInterval = 0.5f;
  187. if (timeNow > lastCheckTime + UpdateInterval)
  188. {
  189. float fps = (float)(frames / (timeNow - lastCheckTime));
  190. frames = 0;
  191. lastCheckTime = timeNow;
  192. _fpsText.text = "FPS:" + fps.ToString("f2");
  193. }
  194. }
  195. void SetSaturation(float v)
  196. {
  197. saturation.Set(v);
  198. _sliderSaturation.SetValueWithoutNotify(saturation.Get());
  199. _sliderSaturation.transform.Find("Value").GetComponent<Text>().text = saturation.Get().ToString("f1");
  200. InfraredCameraHelper.GetInstance().SetSaturation(saturation.Get());
  201. }
  202. void SetContrast(float v)
  203. {
  204. contrast.Set(v);
  205. _sliderContrast.SetValueWithoutNotify(contrast.Get());
  206. _sliderContrast.transform.Find("Value").GetComponent<Text>().text = contrast.Get().ToString("f1");
  207. InfraredCameraHelper.GetInstance().SetContrast(contrast.Get());
  208. }
  209. void SetShakeFilterValue(float v)
  210. {
  211. shakeFilterValue.Set(v);
  212. _sliderShakeFilter.SetValueWithoutNotify(shakeFilterValue.Get());
  213. _sliderShakeFilter.transform.Find("Value").GetComponent<Text>().text = shakeFilterValue.Get().ToString("f1");
  214. InfraredCameraHelper.GetInstance().SetShakeFilterValue(shakeFilterValue.Get());
  215. }
  216. void SetResolution(int optionIndex)
  217. {
  218. resoution.Set(optionIndex);
  219. _dropdownResolution.SetValueWithoutNotify(optionIndex);
  220. switch (optionIndex)
  221. {
  222. case 0:
  223. InfraredCameraHelper.GetInstance().SetCameraResolution(1280, 720);
  224. break;
  225. case 1:
  226. InfraredCameraHelper.GetInstance().SetCameraResolution(640, 360);
  227. break;
  228. case 2:
  229. InfraredCameraHelper.GetInstance().SetCameraResolution(320, 240);
  230. break;
  231. }
  232. }
  233. void OnClick_Reset()
  234. {
  235. SetBrightness(1);
  236. SetSaturation(1);
  237. SetContrast(1);
  238. SetShakeFilterValue(6);
  239. }
  240. void OnClick_ScreenLocateManual()
  241. {
  242. if (InfraredCameraHelper.GetInstance().IsScreenLocateManualDoing()) return;
  243. Texture2D texture2D = InfraredCameraHelper.GetInstance().EnterScreenLocateManual();
  244. if (texture2D == null)
  245. {
  246. InfraredCameraHelper.GetInstance().QuitScreenLocateManual(null);
  247. return;
  248. }
  249. _imageScreenLocateManual.texture = texture2D;
  250. _imageScreenLocateManual.material = InfraredCameraHelper.GetInstance().GetCameraMaterial();
  251. _screenLocatePoints.Clear();
  252. _imageScreenLocateManual.gameObject.SetActive(true);
  253. }
  254. #endregion
  255. #region 蓝牙模块
  256. [SerializeField] Button _btnConnect;
  257. [SerializeField] Text _textMacAddress;
  258. [SerializeField] Text _textBattery;
  259. void InitBluetoothModule()
  260. {
  261. SmartBowHelper.GetInstance().OnBluetoothModuleInited += OnBluetoothModuleInited;
  262. SmartBowHelper.GetInstance().OnBluetoothError += OnBluetoothError;
  263. SmartBowHelper.GetInstance().OnShooting += OnShooting;
  264. _btnConnect.onClick.AddListener(OnClick_Connect);
  265. }
  266. void UpdateBluetoothModule()
  267. {
  268. //更新显示蓝牙状态
  269. BluetoothStatusEnum bluetoothStatus = SmartBowHelper.GetInstance().GetBluetoothStatus();
  270. Text btnConnectText = _btnConnect.GetComponentInChildren<Text>();
  271. if (bluetoothStatus == BluetoothStatusEnum.None) btnConnectText.text = "<color=blue>未连接</color>(点击连接)";
  272. if (bluetoothStatus == BluetoothStatusEnum.Connecting) btnConnectText.text = "<color=#FF670D>连接中</color>";
  273. if (bluetoothStatus == BluetoothStatusEnum.Connected)
  274. {
  275. if (SmartBowHelper.GetInstance().IsBluetoothModuleInited()) btnConnectText.text = "<color=green>已连接</color>(点击断开)";
  276. else btnConnectText.text = "<color=green>已连接</color><color=blue>(正在初始化)</color>";
  277. }
  278. //更新显示电量
  279. int battery = SmartBowHelper.GetInstance().GetBattery();
  280. _textBattery.text = battery > 0 ? $"电量值:{battery}" : "未获得电量值";
  281. //更新显示Mac地址
  282. string macAddress = SmartBowHelper.GetInstance().GetMacAddress();
  283. _textMacAddress.text = macAddress != null ? $"Mac地址:{macAddress}" : "未获得Mac地址";
  284. }
  285. void OnBluetoothModuleInited()
  286. {
  287. SmartBowHelper.GetInstance().StartShootingSensor();
  288. }
  289. void OnBluetoothError(BluetoothError error, string message)
  290. {
  291. Debug.Log("OnBluetoothError:" + error);
  292. if (error == BluetoothError.ScanNotFoundTargetDevice)
  293. {
  294. TipText.Show("连接失败,未发现目标设备!");
  295. return;
  296. }
  297. TipText.Show(message);
  298. }
  299. void OnShooting(float speed)
  300. {
  301. Bow.Instance.Shoot();
  302. }
  303. void OnClick_Connect()
  304. {
  305. if (SmartBowHelper.GetInstance().GetBluetoothStatus() == BluetoothStatusEnum.Connecting) return;
  306. if (SmartBowHelper.GetInstance().GetBluetoothStatus() == BluetoothStatusEnum.None)
  307. {
  308. SmartBowHelper.GetInstance().Connect("test", 1);
  309. return;
  310. }
  311. if (SmartBowHelper.GetInstance().GetBluetoothStatus() == BluetoothStatusEnum.Connected)
  312. {
  313. SmartBowHelper.GetInstance().Disconnect();
  314. return;
  315. }
  316. }
  317. #endregion
  318. }
  319. public class ParamFloatValue
  320. {
  321. private string _saveKey;
  322. private float _valueDefault;
  323. private bool _valueLoaded;
  324. private float _value;
  325. public ParamFloatValue(string saveKey, float valueDefault)
  326. {
  327. _saveKey = saveKey;
  328. _valueDefault = valueDefault;
  329. }
  330. public float Get()
  331. {
  332. if (!_valueLoaded) _value = PlayerPrefs.GetFloat(_saveKey, _valueDefault);
  333. return _value;
  334. }
  335. public void Set(float value)
  336. {
  337. _value = value;
  338. PlayerPrefs.SetFloat(_saveKey, _value);
  339. PlayerPrefs.Save();
  340. }
  341. }