Files
Ipseity-Demo/Assets/Unheimlich_POC/Scripts/Handlers/Interactions/FloatingWords/SketchFadeEffect.cs
T
2026-01-30 17:39:26 +01:00

206 lines
7.7 KiB
C#

using UnityEngine;
using UnityEngine.UI;
using TMPro;
using Unheimlich.Utility;
namespace Unheimlich.Interactions.FloatingWords
{
public class SketchFadeEffect : MonoBehaviour
{
private TextMeshProUGUI _textComponent;
private TextMeshProUGUI _ghostTextComponent;
private Image _scribbleOverlay;
private Material _scribbleMaterialInstance;
private Material _scribbleMaterialTemplate;
private static readonly int ProgressID = Shader.PropertyToID("_Progress");
private bool _isEffectActive = false;
private bool _overlayCreated = false;
private Color _originalTextColor;
private Color _originalGhostColor;
private int _scribbleTweenId = -1;
private int _fadeTweenId = -1;
public void Initialize(TextMeshProUGUI textComponent, TextMeshProUGUI ghostComponent, Material scribbleMaterial)
{
_textComponent = textComponent;
_ghostTextComponent = ghostComponent;
_scribbleMaterialTemplate = scribbleMaterial;
_originalTextColor = _textComponent.color;
if (_ghostTextComponent != null)
_originalGhostColor = _ghostTextComponent.color;
}
private void CreateScribbleOverlay()
{
if (_overlayCreated || _scribbleMaterialTemplate == null || _textComponent == null)
return;
GameObject overlayObject = new GameObject("ScribbleOverlay");
overlayObject.transform.SetParent(_textComponent.transform, false);
_scribbleOverlay = overlayObject.AddComponent<Image>();
_scribbleOverlay.raycastTarget = false;
RectTransform overlayRect = overlayObject.GetComponent<RectTransform>();
RectTransform textRect = _textComponent.GetComponent<RectTransform>();
_textComponent.ForceMeshUpdate();
Vector2 textSize = _textComponent.GetRenderedValues(false);
float horizontalPadding = 1.2f;
float verticalPadding = 0.8f;
Vector2 paddedSize = new Vector2(
textSize.x + horizontalPadding,
textSize.y + verticalPadding
);
overlayRect.anchorMin = new Vector2(0.5f, 0.5f);
overlayRect.anchorMax = new Vector2(0.5f, 0.5f);
overlayRect.pivot = new Vector2(0.5f, 0.5f);
float leftOffset = -horizontalPadding * 0.9f;
overlayRect.anchoredPosition = new Vector2(leftOffset, 0f);
overlayRect.sizeDelta = paddedSize;
overlayRect.localScale = Vector3.one;
_scribbleMaterialInstance = new Material(_scribbleMaterialTemplate);
_scribbleMaterialInstance.SetFloat(ProgressID, 0f);
_scribbleOverlay.material = _scribbleMaterialInstance;
_scribbleOverlay.gameObject.SetActive(false);
_overlayCreated = true;
}
public void PlaySketchFadeEffect(float scribbleDuration, float fadeDuration, float finalAlpha)
{
if (_isEffectActive || _textComponent == null)
return;
CancelActiveTweens();
CreateScribbleOverlay();
if (_scribbleOverlay == null || _scribbleMaterialInstance == null)
return;
_scribbleOverlay.gameObject.SetActive(true);
_isEffectActive = true;
_scribbleTweenId = TweenHelper.AnimateMaterialFloat(
gameObject,
_scribbleMaterialInstance,
ProgressID,
0f,
1f,
scribbleDuration,
() => {
_scribbleTweenId = -1;
float ghostAlphaRatio = _ghostTextComponent != null ? (_originalGhostColor.a / _originalTextColor.a) : 0f;
_fadeTweenId = LeanTween.value(gameObject, _originalTextColor.a, finalAlpha, fadeDuration)
.setEase(LeanTweenType.easeInQuad)
.setOnUpdate((float val) => {
if (_textComponent != null)
{
_textComponent.color = _textComponent.color.WithAlpha(val);
}
if (_ghostTextComponent != null)
{
_ghostTextComponent.color = _ghostTextComponent.color.WithAlpha(val * ghostAlphaRatio);
}
if (_scribbleOverlay != null)
{
_scribbleOverlay.color = _scribbleOverlay.color.WithAlpha(val);
}
})
.setOnComplete(() => {
_fadeTweenId = -1;
}).id;
},
LeanTweenType.easeInOutQuad);
}
public void ResetEffect()
{
CancelActiveTweens();
if (_scribbleMaterialInstance != null)
{
float currentProgress = _scribbleMaterialInstance.GetFloat(ProgressID);
if (currentProgress > 0f)
{
_scribbleTweenId = TweenHelper.AnimateMaterialFloat(
gameObject,
_scribbleMaterialInstance,
ProgressID,
currentProgress,
0f,
0.3f,
() => {
_scribbleTweenId = -1;
if (_scribbleOverlay != null)
_scribbleOverlay.gameObject.SetActive(false);
},
LeanTweenType.easeOutQuad);
}
}
if (_textComponent != null)
{
float currentAlpha = _textComponent.color.a;
if (currentAlpha < _originalTextColor.a)
{
float ghostAlphaRatio = _ghostTextComponent != null ? (_originalGhostColor.a / _originalTextColor.a) : 0f;
_fadeTweenId = TweenHelper.FadeText(
gameObject,
_textComponent,
_ghostTextComponent,
_originalTextColor.a,
0.3f,
ghostAlphaRatio,
() => { _fadeTweenId = -1; },
LeanTweenType.easeOutQuad);
}
}
if (_scribbleOverlay != null)
{
_scribbleOverlay.color = _scribbleOverlay.color.WithAlpha(1f);
}
_isEffectActive = false;
}
private void CancelActiveTweens()
{
TweenHelper.CancelTween(ref _scribbleTweenId);
TweenHelper.CancelTween(ref _fadeTweenId);
}
private void OnDestroy()
{
CancelActiveTweens();
if (_scribbleMaterialInstance != null)
Destroy(_scribbleMaterialInstance);
if (_scribbleOverlay != null)
Destroy(_scribbleOverlay.gameObject);
}
}
}