DCS/ruiyiweiUX/Assets/Scripts/Views/StandByPanel.cs

338 lines
10 KiB
C#
Raw Permalink Normal View History

2026-06-09 13:59:11 +08:00
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class StandByPanel : BasePanel
{
[Header("UI组件")]
public Image CompanyLogoImage; // 公司图标
public Image LoadingProgressBar; // 加载进度条
public TextMeshProUGUI LoadingStatusText; // 加载状态文本
private CanvasGroup SplashCanvasGroup; // 启动界面Canvas Group用于淡入淡出
[Header("动画参数")]
[SerializeField] private float LogoFadeInDuration = 0.5f; // 图标淡入时间
[SerializeField] private float MinSplashDuration = 3f; // 最小启动界面显示时间(秒)
[SerializeField] private float ConnectionTimeOut = 10f; // 连接超时时间(秒)
[SerializeField] private float FadeOutDuration = 0.5f; // 淡出时间
[Header("串口配置")]
[SerializeField] private string WindowsPortName = "COM1"; // Windows 默认串口名
[SerializeField] private string AndroidPortPath = "/dev/ttyS4"; // 安卓默认设备路径(示例)
[SerializeField] private int DefaultBaudRate = 115200; // 默认波特率
private SerialCommunicationService _serialService;
private DCSAlarmManager _alarmManager;
private bool _isConnectionSuccessful = true;
private bool _communicationErrorDetected = false;
private DateTime _startTime;
private const string COMMUNICATION_ERROR_TITLE = "通讯异常";
private const string COMMUNICATION_ERROR_MESSAGE = "设备通讯异常,请检查:\n1. 数据线连接是否正常\n2. 设备是否已开启\n3. 重启应用重新尝试\n\n无法进入应用。";
public override void Init()
{
// 获取服务
_serialService = ServiceLocator.Get<ISerialCommunicationService>() as SerialCommunicationService;
_alarmManager = DCSAlarmManager.Instance;
InitializeUI();
_startTime = DateTime.Now;
StartCoroutine(InitializationSequence());
}
private void InitializeUI()
{
// 确保Canvas Group存在
if (SplashCanvasGroup == null)
{
SplashCanvasGroup = GetComponent<CanvasGroup>();
if (SplashCanvasGroup == null)
{
SplashCanvasGroup = gameObject.AddComponent<CanvasGroup>();
}
}
// 初始化进度条
if (LoadingProgressBar != null)
{
LoadingProgressBar.fillAmount = 0f;
}
// 初始化文本
if (LoadingStatusText != null)
{
LoadingStatusText.text = "初始化中...";
}
}
/// <summary>
/// 启动序列:动画 -> 连接 -> 验证 -> 进入界面
/// </summary>
private IEnumerator InitializationSequence()
{
// Step 1: 淡入公司图标
yield return StartCoroutine(FadeInLogo());
// Step 2: 在动画期间进行串口连接
UpdateLoadingStatus("连接设备中...", 0.2f);
yield return StartCoroutine(ConnectSerialPort());
// Step 3: 检查通讯状态
UpdateLoadingStatus("验证通讯中...", 0.5f);
yield return StartCoroutine(VerifyCommunication());
// Step 4: 确保最小显示时间
float elapsedTime = (float)(DateTime.Now - _startTime).TotalSeconds;
if (elapsedTime < MinSplashDuration)
{
UpdateLoadingStatus("准备就绪...", 0.8f);
yield return new WaitForSeconds(MinSplashDuration - elapsedTime);
}
// Step 5: 根据连接结果处理
if (_communicationErrorDetected)
{
yield return StartCoroutine(ShowCommunicationErrorDialog());
}
else
{
UpdateLoadingStatus("进入应用...", 1f);
yield return StartCoroutine(FadeOutAndEnterApp());
}
}
/// <summary>
/// 淡入公司图标
/// </summary>
private IEnumerator FadeInLogo()
{
if (CompanyLogoImage != null)
{
CompanyLogoImage.color = new Color(1, 1, 1, 0);
float elapsedTime = 0f;
while (elapsedTime < LogoFadeInDuration)
{
elapsedTime += Time.deltaTime;
float alpha = Mathf.Clamp01(elapsedTime / LogoFadeInDuration);
CompanyLogoImage.color = new Color(1, 1, 1, alpha);
yield return null;
}
CompanyLogoImage.color = new Color(1, 1, 1, 1);
}
yield return new WaitForSeconds(0.5f);
}
/// <summary>
/// 连接串口
/// </summary>
private IEnumerator ConnectSerialPort()
{
if (_serialService == null)
{
Debug.LogError("[SplashScreen] SerialCommunicationService not found!");
_isConnectionSuccessful = false;
yield break;
}
// 订阅通讯错误事件
_serialService.OnCommunicationError -= OnSerialCommunicationError;
_serialService.OnCommunicationError += OnSerialCommunicationError;
// 尝试连接
float connectionStartTime = Time.time;
// 根据平台选择串口名/设备路径
string portName = GetPortNameForPlatform();
UpdateLoadingStatus($"正在连接: {portName} @ {DefaultBaudRate}", 0.25f);
Debug.Log($"[SplashScreen] 尝试连接串口: {portName} @ {DefaultBaudRate}");
bool connected = _serialService.Connect(portName, DefaultBaudRate);
if (!connected)
{
Debug.LogWarning("[SplashScreen] Failed to connect serial port");
_isConnectionSuccessful = false;
_communicationErrorDetected = true;
yield break;
}
// Debug.Log("[SplashScreen] Serial port connected, waiting for handshake...");
// _serialService.SendHandshakeRequest();
// // 等待握手完成或超时
// float timeoutTime = Time.time + ConnectionTimeOut;
// while (!_serialService.IsHandshakeCompleted && Time.time < timeoutTime)
// {
// yield return new WaitForSeconds(0.1f);
// }
// if (!_serialService.IsHandshakeCompleted)
// {
// Debug.LogWarning("[SplashScreen] Serial handshake timeout!");
// _communicationErrorDetected = true;
// }
// else
// {
// Debug.Log("[SplashScreen] Serial handshake completed successfully!");
// }
}
/// <summary>
/// 返回当前平台的串口名/设备路径
/// 注意:安卓端通常为 /dev/ttyS* 或 /dev/ttyUSB*
/// 实际设备路径应根据硬件与驱动调整,可通过日志或配置下发
/// </summary>
private string GetPortNameForPlatform()
{
#if UNITY_ANDROID && !UNITY_EDITOR
return string.IsNullOrEmpty(AndroidPortPath) ? "/dev/ttyS4" : AndroidPortPath;
#else
return string.IsNullOrEmpty(WindowsPortName) ? "COM1" : WindowsPortName;
#endif
}
/// <summary>
/// 验证通讯状态
/// </summary>
private IEnumerator VerifyCommunication()
{
// 等待一段时间,让心跳报告处理完成
yield return new WaitForSeconds(1f);
// 检查DCSAlarmManager是否在启动阶段检测到通讯异常
if (_alarmManager != null && _alarmManager.HasCommunicationErrorDuringStartup)
{
Debug.LogError("[SplashScreen] Communication error detected by DCSAlarmManager!");
_communicationErrorDetected = true;
}
// 如果未检测到通讯错误,则认为通讯正常
if (!_communicationErrorDetected)
{
Debug.Log("[SplashScreen] Communication verification passed!");
}
}
/// <summary>
/// 显示通讯异常对话框
/// </summary>
private IEnumerator ShowCommunicationErrorDialog()
{
// 淡出启动界面
yield return StartCoroutine(FadeOut());
// 显示错误对话框
bool dialogClosed = false;
ConfirmDialog.Show(
COMMUNICATION_ERROR_TITLE,
COMMUNICATION_ERROR_MESSAGE,
onConfirm: () =>
{
dialogClosed = true;
// 关闭应用
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
#else
Application.Quit();
#endif
},
onCancel: null,
confirmText: "关闭应用",
cancelText: "",
isWarning: true,
showCancelButton: false
);
// 等待用户关闭对话框
while (!dialogClosed)
{
yield return new WaitForSeconds(0.1f);
}
}
/// <summary>
/// 淡出并进入应用
/// </summary>
private IEnumerator FadeOutAndEnterApp()
{
yield return StartCoroutine(FadeOut());
// 进入登录界面
UIManager.Instance.ShowPanel<LoginPanel>();
// 销毁启动界面
Destroy(gameObject);
}
/// <summary>
/// 淡出启动界面
/// </summary>
private IEnumerator FadeOut()
{
if (SplashCanvasGroup == null)
yield break;
float elapsedTime = 0f;
while (elapsedTime < FadeOutDuration)
{
elapsedTime += Time.deltaTime;
SplashCanvasGroup.alpha = Mathf.Lerp(1f, 0f, elapsedTime / FadeOutDuration);
yield return null;
}
SplashCanvasGroup.alpha = 0f;
}
/// <summary>
/// 更新加载状态文本和进度条
/// </summary>
private void UpdateLoadingStatus(string statusText, float progress)
{
if (LoadingStatusText != null)
{
LoadingStatusText.text = statusText;
}
if (LoadingProgressBar != null)
{
LoadingProgressBar.fillAmount = Mathf.Clamp01(progress);
}
}
/// <summary>
/// 处理通讯错误事件
/// </summary>
private void OnSerialCommunicationError()
{
Debug.LogWarning("[SplashScreen] Serial communication error detected!");
_communicationErrorDetected = true;
}
void OnDestroy()
{
// 取消订阅
if (_serialService != null)
{
_serialService.OnCommunicationError -= OnSerialCommunicationError;
}
}
public void GenerateLoginUI()
{
// 生成登录界面的逻辑
UIManager.Instance.ShowPanel<LoginPanel>();
}
}