继续重构调整(UI)
- 引入 UniTask 和异步版本的 UIModule - 调整 Runtime/UIBase 和 Presentation 下的脚本命名空间到 SepCore.UI - 将原来的 5 层 UI 迁移到异步实现 - 规范各层的 UI 脚本命名
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
using SepCore.Definition;
|
||||
using GameFramework;
|
||||
using StarForce;
|
||||
using UI;
|
||||
using SepCore.UI;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
using UnityGameFramework.Runtime;
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using GameFramework.ObjectPool;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityGameFramework.Runtime;
|
||||
|
||||
namespace CustomComponent
|
||||
@@ -78,4 +75,4 @@ namespace CustomComponent
|
||||
_damageTextItemPool = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using GameFramework.ObjectPool;
|
||||
using GameFramework.ObjectPool;
|
||||
using System.Collections.Generic;
|
||||
using Entity;
|
||||
using StarForce;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
using UnityGameFramework.Runtime;
|
||||
|
||||
namespace CustomComponent
|
||||
@@ -122,4 +114,4 @@ namespace CustomComponent
|
||||
return hpBarItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections;
|
||||
using Entity;
|
||||
using UI;
|
||||
using SepCore.UI;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
using UnityEngine.UI;
|
||||
using UnityGameFramework.Runtime;
|
||||
|
||||
@@ -20,22 +14,15 @@ namespace StarForce
|
||||
private const float KeepSeconds = 0.4f;
|
||||
private const float FadeOutSeconds = 0.3f;
|
||||
|
||||
[SerializeField]
|
||||
private Slider m_HPBar = null;
|
||||
[FormerlySerializedAs("m_HPBar")] [SerializeField] private Slider _hPBar = null;
|
||||
|
||||
private Canvas m_ParentCanvas = null;
|
||||
private RectTransform m_CachedTransform = null;
|
||||
private CanvasGroup m_CachedCanvasGroup = null;
|
||||
private EntityBase m_Owner = null;
|
||||
private Canvas _parentCanvas = null;
|
||||
private RectTransform _cachedTransform = null;
|
||||
private CanvasGroup _cachedCanvasGroup = null;
|
||||
private EntityBase _owner = null;
|
||||
private int m_OwnerId = 0;
|
||||
|
||||
public EntityBase Owner
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Owner;
|
||||
}
|
||||
}
|
||||
public EntityBase Owner => _owner;
|
||||
|
||||
public void Init(EntityBase owner, Canvas parentCanvas, float fromHPRatio, float toHPRatio)
|
||||
{
|
||||
@@ -45,16 +32,16 @@ namespace StarForce
|
||||
return;
|
||||
}
|
||||
|
||||
m_ParentCanvas = parentCanvas;
|
||||
_parentCanvas = parentCanvas;
|
||||
|
||||
gameObject.SetActive(true);
|
||||
StopAllCoroutines();
|
||||
|
||||
m_CachedCanvasGroup.alpha = 1f;
|
||||
if (m_Owner != owner || m_OwnerId != owner.Id)
|
||||
_cachedCanvasGroup.alpha = 1f;
|
||||
if (_owner != owner || m_OwnerId != owner.Id)
|
||||
{
|
||||
m_HPBar.value = fromHPRatio;
|
||||
m_Owner = owner;
|
||||
_hPBar.value = fromHPRatio;
|
||||
_owner = owner;
|
||||
m_OwnerId = owner.Id;
|
||||
}
|
||||
|
||||
@@ -65,21 +52,22 @@ namespace StarForce
|
||||
|
||||
public bool Refresh()
|
||||
{
|
||||
if (m_CachedCanvasGroup.alpha <= 0f)
|
||||
if (_cachedCanvasGroup.alpha <= 0f)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_Owner != null && Owner.Available && Owner.Id == m_OwnerId)
|
||||
if (_owner != null && Owner.Available && Owner.Id == m_OwnerId)
|
||||
{
|
||||
Vector3 worldPosition = m_Owner.CachedTransform.position + Vector3.forward;
|
||||
Vector3 worldPosition = _owner.CachedTransform.position + Vector3.forward;
|
||||
Vector3 screenPosition = GameEntry.Scene.MainCamera.WorldToScreenPoint(worldPosition);
|
||||
|
||||
Vector2 position;
|
||||
if (RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)m_ParentCanvas.transform, screenPosition,
|
||||
m_ParentCanvas.worldCamera, out position))
|
||||
if (RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)_parentCanvas.transform,
|
||||
screenPosition,
|
||||
_parentCanvas.worldCamera, out position))
|
||||
{
|
||||
m_CachedTransform.localPosition = position;
|
||||
_cachedTransform.localPosition = position;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,23 +77,23 @@ namespace StarForce
|
||||
public void Reset()
|
||||
{
|
||||
StopAllCoroutines();
|
||||
m_CachedCanvasGroup.alpha = 1f;
|
||||
m_HPBar.value = 1f;
|
||||
m_Owner = null;
|
||||
_cachedCanvasGroup.alpha = 1f;
|
||||
_hPBar.value = 1f;
|
||||
_owner = null;
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
m_CachedTransform = GetComponent<RectTransform>();
|
||||
if (m_CachedTransform == null)
|
||||
_cachedTransform = GetComponent<RectTransform>();
|
||||
if (_cachedTransform == null)
|
||||
{
|
||||
Log.Error("RectTransform is invalid.");
|
||||
return;
|
||||
}
|
||||
|
||||
m_CachedCanvasGroup = GetComponent<CanvasGroup>();
|
||||
if (m_CachedCanvasGroup == null)
|
||||
_cachedCanvasGroup = GetComponent<CanvasGroup>();
|
||||
if (_cachedCanvasGroup == null)
|
||||
{
|
||||
Log.Error("CanvasGroup is invalid.");
|
||||
return;
|
||||
@@ -114,9 +102,9 @@ namespace StarForce
|
||||
|
||||
private IEnumerator HPBarCo(float value, float animationDuration, float keepDuration, float fadeOutDuration)
|
||||
{
|
||||
yield return m_HPBar.SmoothValue(value, animationDuration);
|
||||
yield return _hPBar.SmoothValue(value, animationDuration);
|
||||
yield return new WaitForSeconds(keepDuration);
|
||||
yield return m_CachedCanvasGroup.FadeToAlpha(0f, fadeOutDuration);
|
||||
yield return _cachedCanvasGroup.FadeToAlpha(0f, fadeOutDuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +1,91 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using SepCore.Definition;
|
||||
using SepCore.UI;
|
||||
using UnityEngine;
|
||||
using UnityGameFramework.Runtime;
|
||||
using UI;
|
||||
|
||||
namespace CustomComponent
|
||||
namespace SepCore.CustomComponent
|
||||
{
|
||||
public class UIRouterComponent : GameFrameworkComponent
|
||||
{
|
||||
[Serializable]
|
||||
public class ControllerBinding
|
||||
{
|
||||
[SerializeField] private UIFormType _uiFormType = UIFormType.Undefined;
|
||||
[SerializeField] private string _controllerTypeName;
|
||||
|
||||
public UIFormType UIFormType => _uiFormType;
|
||||
|
||||
public string ControllerTypeName => _controllerTypeName;
|
||||
}
|
||||
|
||||
[SerializeField] private List<ControllerBinding> _controllerBindings = new();
|
||||
|
||||
private readonly Dictionary<UIFormType, IUIFormController> _routeControllers = new();
|
||||
private readonly Dictionary<UIFormType, Func<IUIFormController>> _controllerFactories = new();
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
RegisterSerializedBindings();
|
||||
}
|
||||
|
||||
public void RegisterController(UIFormType uiFormType, Func<IUIFormController> controllerFactory)
|
||||
{
|
||||
if (controllerFactory == null)
|
||||
{
|
||||
Log.Error("UIRouterComponent.RegisterController() controllerFactory is invalid.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_routeControllers.TryGetValue(uiFormType, out IUIFormController controller))
|
||||
{
|
||||
controller.CloseUIAsync().Forget();
|
||||
_routeControllers.Remove(uiFormType);
|
||||
}
|
||||
|
||||
_controllerFactories[uiFormType] = controllerFactory;
|
||||
}
|
||||
|
||||
public void RegisterController<TController>(UIFormType uiFormType)
|
||||
where TController : IUIFormController, new()
|
||||
{
|
||||
RegisterController(uiFormType, () => new TController());
|
||||
}
|
||||
|
||||
public void BindUIUseCase(UIFormType uiFormType, IUIUseCase useCase)
|
||||
{
|
||||
IUIFormController controller = GetOrCreateController(uiFormType);
|
||||
if (controller == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
controller.BindUseCase(useCase);
|
||||
}
|
||||
|
||||
public int? OpenUI(UIFormType uiFormType, object userData = null)
|
||||
public UniTask<int?> OpenUIAsync(UIFormType uiFormType, object userData = null, float timeout = 30f)
|
||||
{
|
||||
IUIFormController controller = GetOrCreateController(uiFormType);
|
||||
return controller.OpenUI(userData);
|
||||
if (controller == null)
|
||||
{
|
||||
return UniTask.FromResult<int?>(null);
|
||||
}
|
||||
|
||||
return controller.OpenUIAsync(userData, timeout);
|
||||
}
|
||||
|
||||
public void CloseUI(UIFormType uiFormType)
|
||||
public UniTask CloseUIAsync(UIFormType uiFormType, object userData = null, float timeout = 30f)
|
||||
{
|
||||
IUIFormController controller = GetOrCreateController(uiFormType);
|
||||
controller.CloseUI();
|
||||
if (controller == null)
|
||||
{
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
|
||||
return controller.CloseUIAsync(userData, timeout);
|
||||
}
|
||||
|
||||
private IUIFormController GetOrCreateController(UIFormType uiFormType)
|
||||
@@ -35,67 +95,82 @@ namespace CustomComponent
|
||||
return controller;
|
||||
}
|
||||
|
||||
string typename = $"UI.{uiFormType}Controller";
|
||||
Type controllerType = Type.GetType(typename);
|
||||
if (controllerType == null)
|
||||
if (!_controllerFactories.TryGetValue(uiFormType, out Func<IUIFormController> controllerFactory))
|
||||
{
|
||||
controller = new DefaultUIFormController(uiFormType);
|
||||
Log.Error("UIRouterComponent requires a controller binding for '{0}'.", uiFormType.ToString());
|
||||
return null;
|
||||
}
|
||||
else
|
||||
|
||||
controller = controllerFactory();
|
||||
if (controller == null)
|
||||
{
|
||||
controller = (IUIFormController)Activator.CreateInstance(controllerType);
|
||||
Log.Error("UIRouterComponent controller factory for '{0}' returned null.", uiFormType.ToString());
|
||||
return null;
|
||||
}
|
||||
|
||||
_routeControllers.Add(uiFormType, controller);
|
||||
return controller;
|
||||
}
|
||||
|
||||
private void RegisterSerializedBindings()
|
||||
{
|
||||
if (_controllerBindings == null || _controllerBindings.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HashSet<UIFormType> seen = new();
|
||||
foreach (ControllerBinding binding in _controllerBindings)
|
||||
{
|
||||
if (binding == null || binding.UIFormType == UIFormType.Undefined ||
|
||||
string.IsNullOrWhiteSpace(binding.ControllerTypeName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!seen.Add(binding.UIFormType))
|
||||
{
|
||||
Log.Warning("UIRouter duplicate binding for '{0}', later one overrides earlier one.",
|
||||
binding.UIFormType.ToString());
|
||||
}
|
||||
|
||||
Type controllerType = Type.GetType(binding.ControllerTypeName);
|
||||
if (controllerType == null)
|
||||
{
|
||||
Log.Warning("UIRouter binding type not found: {0}", binding.ControllerTypeName);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!typeof(IUIFormController).IsAssignableFrom(controllerType))
|
||||
{
|
||||
Log.Warning("UIRouter binding type '{0}' does not implement IUIFormController.",
|
||||
binding.ControllerTypeName);
|
||||
continue;
|
||||
}
|
||||
|
||||
RegisterController(binding.UIFormType, () => CreateController(controllerType));
|
||||
}
|
||||
}
|
||||
|
||||
private static IUIFormController CreateController(Type controllerType)
|
||||
{
|
||||
object instance = Activator.CreateInstance(controllerType);
|
||||
if (instance is IUIFormController controller)
|
||||
{
|
||||
return controller;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
foreach (KeyValuePair<UIFormType, IUIFormController> pair in _routeControllers)
|
||||
{
|
||||
pair.Value.CloseUI();
|
||||
pair.Value.CloseUIAsync().Forget();
|
||||
}
|
||||
|
||||
_routeControllers.Clear();
|
||||
}
|
||||
|
||||
private class DefaultUIFormController : IUIFormController
|
||||
{
|
||||
private readonly UIFormType _uiFormType;
|
||||
private int? _lastSerialId;
|
||||
|
||||
public DefaultUIFormController(UIFormType uiFormType)
|
||||
{
|
||||
_uiFormType = uiFormType;
|
||||
}
|
||||
|
||||
public int? OpenUI(object userData = null)
|
||||
{
|
||||
_lastSerialId = GameEntry.UI.OpenUIForm(_uiFormType, userData);
|
||||
return _lastSerialId;
|
||||
}
|
||||
|
||||
public void CloseUI()
|
||||
{
|
||||
if (_lastSerialId.HasValue)
|
||||
{
|
||||
GameEntry.UI.CloseUIForm(_lastSerialId.Value);
|
||||
_lastSerialId = null;
|
||||
return;
|
||||
}
|
||||
|
||||
UGuiForm uiForm = GameEntry.UI.GetUIForm(_uiFormType);
|
||||
if (uiForm != null)
|
||||
{
|
||||
GameEntry.UI.CloseUIForm(uiForm);
|
||||
}
|
||||
}
|
||||
|
||||
public void BindUseCase(IUIUseCase useCase)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b3695ff420be99d44ab812d7e1863044
|
||||
guid: 8e8c4ca7b7a670745a789c67ac6c8e40
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
|
||||
Reference in New Issue
Block a user