312 lines
9.0 KiB
C#
312 lines
9.0 KiB
C#
using DG.Tweening;
|
|
using Event;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using UnityGameFramework.Runtime;
|
|
|
|
namespace UI
|
|
{
|
|
public class BgForm : UGuiForm
|
|
{
|
|
[SerializeField] private Image _bgImage;
|
|
[SerializeField] private Image _fadeMaskImage;
|
|
[SerializeField] private float _fadeToBlackDuration = 0.2f;
|
|
[SerializeField] private float _fadeFromBlackDuration = 0.25f;
|
|
[SerializeField] private Ease _fadeEase = Ease.Linear;
|
|
|
|
private Sprite _currentSprite;
|
|
private string _currentAssetName = string.Empty;
|
|
private Tween _fadeTween;
|
|
private int _refreshVersion;
|
|
|
|
protected override void OnOpen(object userData)
|
|
{
|
|
base.OnOpen(userData);
|
|
|
|
if (!(userData is BgFormContext context))
|
|
{
|
|
Log.Error("BgFormContext is invalid.");
|
|
return;
|
|
}
|
|
|
|
RefreshUI(context);
|
|
}
|
|
|
|
protected override void OnClose(bool isShutdown, object userData)
|
|
{
|
|
_refreshVersion++;
|
|
KillFadeTween();
|
|
SetFadeMaskAlpha(0f);
|
|
|
|
_currentSprite = null;
|
|
_currentAssetName = string.Empty;
|
|
if (_bgImage != null)
|
|
{
|
|
_bgImage.sprite = null;
|
|
}
|
|
|
|
base.OnClose(isShutdown, userData);
|
|
}
|
|
|
|
public void RefreshUI(BgFormContext context)
|
|
{
|
|
if (context == null)
|
|
{
|
|
Log.Warning("BgForm refresh failed. context is null.");
|
|
return;
|
|
}
|
|
|
|
int requestId = context.TransitionRequestId;
|
|
bool shouldFadeTransition = _currentSprite != null;
|
|
|
|
if (context.Sprite != null)
|
|
{
|
|
RefreshWithSprite(context.Sprite, context.BackgroundAssetName, requestId);
|
|
return;
|
|
}
|
|
|
|
string targetAssetName = string.IsNullOrWhiteSpace(context.BackgroundAssetName)
|
|
? string.Empty
|
|
: context.BackgroundAssetName.Trim();
|
|
if (string.IsNullOrEmpty(targetAssetName))
|
|
{
|
|
PublishTransitionCompleted(requestId);
|
|
return;
|
|
}
|
|
|
|
if (_currentSprite != null && string.Equals(_currentAssetName, targetAssetName))
|
|
{
|
|
PublishTransitionCompleted(requestId);
|
|
return;
|
|
}
|
|
|
|
if (GameEntry.SpriteCache == null)
|
|
{
|
|
Log.Warning("BgForm refresh failed. SpriteCache is missing.");
|
|
PublishTransitionCompleted(requestId);
|
|
return;
|
|
}
|
|
|
|
int version = ++_refreshVersion;
|
|
TweenCallback loadAndApplySprite = () =>
|
|
{
|
|
if (version != _refreshVersion)
|
|
{
|
|
return;
|
|
}
|
|
|
|
GameEntry.SpriteCache.GetSprite(targetAssetName, sprite =>
|
|
{
|
|
if (version != _refreshVersion)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (sprite != null)
|
|
{
|
|
_currentSprite = sprite;
|
|
_currentAssetName = targetAssetName;
|
|
if (_bgImage != null)
|
|
{
|
|
_bgImage.sprite = sprite;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Log.Warning("BgForm refresh failed. Can not load sprite '{0}'.", targetAssetName);
|
|
}
|
|
|
|
if (shouldFadeTransition)
|
|
{
|
|
FadeFromBlack(() => { PublishTransitionCompleted(requestId); });
|
|
}
|
|
else
|
|
{
|
|
PublishTransitionCompleted(requestId);
|
|
}
|
|
});
|
|
};
|
|
|
|
if (shouldFadeTransition)
|
|
{
|
|
FadeToBlack(loadAndApplySprite);
|
|
}
|
|
else
|
|
{
|
|
loadAndApplySprite.Invoke();
|
|
}
|
|
}
|
|
|
|
private void RefreshWithSprite(Sprite sprite, string backgroundAssetName, int requestId)
|
|
{
|
|
if (sprite == null)
|
|
{
|
|
PublishTransitionCompleted(requestId);
|
|
return;
|
|
}
|
|
|
|
bool isSameSprite = _currentSprite == sprite;
|
|
bool hasSameAssetName = !string.IsNullOrEmpty(backgroundAssetName) &&
|
|
string.Equals(_currentAssetName, backgroundAssetName);
|
|
if (isSameSprite && (string.IsNullOrEmpty(backgroundAssetName) || hasSameAssetName))
|
|
{
|
|
PublishTransitionCompleted(requestId);
|
|
return;
|
|
}
|
|
|
|
bool shouldFadeTransition = _currentSprite != null;
|
|
int version = ++_refreshVersion;
|
|
TweenCallback applySprite = () =>
|
|
{
|
|
if (version != _refreshVersion)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_currentSprite = sprite;
|
|
_currentAssetName = string.IsNullOrWhiteSpace(backgroundAssetName)
|
|
? _currentAssetName
|
|
: backgroundAssetName.Trim();
|
|
if (_bgImage != null)
|
|
{
|
|
_bgImage.sprite = sprite;
|
|
}
|
|
|
|
if (shouldFadeTransition)
|
|
{
|
|
FadeFromBlack(() => { PublishTransitionCompleted(requestId); });
|
|
}
|
|
else
|
|
{
|
|
PublishTransitionCompleted(requestId);
|
|
}
|
|
};
|
|
|
|
if (shouldFadeTransition)
|
|
{
|
|
FadeToBlack(applySprite);
|
|
}
|
|
else
|
|
{
|
|
applySprite.Invoke();
|
|
}
|
|
}
|
|
|
|
private void FadeToBlack(TweenCallback onComplete)
|
|
{
|
|
EnsureFadeMask();
|
|
if (_fadeMaskImage == null)
|
|
{
|
|
onComplete?.Invoke();
|
|
return;
|
|
}
|
|
|
|
_fadeMaskImage.transform.SetAsLastSibling();
|
|
KillFadeTween();
|
|
|
|
if (_fadeToBlackDuration <= 0f)
|
|
{
|
|
SetFadeMaskAlpha(1f);
|
|
onComplete?.Invoke();
|
|
return;
|
|
}
|
|
|
|
_fadeTween = _fadeMaskImage.DOFade(1f, _fadeToBlackDuration)
|
|
.SetEase(_fadeEase)
|
|
.OnComplete(onComplete);
|
|
}
|
|
|
|
private void FadeFromBlack(TweenCallback onComplete = null)
|
|
{
|
|
EnsureFadeMask();
|
|
if (_fadeMaskImage == null)
|
|
{
|
|
onComplete?.Invoke();
|
|
return;
|
|
}
|
|
|
|
_fadeMaskImage.transform.SetAsLastSibling();
|
|
KillFadeTween();
|
|
|
|
if (_fadeFromBlackDuration <= 0f)
|
|
{
|
|
SetFadeMaskAlpha(0f);
|
|
onComplete?.Invoke();
|
|
return;
|
|
}
|
|
|
|
_fadeTween = _fadeMaskImage.DOFade(0f, _fadeFromBlackDuration)
|
|
.SetEase(_fadeEase)
|
|
.OnComplete(onComplete);
|
|
}
|
|
|
|
private void EnsureFadeMask()
|
|
{
|
|
if (_fadeMaskImage != null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
RectTransform parentRect = transform as RectTransform;
|
|
if (parentRect == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
GameObject maskObject = new GameObject("BgFadeMask", typeof(RectTransform), typeof(Image));
|
|
maskObject.transform.SetParent(parentRect, false);
|
|
RectTransform maskRect = maskObject.GetComponent<RectTransform>();
|
|
if (maskRect != null)
|
|
{
|
|
maskRect.anchorMin = Vector2.zero;
|
|
maskRect.anchorMax = Vector2.one;
|
|
maskRect.offsetMin = Vector2.zero;
|
|
maskRect.offsetMax = Vector2.zero;
|
|
}
|
|
|
|
_fadeMaskImage = maskObject.GetComponent<Image>();
|
|
if (_fadeMaskImage != null)
|
|
{
|
|
_fadeMaskImage.raycastTarget = false;
|
|
_fadeMaskImage.color = Color.clear;
|
|
}
|
|
}
|
|
|
|
private void KillFadeTween()
|
|
{
|
|
if (_fadeTween == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_fadeTween.Kill();
|
|
_fadeTween = null;
|
|
}
|
|
|
|
private void SetFadeMaskAlpha(float alpha)
|
|
{
|
|
if (_fadeMaskImage == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Color color = _fadeMaskImage.color;
|
|
color.r = 0f;
|
|
color.g = 0f;
|
|
color.b = 0f;
|
|
color.a = Mathf.Clamp01(alpha);
|
|
_fadeMaskImage.color = color;
|
|
}
|
|
|
|
private void PublishTransitionCompleted(int requestId)
|
|
{
|
|
if (requestId <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
GameEntry.Event.Fire(this, BgTransitionCompletedEventArgs.Create(requestId));
|
|
}
|
|
}
|
|
}
|