10 KiB
10 KiB
UI系统优化建议
1. UI框架优化
1.1 当前实现
// UIFightTeamController.cs 中的UI实现
public class UIFightTeamController : UIWindow
{
private List<uint> _displayList;
private List<GameObject> _headList;
private bool _isInit = false;
public override void OnInit()
{
UIFightTeamBinder.GetComponents(this);
_OnInit();
}
protected override void OnShowWindow(object data = null)
{
if (_isInit)
{
_isInit = false;
return;
}
_SetData();
_Refresh();
}
}
1.2 优化建议
- UI组件化和对象池优化:
// UI组件基类
public abstract class UIComponent : MonoBehaviour
{
protected UIData _data;
protected bool _initialized;
public virtual void Init()
{
if (_initialized) return;
_initialized = true;
OnInit();
}
protected virtual void OnInit() { }
public virtual void SetData(UIData data)
{
_data = data;
Refresh();
}
public virtual void Refresh() { }
}
// UI对象池管理
public class UIPoolManager
{
private Dictionary<string, Queue<GameObject>> _pools = new();
private Dictionary<string, GameObject> _prefabs = new();
public T GetUI<T>(string prefabPath) where T : UIComponent
{
if (!_pools.ContainsKey(prefabPath))
_pools[prefabPath] = new Queue<GameObject>();
if (_pools[prefabPath].Count > 0)
{
var go = _pools[prefabPath].Dequeue();
go.SetActive(true);
return go.GetComponent<T>();
}
return CreateUI<T>(prefabPath);
}
public void ReturnUI(string prefabPath, GameObject ui)
{
ui.SetActive(false);
_pools[prefabPath].Enqueue(ui);
}
}
protected void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
// 战斗UI的ViewModel
public class FightTeamViewModel : ViewModel
{
private ObservableCollection<UnitViewModel> _units = new();
public ObservableCollection<UnitViewModel> Units => _units;
private UnitViewModel _selectedUnit;
public UnitViewModel SelectedUnit
{
get => _selectedUnit;
set
{
_selectedUnit = value;
NotifyPropertyChanged();
}
}
}
// UI View层
public class UIFightTeamView : UIWindow
{
private FightTeamViewModel _viewModel;
public override void OnInit()
{
_viewModel = new FightTeamViewModel();
InitializeBindings();
}
private void InitializeBindings()
{
// 数据绑定
_viewModel.PropertyChanged += OnViewModelPropertyChanged;
}
}
2. UI性能优化
2.1 列表优化
使用对象池和虚拟列表优化长列表:
public class VirtualizedList<T> : MonoBehaviour where T : MonoBehaviour
{
[SerializeField] private RectTransform _viewport;
[SerializeField] private RectTransform _content;
[SerializeField] private T _itemPrefab;
private List<T> _activeItems = new();
private Queue<T> _pooledItems = new();
private List<IItemData> _dataList = new();
public void SetData(List<IItemData> dataList)
{
_dataList = dataList;
UpdateVisibleItems();
}
private void UpdateVisibleItems()
{
// 计算可见区域
var viewportBounds = new Bounds(_viewport.position, _viewport.rect.size);
// 回收不可见项
for (int i = _activeItems.Count - 1; i >= 0; i--)
{
var item = _activeItems[i];
if (!viewportBounds.Intersects(item.GetComponent<RectTransform>().bounds))
{
ReturnToPool(item);
_activeItems.RemoveAt(i);
}
}
// 创建可见项
foreach (var data in _dataList)
{
if (IsItemVisible(data) && !IsItemCreated(data))
{
CreateItem(data);
}
}
}
}
2.2 UI资源加载优化
使用异步加载和预加载机制:
public class UIResourceManager : MonoBehaviour
{
private Dictionary<string, WeakReference<GameObject>> _uiCache = new();
private HashSet<string> _preloadList = new();
public async UniTask PreloadUI(string uiName)
{
if (_preloadList.Contains(uiName)) return;
var prefab = await LoadUIPrefabAsync(uiName);
_uiCache[uiName] = new WeakReference<GameObject>(prefab);
_preloadList.Add(uiName);
}
public async UniTask<GameObject> GetUI(string uiName)
{
if (_uiCache.TryGetValue(uiName, out var weakRef))
{
if (weakRef.TryGetTarget(out var cachedUI))
{
return cachedUI;
}
}
return await LoadUIPrefabAsync(uiName);
}
}
3. UI事件系统优化
3.1 当前问题
- GameObject查找性能开销
- 组件获取方式不优化
- 事件系统使用不规范
3.2 优化建议
- 优化组件获取:
public class UIUtils
{
// 缓存组件查找结果
private static Dictionary<int, Dictionary<Type, Component>> _componentCache = new();
public static T GetComponent<T>(GameObject go) where T : Component
{
var instanceId = go.GetInstanceID();
var type = typeof(T);
if (!_componentCache.ContainsKey(instanceId))
_componentCache[instanceId] = new Dictionary<Type, Component>();
if (!_componentCache[instanceId].ContainsKey(type))
_componentCache[instanceId][type] = go.GetComponent<T>();
return _componentCache[instanceId][type] as T;
}
public static void ClearCache(GameObject go)
{
var instanceId = go.GetInstanceID();
if (_componentCache.ContainsKey(instanceId))
_componentCache.Remove(instanceId);
}
}
- 优化事件系统使用:
public class UIEventHandler : MonoBehaviour
{
private List<UIEventRegistration> _registrations = new();
protected void RegisterEvent<T>(string eventName, Action<T> handler)
{
var registration = new UIEventRegistration
{
eventName = eventName,
unregisterAction = () => EventManager.Instance.Unregister(eventName, handler)
};
EventManager.Instance.Register(eventName, handler);
_registrations.Add(registration);
}
protected virtual void OnDestroy()
{
foreach (var registration in _registrations)
{
registration.unregisterAction?.Invoke();
}
_registrations.Clear();
}
}
3.2 优化建议
- 实现UI事件管理器:
public class UIEventManager
{
private Dictionary<Type, HashSet<IUIEventHandler>> _eventHandlers = new();
public void Register<T>(IUIEventHandler handler) where T : IUIEvent
{
var type = typeof(T);
if (!_eventHandlers.ContainsKey(type))
{
_eventHandlers[type] = new HashSet<IUIEventHandler>();
}
_eventHandlers[type].Add(handler);
}
public void Unregister<T>(IUIEventHandler handler) where T : IUIEvent
{
var type = typeof(T);
if (_eventHandlers.TryGetValue(type, out var handlers))
{
handlers.Remove(handler);
}
}
public void Dispatch<T>(T uiEvent) where T : IUIEvent
{
var type = typeof(T);
if (_eventHandlers.TryGetValue(type, out var handlers))
{
foreach (var handler in handlers)
{
handler.Handle(uiEvent);
}
}
}
}
4. UI动画系统优化
4.1 实现动画状态机:
public class UIAnimationStateMachine
{
private Dictionary<string, UIAnimationState> _states = new();
private UIAnimationState _currentState;
public async UniTask TransitionTo(string stateName, bool immediate = false)
{
if (_currentState != null)
{
await _currentState.Exit(immediate);
}
if (_states.TryGetValue(stateName, out var newState))
{
_currentState = newState;
await _currentState.Enter(immediate);
}
}
}
public class UIAnimationState
{
private List<UIAnimation> _animations = new();
public async UniTask Enter(bool immediate)
{
foreach (var anim in _animations)
{
if (immediate)
anim.Complete();
else
await anim.Play();
}
}
public async UniTask Exit(bool immediate)
{
foreach (var anim in _animations)
{
if (immediate)
anim.Complete();
else
await anim.Reverse();
}
}
}
5. UI响应式布局优化
5.1 实现响应式布局系统:
public class ResponsiveLayout : MonoBehaviour
{
[SerializeField] private List<BreakPoint> _breakPoints = new();
[SerializeField] private List<LayoutConfig> _configs = new();
private void OnRectTransformDimensionsChange()
{
UpdateLayout();
}
private void UpdateLayout()
{
var currentWidth = GetComponent<RectTransform>().rect.width;
var config = GetConfigForWidth(currentWidth);
ApplyConfig(config);
}
private void ApplyConfig(LayoutConfig config)
{
// 应用布局配置
foreach (var element in config.elements)
{
ApplyElementLayout(element);
}
}
}
6. UI优化建议总结
6.1 架构优化
- 实现MVVM架构
- 统一UI事件系统
- 规范UI生命周期管理
6.2 性能优化
- 使用对象池
- 实现虚拟列表
- 优化UI资源加载
6.3 开发效率
- 完善UI工具链
- 标准化UI组件
- 自动化UI测试
6.4 后续优化方向
-
UI框架
- 实现完整的MVVM框架
- 优化UI导航系统
- 增加UI单元测试
-
性能优化
- 实现UI合批
- 优化UI重建
- 减少UI重绘
-
工具链
- UI编辑器扩展
- UI自动化测试
- UI性能分析工具