添加unity容器类,允许使用泛型控制界面上的值。

目前添加了一次最多三个项目的属性。
This commit is contained in:
2025-07-23 20:08:59 +08:00
parent 84d79a430e
commit 49f616f4c7
63 changed files with 2580 additions and 6 deletions
@@ -0,0 +1,151 @@
using System;
using System.Collections.Generic;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.UI;
using XericUI.Core.Vessel;
namespace XericUI.FlipPage
{
/// <summary>
/// 翻页组件管理器
///
/// 对翻页组件的管理
/// </summary>
public class FlipPageComponentManager : XericFlipPageIndexVesselBase
{
#region 界面属性
/// <summary>
/// 首页按钮
/// </summary>
#if ODIN_INSPECTOR
[LabelText("首页按钮")] [BoxGroup("组件", centerLabel: true)]
#endif
public ObjectVessel<Button> buttonStartPage;
/// <summary>
/// 上一页按钮
/// </summary>
#if ODIN_INSPECTOR
[LabelText("上一页按钮")] [BoxGroup("组件")]
#endif
public ObjectVessel<Button> buttonPreviousPage;
/// <summary>
/// 下一页按钮
/// </summary>
#if ODIN_INSPECTOR
[LabelText("下一页按钮")] [BoxGroup("组件")]
#endif
public ObjectVessel<Button> buttonNextPage;
/// <summary>
/// 下一页按钮
/// </summary>
#if ODIN_INSPECTOR
[LabelText("尾页按钮")] [BoxGroup("组件")]
#endif
public ObjectVessel<Button> buttoneEndPage;
/// <summary>
/// 总页面数量文本
/// </summary>
#if ODIN_INSPECTOR
[LabelText("总页面数量文本")] [BoxGroup("组件")]
#endif
public ObjectVessel<TMPro.TMP_Text> labelTextTotalPageCount =
new ObjectVessel<TMPro.TMP_Text>();
/// <summary>
/// 总页面数量文本
/// </summary>
#if ODIN_INSPECTOR
[LabelText("总页面数量文本")] [BoxGroup("组件")]
// [ListDrawerSettings(ShowIndexLabels = true)]
#endif
public List<ObjectVessel<Button, TMPro.TMP_Text>> pageSelectButton =
new List<ObjectVessel<Button, TMPro.TMP_Text>>();
/// <summary>
/// 页面跳转输入框
/// </summary>
#if ODIN_INSPECTOR
[LabelText("页面跳转输入框")] [BoxGroup("组件")]
#endif
public ObjectVessel<TMPro.TMP_InputField> inputFieldFlipPageIndex =
new ObjectVessel<TMPro.TMP_InputField>();
/// <summary>
/// 翻页到索引按钮池
/// </summary>
#if ODIN_INSPECTOR
[LabelText("翻页到索引按钮池")] [BoxGroup("组件")]
#endif
public XericLibrary.Runtime.MacroLibrary.MacroPool.UnionSet pageButtonPool = new XericLibrary.Runtime.MacroLibrary.MacroPool.UnionSet();
#endregion
#region 生命周期
protected override void Awake()
{
base.Awake();
if (buttonStartPage.IsValid()) // 翻到开头
buttonStartPage.Target.onClick.AddListener(FlipPageToStart);
if (buttonPreviousPage.IsValid()) // 翻到上一页
buttonPreviousPage.Target.onClick.AddListener(FlipPageToPrevious);
if (buttonNextPage.IsValid()) // 翻到下一页
buttonNextPage.Target.onClick.AddListener(FlipPageToNext);
if (buttoneEndPage.IsValid()) // 翻到结尾
buttoneEndPage.Target.onClick.AddListener(FlipPageToEnd);
pageButtonPool.Init();
}
private void Update()
{
if (labelTextTotalPageCount.IsValid()) // 页数
labelTextTotalPageCount.Target.text = PageInfos.Count.ToString();
}
public override void FlipPage(int pageIndex, bool forceRefresh = false)
{
base.FlipPage(pageIndex, forceRefresh);
}
public override void AddPage(PageInfo pageInfo)
{
base.AddPage(pageInfo);
pageSelectButton.Add(GetPageIndexButton());
}
#endregion
#region 组件方法
/// <summary>
/// 获取页面索引按钮
/// </summary>
/// <returns></returns>
protected virtual ObjectVessel<Button, TMPro.TMP_Text> GetPageIndexButton()
{
var obj = pageButtonPool.Get();
var button = obj.GetComponent<Button>() ?? obj.GetComponentInChildren<Button>();
var text = obj.GetComponent<TMPro.TMP_Text>() ?? obj.GetComponentInChildren<TMPro.TMP_Text>();
// var vessel = new ObjectVessel<Button, TMPro.TMP_Text>(button, text);
// return vessel;
return null;
}
/// <summary>
/// 释放页面索引按钮
/// </summary>
protected virtual void ReleasePageIndexButton(Component comp)
{
pageButtonPool.IndirectRelease(comp);
}
#endregion
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b34975b4d49d413dbb194031b7db92f3
timeCreated: 1753254951
@@ -0,0 +1,221 @@
using System;
using System.Collections.Generic;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UI;
using XericLibrary.Runtime.MacroLibrary;
using XericUI.Core.Base;
using XericUI.Core.Vessel;
namespace XericUI.FlipPage
{
public delegate void PageIndexAction(int pageIndex, int pageOffset, int totalPageCount);
/// <summary>
/// 翻页管理器
/// </summary>
public class XericFlipPageIndexVesselBase : XericUIBehaciour
{
#region 委托事件
public event PageIndexAction OnPageFlip;
#endregion
#region 设定参数
/// <summary>
/// 候选页数量
/// </summary>
#if ODIN_INSPECTOR
[LabelText("候选页数量")]
[BoxGroup("设定", centerLabel: true)]
#endif
[SerializeField]
private int candidatesNumber = 1;
/// <summary>
/// 翻页可以跨越索引边接(循环索引)
/// </summary>
#if ODIN_INSPECTOR
[LabelText("翻页时允许跨越索引循环")]
[BoxGroup("设定", centerLabel: true)]
#endif
[SerializeField]
private bool canPassIndexBoundary;
#endregion
#region 类内类型
[Serializable]
public class PageInfo
{
#if ODIN_INSPECTOR
[LabelText("页面名称")]
#endif
public string Name = DateTime.Now.Ticks.ToString();
}
#endregion
#region 字段属性
/// <summary>
/// 当前页面
/// </summary>
private int _currentPageIndex = 0;
/// <summary>
/// 所有页面
/// </summary>
private LinkedList<PageInfo> _pageInfos = new LinkedList<PageInfo>();
public LinkedList<PageInfo> PageInfos => _pageInfos;
#endregion
#region 生命周期
protected override void Awake()
{
base.Awake();
}
protected override void Start()
{
base.Start();
FlipPage(_currentPageIndex);
}
#endregion
#region 翻页管理
/// <summary>
/// 翻到指定页
/// </summary>
/// <param name="pageIndex"></param>
/// <param name="forceRefresh"></param>
public virtual void FlipPage(int pageIndex, bool forceRefresh = false)
{
// 检查翻页索引有效
if (!canPassIndexBoundary &&
(pageIndex < 0 || pageIndex >= _pageInfos.Count))
pageIndex = Mathf.Clamp(pageIndex, 0, _pageInfos.Count - 1);
else
pageIndex = MacroMath.PMod(pageIndex, _pageInfos.Count - 1);
// 检查翻页数量有效
if (!forceRefresh && _currentPageIndex == pageIndex)
return;
// 翻页计算
var pageIndexOffset = _currentPageIndex - pageIndex;
var lastPageIndex = _currentPageIndex;
_currentPageIndex = pageIndex;
try
{
// 翻页事件委托
OnPageFlip?.Invoke(pageIndex, pageIndexOffset, _pageInfos.Count);
}
catch (Exception e)
{
Debug.LogError($"翻页时委托错误已捕获\n{e.Message}\n{e.Data}");
}
}
/// <summary>
/// 翻到开头
/// </summary>
#if ODIN_INSPECTOR
[HorizontalGroup("翻页"), Button("翻到开头")]
#endif
public void FlipPageToStart()
=> FlipPage(0);
/// <summary>
/// 翻到上一页
/// </summary>
#if ODIN_INSPECTOR
[HorizontalGroup("翻页"), Button("翻到上一页")]
#endif
public void FlipPageToPrevious()
=> FlipPage(_currentPageIndex - 1);
/// <summary>
/// 翻到下一页
/// </summary>
#if ODIN_INSPECTOR
[HorizontalGroup("翻页"), Button("翻到下一页")]
#endif
public void FlipPageToNext()
=> FlipPage(_currentPageIndex + 1);
/// <summary>
/// 翻到结尾
/// </summary>
#if ODIN_INSPECTOR
[HorizontalGroup("翻页"), Button("翻到结尾")]
#endif
public void FlipPageToEnd()
=> FlipPage(_pageInfos.Count - 1);
/// <summary>
/// 添加页面
/// </summary>
public virtual void AddPage(PageInfo pageInfo)
{
_pageInfos.AddLast(pageInfo);
// 刷新页面
FlipPage(_currentPageIndex, true);
}
/// <summary>
/// 移除页面
/// </summary>
public void RemovePage(int pageIndex)
{
RemovePage(IndexOfPage(pageIndex));
}
/// <summary>
/// 移除页面
/// </summary>
/// <param name="pageRef"></param>
public void RemovePage(PageInfo pageRef)
{
_pageInfos.Remove(pageRef);
// 刷新页面
FlipPage(_currentPageIndex, true);
}
/// <summary>
/// 交换AB页面
/// </summary>
public void SwapPages(int pageIndexA, int pageIndexB)
{
var a = _pageInfos.GetOrderNode().LandedIndex(pageIndexA);
var b = _pageInfos.GetOrderNode().LandedIndex(pageIndexB);
_pageInfos.SwapNodes(a, b);
// 刷新页面
FlipPage(_currentPageIndex, true);
}
/// <summary>
/// 选择索引下的页面
/// </summary>
/// <param name="pageIndex"></param>
/// <returns></returns>
public PageInfo IndexOfPage(int pageIndex)
{
return _pageInfos.LandedIndex(pageIndex);
}
#endregion
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2ebd655eef6355d44a67e9b8aef1b8f4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: