| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using DG.Tweening;
- using TMPro;
- using UnityEngine;
- using UnityEngine.UI;
- namespace AppUI.View.Home.Main
- {
- [Serializable]
- public class TopBarButtonInfoTMP
- {
- public string Name;
- public Image Icon;
- [Tooltip("选中态图标,不填则保持当前 Sprite 仅切换颜色")]
- public Sprite selectedIconSprite;
- [Tooltip("未选中态图标,不填则保持当前 Sprite 仅切换颜色")]
- public Sprite unselectedIconSprite;
- public TMP_Text text;
- public bool selected;
- public DeviceMode deviceMode;
- public GameObject container;
- [Tooltip("背景滑动对齐目标(如 Archery / Gun 按钮节点),不填则使用 container")]
- public RectTransform tabRect;
- }
- public class HomeViewTopBar : MonoBehaviour
- {
- public List<TopBarButtonInfoTMP> topBarButtonInfos;
- public UnityEngine.Events.UnityEvent<DeviceMode> onChangeTypeEvent;
- [Header("背景滑动")]
- [SerializeField] RectTransform btnBg;
- [SerializeField] float btnBgMoveDuration = 0.25f;
- [SerializeField] Ease btnBgMoveEase = Ease.OutCubic;
- [Tooltip("切换时是否同步缩放到 tab 节点尺寸")]
- [SerializeField] bool matchTabSize;
- [Header("背景 Padding")]
- [Tooltip("位置偏移,相对标签本地坐标(X 向右,Y 向上)")]
- [SerializeField] Vector2 btnBgPositionOffset;
- [Tooltip("在标签尺寸基础上向四周扩展(仅 Match Tab Size 开启时生效)")]
- [SerializeField] float btnBgPaddingLeft;
- [SerializeField] float btnBgPaddingRight;
- [SerializeField] float btnBgPaddingTop;
- [SerializeField] float btnBgPaddingBottom;
- static readonly Color32 SelectedIconColor = new Color32(0, 0, 0, 255);
- static readonly Color32 SelectedTextColor = new Color32(48, 57, 57, 255);
- static readonly Color32 UnselectedIconColor = new Color32(255, 255, 255, 255);
- static readonly Color32 UnselectedTextColor = new Color32(141, 150, 151, 255);
- string _saveKey = "DeviceModeKey";
- int _value;
- int _valueDefault;
- Tween _btnBgTween;
- void Start()
- {
- int deviceValue = GetDeviceModeValue();
- if (topBarButtonInfos != null && topBarButtonInfos.Count > 0)
- deviceValue = Mathf.Clamp(deviceValue, 0, topBarButtonInfos.Count - 1);
- GlobalData.MyDeviceMode = (DeviceMode)deviceValue;
- Debug.Log(" GlobalData.MyDeviceMode :" + GlobalData.MyDeviceMode);
- onChangeTypeEvent?.Invoke(GlobalData.MyDeviceMode);
- UpdateTabVisuals(deviceValue);
- StartCoroutine(InitBtnBgPositionAfterLayout(deviceValue));
- }
- IEnumerator InitBtnBgPositionAfterLayout(int index)
- {
- yield return null;
- Canvas.ForceUpdateCanvases();
- MoveBtnBgToTab(index, false);
- }
- void OnDestroy()
- {
- _btnBgTween?.Kill();
- if (btnBg != null)
- btnBg.DOKill();
- }
- public TopBarButtonInfoTMP GetCurrentTopBarButtonInfo()
- {
- return topBarButtonInfos[(int)GlobalData.MyDeviceMode];
- }
- public void onChangeType(int index)
- {
- if (topBarButtonInfos == null || index < 0 || index >= topBarButtonInfos.Count)
- return;
- UpdateTabVisuals(index);
- MoveBtnBgToTab(index, true);
- SetDeviceModeValue(index);
- GlobalData.MyDeviceMode = (DeviceMode)index;
- Debug.Log("Set GlobalData.MyDeviceMode :" + GlobalData.MyDeviceMode);
- onChangeTypeEvent?.Invoke(GlobalData.MyDeviceMode);
- }
- void UpdateTabVisuals(int selectedIndex)
- {
- if (topBarButtonInfos == null) return;
- for (int i = 0; i < topBarButtonInfos.Count; i++)
- {
- TopBarButtonInfoTMP topBarButtonInfo = topBarButtonInfos[i];
- bool isSelected = i == selectedIndex;
- topBarButtonInfo.selected = isSelected;
- ApplyIconVisual(topBarButtonInfo, isSelected);
- if (topBarButtonInfo.text == null)
- continue;
- topBarButtonInfo.text.color = isSelected ? SelectedTextColor : UnselectedTextColor;
- }
- }
- static void ApplyIconVisual(TopBarButtonInfoTMP info, bool isSelected)
- {
- if (info?.Icon == null)
- return;
- info.Icon.color = isSelected ? SelectedIconColor : UnselectedIconColor;
- Sprite targetSprite = isSelected ? info.selectedIconSprite : info.unselectedIconSprite;
- if (targetSprite != null)
- info.Icon.sprite = targetSprite;
- }
- void MoveBtnBgToTab(int index, bool animate)
- {
- if (btnBg == null || topBarButtonInfos == null || index < 0 || index >= topBarButtonInfos.Count)
- return;
- RectTransform target = GetTabBgTarget(topBarButtonInfos[index]);
- if (target == null)
- return;
- Canvas.ForceUpdateCanvases();
- CalcBtnBgTarget(target, out Vector3 targetPos, out Vector2 targetSize);
- _btnBgTween?.Kill();
- btnBg.DOKill();
- if (animate)
- {
- Sequence seq = DOTween.Sequence();
- seq.Join(btnBg.DOMove(targetPos, btnBgMoveDuration).SetEase(btnBgMoveEase));
- if (matchTabSize)
- seq.Join(btnBg.DOSizeDelta(targetSize, btnBgMoveDuration).SetEase(btnBgMoveEase));
- _btnBgTween = seq;
- }
- else
- {
- btnBg.position = targetPos;
- if (matchTabSize)
- btnBg.sizeDelta = targetSize;
- }
- }
- void CalcBtnBgTarget(RectTransform target, out Vector3 worldPos, out Vector2 size)
- {
- Vector2 localCenter = target.rect.center;
- localCenter.x += btnBgPositionOffset.x + (btnBgPaddingRight - btnBgPaddingLeft) * 0.5f;
- localCenter.y += btnBgPositionOffset.y + (btnBgPaddingTop - btnBgPaddingBottom) * 0.5f;
- Vector3 targetWorldCenter = target.TransformPoint(localCenter);
- worldPos = new Vector3(targetWorldCenter.x, targetWorldCenter.y, btnBg.position.z);
- size = new Vector2(
- target.rect.width + btnBgPaddingLeft + btnBgPaddingRight,
- target.rect.height + btnBgPaddingTop + btnBgPaddingBottom);
- }
- RectTransform GetTabBgTarget(TopBarButtonInfoTMP info)
- {
- if (info == null)
- return null;
- if (info.tabRect != null)
- return info.tabRect;
- if (info.container != null)
- return info.container.GetComponent<RectTransform>();
- return null;
- }
- public int GetDeviceModeValue()
- {
- _value = PlayerPrefs.GetInt(_saveKey, _valueDefault);
- return _value;
- }
- public void SetDeviceModeValue(int value)
- {
- _value = value;
- PlayerPrefs.SetInt(_saveKey, _value);
- PlayerPrefs.Save();
- }
- }
- }
|