killapp/Assets/Scripts/UI/Pages/HomePage/HomePageDeviceItem.cs
“虞渠成” 3a335e60a2 chore: 重构DOTween插件路径并更新相关代码
1. 将DOTween从原Plugins/DOTween迁移到Plugins/Demigiant/DOTween
2. 更新版本号解析逻辑,适配设备端压缩编码格式
3. 新增UI动画组件UIAnimator及其编辑器脚本
4. 优化主页设备列表项滑动菜单功能
5. 移除无用的VSCode编辑器包配置
6. 更新多语言文案修正末尾标点
7. 调整主页锁定超时配置为可配置项
2026-08-19 09:47:44 +08:00

177 lines
6.0 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 DG.Tweening;
using Kill.Managers;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace Kill.UI.Pages
{
/// <summary>
/// 首页设备列表项 - 显示单个设备信息
/// 支持左滑手势:左滑时菜单向左滑出并显示高斯模糊覆盖层,
/// 滑动超过菜单宽度1/3松手则完整展开否则缩回并隐藏模糊层
/// </summary>
public class HomePageDeviceItem : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
public Text deviceNameText;
public GameObject selectedIndicator;
/// <summary>菜单子物体锚点位于item最右侧左滑时向左滑出</summary>
public RectTransform menuRect;
/// <summary>高斯模糊覆盖层(子物体,覆盖其他内容),菜单出现时显示,缩回时隐藏</summary>
public GameObject blurOverlay;
// 当前设备信息
public DeviceInfo deviceInfo;
/// <summary>当前展开菜单的item全局仅允许一个菜单展开</summary>
private static HomePageDeviceItem openItem;
private float menuWidth;
private float currentOffset;
private float dragStartOffset;
private bool isMenuOpen;
private bool isDragging;
private Vector3 menuInitPos;
private Tweener tweener;
private Button button;
void Awake()
{
button = GetComponent<Button>();
InitSwipe();
}
void OnDisable()
{
// 防止拖拽中被禁用且未恢复的情况
if (button != null) button.interactable = true;
}
void OnDestroy()
{
// 销毁时释放全局展开引用
if (openItem == this)
openItem = null;
}
public void InitDeviceItem(DeviceInfo device)
{
deviceInfo = device;
deviceNameText.text = device.device_name;
selectedIndicator.SetActive(false);
InitSwipe();
}
public void SetSelectedState(bool isSelected)
{
// 设置选中状态
selectedIndicator.SetActive(isSelected);
}
/// <summary>
/// 初始化滑动数据:记录菜单初始位置、菜单宽度,重置为收起状态
/// </summary>
private void InitSwipe()
{
tweener?.Kill();
if (menuRect == null) return;
menuWidth = menuRect.sizeDelta.x;
menuInitPos = menuRect.anchoredPosition3D;
isMenuOpen = false;
currentOffset = 0;
ApplyMenuOffset(0);
if (blurOverlay != null) blurOverlay.SetActive(false);
}
public void OnBeginDrag(PointerEventData eventData)
{
if (menuRect == null || menuWidth <= 0) return;
// 拖拽滑动时禁用按钮点击,避免与菜单滑动同时触发
if (button != null) button.interactable = false;
// 其他item的菜单展开时先收起保证全局只有一个菜单
if (openItem != null && openItem != this)
openItem.CloseMenu();
isDragging = true;
// 菜单开始出现,显示高斯模糊覆盖层
if (blurOverlay != null) blurOverlay.SetActive(true);
currentOffset = isMenuOpen ? -menuWidth : 0;
dragStartOffset = currentOffset;
ApplyMenuOffset(currentOffset);
}
public void OnDrag(PointerEventData eventData)
{
if (!isDragging) return;
// 累加位移并限制在 [-菜单宽度, 0],只允许左滑露出菜单
currentOffset += eventData.delta.x;
currentOffset = Mathf.Clamp(currentOffset, -menuWidth, 0);
ApplyMenuOffset(currentOffset);
}
public void OnEndDrag(PointerEventData eventData)
{
if (!isDragging) return;
isDragging = false;
// 恢复按钮点击
if (button != null) button.interactable = true;
// 右滑超过菜单宽度的1/5则直接缩回方便关闭已展开的菜单
float dragDistance = currentOffset - dragStartOffset;
if (dragDistance > menuWidth / 5f)
{
AnimateTo(0);
return;
}
// 左滑展示超过菜单宽度的1/3则完整滑出否则缩回
float target = currentOffset < -menuWidth / 3f ? -menuWidth : 0;
AnimateTo(target);
}
/// <summary>
/// 收起菜单(供菜单按钮点击等外部调用)
/// </summary>
public void CloseMenu()
{
if (!isMenuOpen) return;
AnimateTo(0);
}
/// <summary>
/// 将菜单平移到指定偏移
/// </summary>
private void ApplyMenuOffset(float offset)
{
Vector3 pos = menuInitPos;
pos.x += offset;
menuRect.anchoredPosition3D = pos;
}
/// <summary>
/// 平滑动画到目标偏移
/// </summary>
private void AnimateTo(float target)
{
tweener?.Kill();
bool open = target < 0;
if (open)
{
// 已有其他item的菜单展开时先收起保证全局只有一个菜单
if (openItem != null && openItem != this)
openItem.CloseMenu();
openItem = this;
}
else if (openItem == this)
{
openItem = null;
}
isMenuOpen = open;
if (!isMenuOpen && blurOverlay != null)
blurOverlay.SetActive(false); // 菜单缩回时隐藏模糊层
tweener = DOTween.To(() => currentOffset, v =>
{
currentOffset = v;
ApplyMenuOffset(v);
}, target, 0.25f).SetEase(Ease.OutCubic);
}
}
}