killapp/Assets/Scripts/UI/Pages/HomePage/FovSettingPage.cs

564 lines
18 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections;
using System.Collections.Generic;
using Kill.Bluetooth;
using Kill.Bluetooth.Protocol;
using Kill.Core;
using Kill.Managers;
using Kill.UI.Components;
using UnityEngine;
using UnityEngine.UI;
namespace Kill.UI.Pages
{
public class FovSettingPage : MonoBehaviour
{
public Text fovText;
public Image fovIcon;
/// <summary>
/// 角度示例图 30 45 60 75 90 度
/// </summary>
public Sprite[] fovIconSprites;
public Button[] fovSettingButtons;
/// <summary>
/// 按钮背景颜色 0未选中 1选中
/// </summary>
public Color[] buttonBgColors;
/// <summary>
/// 按钮字体颜色 0未选中 1选中
/// </summary>
public Color[] buttonFontColors;
/// <summary>
/// 可见激光开关 0关 1开
/// </summary>
public Button vllButton;
/// <summary>
/// 可见激光开关图标 0关 1开
/// </summary>
public Sprite[] vllButtonSprites;
public Button confirmButton;
public Button cancelButton;
// 当前设置值
private int currentAngle = 30; // 当前角度(度)
private int selectedAngle = 30; // 选中的角度(度)
private bool vllEnabled = false; // 可见激光开关状态
// 进入设置前的原始值(用于取消恢复)
private int originalAngle = 30; // 原始角度
private bool originalVllEnabled = false; // 原始可见激光状态
// 可选角度值
private readonly int[] angleValues = { 30, 45, 60, 75, 90 };
string improvementTextStr="";
bool isLoading = false;
// 静态标志:是否有设置页面正在处理回调
private static bool _isSettingPageActive = false;
void Start()
{
// 绑定按钮点击事件
BindButtonEvents();
improvementTextStr=LanguageManager.Instance.GetLanguage("100103");
InitFovSettingPage();
}
/// <summary>
/// 绑定按钮点击事件
/// </summary>
private void BindButtonEvents()
{
// 绑定角度选择按钮
for (int i = 0; i < fovSettingButtons.Length && i < angleValues.Length; i++)
{
int angle = angleValues[i]; // 捕获局部变量
fovSettingButtons[i].onClick.RemoveAllListeners();
fovSettingButtons[i].onClick.AddListener(() => OnAngleButtonClick(angle));
}
// 绑定可见激光开关按钮
if (vllButton != null)
{
vllButton.onClick.RemoveAllListeners();
vllButton.onClick.AddListener(OnVllButtonClick);
}
// 绑定确认按钮
if (confirmButton != null)
{
confirmButton.onClick.RemoveAllListeners();
confirmButton.onClick.AddListener(OnConfirmButtonClick);
}
// 绑定取消按钮
if (cancelButton != null)
{
cancelButton.onClick.RemoveAllListeners();
cancelButton.onClick.AddListener(OnCancelButtonClick);
}
}
/// <summary>
/// 初始化FOV设置页面
/// </summary>
public void InitFovSettingPage()
{
Debug.Log("[FovSettingPage] 初始化FOV设置页面");
// 注册蓝牙回调(顶替主页)
RegisterBluetoothCallbacks();
// 读取当前角度控制和可见激光设置
ReadAngleAndVllSettings();
}
/// <summary>
/// 注册蓝牙回调(顶替主页)
/// </summary>
private void RegisterBluetoothCallbacks()
{
if (BLECommunicationManager.Instance != null)
{
// 设置标志位,表示设置页面正在处理
_isSettingPageActive = true;
// 订阅事件(不取消主页的订阅,通过标志位控制)
BLECommunicationManager.Instance.OnAngleControlReceived += OnAngleControlReceived;
BLECommunicationManager.Instance.OnVisibleLaserControlReceived += OnVisibleLaserControlReceived;
Debug.Log("[FovSettingPage] 蓝牙回调已注册");
}
}
/// <summary>
/// 注销蓝牙回调(恢复主页)
/// </summary>
private void UnregisterBluetoothCallbacks()
{
if (BLECommunicationManager.Instance != null)
{
// 取消订阅事件
BLECommunicationManager.Instance.OnAngleControlReceived -= OnAngleControlReceived;
BLECommunicationManager.Instance.OnVisibleLaserControlReceived -= OnVisibleLaserControlReceived;
// 清除标志位
_isSettingPageActive = false;
Debug.Log("[FovSettingPage] 蓝牙回调已注销");
}
}
/// <summary>
/// 角度控制接收回调
/// </summary>
private void OnAngleControlReceived(AngleControl control)
{
Loom.QueueOnMainThread(() =>
{
// 只有当前设置页面激活时才处理
if (!_isSettingPageActive) return;
// 角度单位是0.1度,转换为实际角度
currentAngle = Mathf.RoundToInt(control.ActualAngle);
selectedAngle = currentAngle;
originalAngle = currentAngle; // 保存原始值
Debug.Log($"[FovSettingPage] 读取角度控制: {currentAngle}°");
Invoke("ReadVisibleLaserControl",0.2f);
});
// BLECommunicationManager.Instance?.ReadVisibleLaserControl();
}
private void ReadVisibleLaserControl()
{
BLECommunicationManager.Instance?.ReadVisibleLaserControl();
}
/// <summary>
/// 可见激光控制接收回调
/// </summary>
private void OnVisibleLaserControlReceived(VisibleLaserControl control)
{
// 只有当前设置页面激活时才处理
if (!_isSettingPageActive) return;
LoadingUI.Hide();
isLoading=false;
// 获取可见激光开关状态
vllEnabled = control.Enable;
originalVllEnabled = vllEnabled; // 保存原始值
Debug.Log($"[FovSettingPage] 读取可见激光: {vllEnabled}");
// 更新UI显示
UpdateUI();
}
/// <summary>
/// 检查是否有设置页面正在处理回调
/// </summary>
public static bool IsSettingPageActive()
{
return _isSettingPageActive;
}
/// <summary>
/// 读取角度控制和可见激光设置
/// </summary>
private void ReadAngleAndVllSettings()
{
#if UNITY_EDITOR
// 编辑器模式下使用假数据
Editor_InitWithFakeData();
return;
#endif
// 显示Loading
LoadingUI.Show();
isLoading = true;
// 先读取角度控制
BLECommunicationManager.Instance?.ReadAngleControl();
// 超时保护
StartCoroutine(ReadSettingsTimeout());
}
#if UNITY_EDITOR
/// <summary>
/// 编辑器模式下使用假数据初始化
/// </summary>
private void Editor_InitWithFakeData()
{
Debug.Log("[FovSettingPage] 编辑器模式:使用假数据初始化");
// 假数据:角度 60度可见激光开启
currentAngle = 60;
selectedAngle = 60;
vllEnabled = true;
// 更新UI显示
UpdateUI();
}
/// <summary>
/// 编辑器模式切换测试数据可在Inspector中调用
/// </summary>
[ContextMenu("测试切换角度为30度")]
private void Editor_SetAngle30()
{
currentAngle = 30;
selectedAngle = 30;
UpdateUI();
}
[ContextMenu("测试切换角度为90度")]
private void Editor_SetAngle90()
{
currentAngle = 90;
selectedAngle = 90;
UpdateUI();
}
[ContextMenu("测试:切换可见激光开关")]
private void Editor_ToggleVll()
{
vllEnabled = !vllEnabled;
UpdateVllButton();
}
#endif
/// <summary>
/// 读取设置超时保护
/// </summary>
private IEnumerator ReadSettingsTimeout()
{
yield return new WaitForSeconds(5f);
LoadingUI.Hide();
isLoading=false;
}
/// <summary>
/// 更新UI显示
/// </summary>
private void UpdateUI()
{
// 更新角度文本
if (fovText != null)
{
fovText.text = $"{selectedAngle}°";
}
// 更新角度示例图标
UpdateFovIcon(selectedAngle);
// 更新改进文本
UpdateImprovementText();
// 更新按钮选中状态
UpdateButtonSelection(selectedAngle);
// 更新可见激光开关图标
UpdateVllButton();
}
private void UpdateImprovementText()
{
int improvementValue=(90-selectedAngle)/15*10;
if(improvementValue==0)
{
improvementText.text="";
}
else
{
improvementText.text=improvementTextStr.Replace("{0}",improvementValue+"%");
}
}
/// <summary>
/// 更新FOV图标
/// </summary>
private void UpdateFovIcon(int angle)
{
if (fovIcon == null || fovIconSprites == null || fovIconSprites.Length == 0)
return;
// 根据角度选择对应的图标
int iconIndex = angle / 15 - 2; // 30->0, 45->1, 60->2, 75->3, 90->4
iconIndex = Mathf.Clamp(iconIndex, 0, fovIconSprites.Length - 1);
fovIcon.sprite = fovIconSprites[iconIndex];
}
/// <summary>
/// 更新按钮选中状态
/// </summary>
private void UpdateButtonSelection(int angle)
{
if (fovSettingButtons == null || buttonBgColors == null || buttonFontColors == null)
return;
for (int i = 0; i < fovSettingButtons.Length && i < angleValues.Length; i++)
{
bool isSelected = (angleValues[i] == angle);
// 获取按钮的Image和Text组件
Image buttonImage = fovSettingButtons[i].GetComponent<Image>();
Text buttonText = fovSettingButtons[i].GetComponentInChildren<Text>();
if (buttonImage != null && buttonBgColors.Length > 1)
{
buttonImage.color = isSelected ? buttonBgColors[1] : buttonBgColors[0];
}
if (buttonText != null && buttonFontColors.Length > 1)
{
buttonText.color = isSelected ? buttonFontColors[1] : buttonFontColors[0];
}
}
}
/// <summary>
/// 更新可见激光开关按钮
/// </summary>
private void UpdateVllButton()
{
if (vllButton == null || vllButtonSprites == null || vllButtonSprites.Length < 2)
return;
Image buttonImage = vllButton.GetComponent<Image>();
if (buttonImage != null)
{
buttonImage.sprite = vllEnabled ? vllButtonSprites[1] : vllButtonSprites[0];
}
}
public Text improvementText;
/// <summary>
/// 角度按钮点击事件 - 立即发送到设备
/// </summary>
private void OnAngleButtonClick(int angle)
{
Debug.Log($"[FovSettingPage] 选择角度: {angle}°");
selectedAngle = angle;
UpdateUI();
#if UNITY_EDITOR
Debug.Log("[FovSettingPage] 编辑器模式:模拟设置角度");
currentAngle = selectedAngle;
return;
#endif
// 立即发送角度设置到设备
AngleControl angleControl = new AngleControl
{
AngleRange = (ushort)(selectedAngle * 10) // 转换为0.1度单位
};
BLECommunicationManager.Instance?.WriteAngleControl(angleControl, (success) =>
{
Loom.QueueOnMainThread(() =>
{
if (success)
{
Debug.Log($"[FovSettingPage] 角度设置成功: {selectedAngle}°");
currentAngle = selectedAngle;
}
else
{
Debug.LogError("[FovSettingPage] 角度设置失败");
// 设置失败恢复UI显示
selectedAngle = currentAngle;
UpdateUI();
}
});
});
}
/// <summary>
/// 可见激光开关按钮点击事件 - 立即发送到设备
/// </summary>
private void OnVllButtonClick()
{
bool newVllState = !vllEnabled;
Debug.Log($"[FovSettingPage] 可见激光开关: {(newVllState ? "" : "")}");
#if UNITY_EDITOR
Debug.Log("[FovSettingPage] 编辑器模式:模拟设置可见激光");
vllEnabled = newVllState;
UpdateVllButton();
return;
#endif
// 立即发送可见激光设置到设备
VisibleLaserControl vllControl = new VisibleLaserControl
{
Enable = newVllState
};
BLECommunicationManager.Instance?.WriteVisibleLaserControl(vllControl, (success) =>
{
Loom.QueueOnMainThread(() =>
{
if (success)
{
Debug.Log($"[FovSettingPage] 可见激光设置成功: {(newVllState ? "" : "")}");
vllEnabled = newVllState;
UpdateVllButton();
}
else
{
Debug.LogError("[FovSettingPage] 可见激光设置失败");
// 设置失败不更新UI保持原状态
}
});
});
}
/// <summary>
/// 确认按钮点击事件 - 只是关闭页面,设置已经实时生效
/// </summary>
private void OnConfirmButtonClick()
{
Debug.Log($"[FovSettingPage] 确认设置,当前角度={selectedAngle}°");
// 通知主页刷新角度信息
NotifyHomePageRefresh();
// 关闭页面
ClosePage();
}
/// <summary>
/// 写入设置超时保护
/// </summary>
private IEnumerator WriteSettingsTimeout()
{
yield return new WaitForSeconds(5f);
LoadingUI.Hide();
}
/// <summary>
/// 取消按钮点击事件 - 只恢复原始角度,可见激光不恢复
/// </summary>
public void OnCancelButtonClick()
{
Debug.Log("[FovSettingPage] 取消设置,恢复原始角度");
#if UNITY_EDITOR
Debug.Log("[FovSettingPage] 编辑器模式:模拟恢复原始角度");
ClosePage();
return;
#endif
// 如果角度没有变化,直接关闭页面
if (selectedAngle == originalAngle)
{
Debug.Log("[FovSettingPage] 角度未变化,直接关闭页面");
ClosePage();
return;
}
// 显示Loading
LoadingUI.Show();
// 只恢复原始角度(可见激光不恢复)
AngleControl angleControl = new AngleControl
{
AngleRange = (ushort)(originalAngle * 10)
};
BLECommunicationManager.Instance?.WriteAngleControl(angleControl, (angleSuccess) =>
{
Loom.QueueOnMainThread(() =>
{
LoadingUI.Hide();
if (angleSuccess)
{
Debug.Log($"[FovSettingPage] 角度恢复成功: {originalAngle}°");
currentAngle = originalAngle;
selectedAngle = originalAngle;
}
else
{
Debug.LogError("[FovSettingPage] 角度恢复失败");
}
// 通知主页刷新
NotifyHomePageRefresh();
// 关闭页面
ClosePage();
});
});
// 超时保护
StartCoroutine(WriteSettingsTimeout());
}
/// <summary>
/// 通知主页刷新角度信息
/// </summary>
private void NotifyHomePageRefresh()
{
// 通过事件或直接调用主页方法刷新
HomePageCtrl.Instance?.RefreshAngleControl();
}
/// <summary>
/// 关闭页面
/// </summary>
private void ClosePage()
{
// 注销蓝牙回调(恢复主页)
UnregisterBluetoothCallbacks();
// 通知主页刷新
NotifyHomePageRefresh();
Destroy(gameObject);
// 清除UIManager返回事件
UIManager.Instance?.ClearBackAction();
if(isLoading)
{
LoadingUI.Hide();
isLoading=false;
}
}
}
}