1. 将DOTween从原Plugins/DOTween迁移到Plugins/Demigiant/DOTween 2. 更新版本号解析逻辑,适配设备端压缩编码格式 3. 新增UI动画组件UIAnimator及其编辑器脚本 4. 优化主页设备列表项滑动菜单功能 5. 移除无用的VSCode编辑器包配置 6. 更新多语言文案修正末尾标点 7. 调整主页锁定超时配置为可配置项
177 lines
6.0 KiB
C#
177 lines
6.0 KiB
C#
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);
|
||
}
|
||
}
|
||
}
|