Files
WhaleAdventure_VR/Assets/My project/Fishing Scripts/UI/FishingUIEffects.cs
2026-06-25 17:39:42 +09:00

362 lines
11 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class FishingUIEffects : MonoBehaviour
{
private readonly Dictionary<Object, Coroutine> runningEffects = new Dictionary<Object, Coroutine>();
private readonly Dictionary<Transform, Vector3> originalScales = new Dictionary<Transform, Vector3>();
private readonly Dictionary<RectTransform, Vector2> originalAnchoredPositions = new Dictionary<RectTransform, Vector2>();
public CanvasGroup EnsureCanvasGroup(GameObject target)
{
if (target == null)
return null;
CanvasGroup group = target.GetComponent<CanvasGroup>();
if (group == null)
group = target.AddComponent<CanvasGroup>();
return group;
}
public void SetCanvasGroupInstant(GameObject target, CanvasGroup group, bool visible)
{
if (target == null && group == null)
return;
if (target != null)
target.SetActive(visible);
if (group != null)
{
group.alpha = visible ? 1f : 0f;
group.interactable = visible;
group.blocksRaycasts = visible;
}
}
public void FadeCanvasGroup(GameObject target, CanvasGroup group, bool visible, float duration)
{
if (target == null && group == null)
return;
if (group == null && target != null)
group = EnsureCanvasGroup(target);
if (group == null)
{
if (target != null)
target.SetActive(visible);
return;
}
StopManaged(group);
runningEffects[group] = StartCoroutine(FadeCanvasGroupRoutine(target, group, visible, Mathf.Max(0f, duration)));
}
private IEnumerator FadeCanvasGroupRoutine(GameObject target, CanvasGroup group, bool visible, float duration)
{
if (target != null && visible)
target.SetActive(true);
group.interactable = visible;
group.blocksRaycasts = visible;
float startAlpha = group.alpha;
float endAlpha = visible ? 1f : 0f;
if (duration <= 0f)
{
group.alpha = endAlpha;
}
else
{
float timer = 0f;
while (timer < duration)
{
timer += Time.deltaTime;
float t = Mathf.Clamp01(timer / duration);
t = EaseOutCubic(t);
group.alpha = Mathf.Lerp(startAlpha, endAlpha, t);
yield return null;
}
group.alpha = endAlpha;
}
if (target != null && !visible)
target.SetActive(false);
runningEffects.Remove(group);
}
public void Pop(Transform target, float peakScale = 1.12f, float duration = 0.18f)
{
if (target == null)
return;
StopManaged(target);
runningEffects[target] = StartCoroutine(PopRoutine(target, Mathf.Max(1f, peakScale), Mathf.Max(0.01f, duration)));
}
private IEnumerator PopRoutine(Transform target, float peakScale, float duration)
{
if (!originalScales.TryGetValue(target, out Vector3 originalScale))
{
originalScale = target.localScale;
originalScales[target] = originalScale;
}
float half = duration * 0.5f;
float timer = 0f;
while (timer < half)
{
timer += Time.deltaTime;
float t = Mathf.Clamp01(timer / half);
target.localScale = Vector3.Lerp(originalScale, originalScale * peakScale, EaseOutCubic(t));
yield return null;
}
timer = 0f;
Vector3 peak = originalScale * peakScale;
while (timer < half)
{
timer += Time.deltaTime;
float t = Mathf.Clamp01(timer / half);
target.localScale = Vector3.Lerp(peak, originalScale, EaseOutCubic(t));
yield return null;
}
target.localScale = originalScale;
runningEffects.Remove(target);
}
public void Shake(RectTransform target, float strength = 12f, float duration = 0.18f)
{
if (target == null)
return;
StopManaged(target);
runningEffects[target] = StartCoroutine(ShakeRoutine(target, Mathf.Max(0f, strength), Mathf.Max(0.01f, duration)));
}
private IEnumerator ShakeRoutine(RectTransform target, float strength, float duration)
{
if (!originalAnchoredPositions.TryGetValue(target, out Vector2 originalPosition))
{
originalPosition = target.anchoredPosition;
originalAnchoredPositions[target] = originalPosition;
}
float timer = 0f;
while (timer < duration)
{
timer += Time.deltaTime;
float t = Mathf.Clamp01(timer / duration);
float power = Mathf.Lerp(strength, 0f, t);
Vector2 offset = UnityEngine.Random.insideUnitCircle * power;
target.anchoredPosition = originalPosition + offset;
yield return null;
}
target.anchoredPosition = originalPosition;
runningEffects.Remove(target);
}
public void Flash(Image image, Color color, float maxAlpha = 0.28f, float duration = 0.16f)
{
if (image == null)
return;
StopManaged(image);
runningEffects[image] = StartCoroutine(FlashRoutine(image, color, Mathf.Clamp01(maxAlpha), Mathf.Max(0.01f, duration)));
}
private IEnumerator FlashRoutine(Image image, Color color, float maxAlpha, float duration)
{
image.gameObject.SetActive(true);
image.raycastTarget = false;
float timer = 0f;
while (timer < duration)
{
timer += Time.deltaTime;
float t = Mathf.Clamp01(timer / duration);
Color current = color;
current.a = Mathf.Lerp(maxAlpha, 0f, EaseOutCubic(t));
image.color = current;
yield return null;
}
Color clear = color;
clear.a = 0f;
image.color = clear;
image.gameObject.SetActive(false);
runningEffects.Remove(image);
}
public void FillImage(Image image, float targetFill, float duration)
{
if (image == null)
return;
targetFill = Mathf.Clamp01(targetFill);
StopManaged(image);
runningEffects[image] = StartCoroutine(FillImageRoutine(image, targetFill, Mathf.Max(0f, duration)));
}
private IEnumerator FillImageRoutine(Image image, float targetFill, float duration)
{
float startFill = image.fillAmount;
if (duration <= 0f)
{
image.fillAmount = targetFill;
}
else
{
float timer = 0f;
while (timer < duration)
{
timer += Time.deltaTime;
float t = Mathf.Clamp01(timer / duration);
image.fillAmount = Mathf.Lerp(startFill, targetFill, EaseOutCubic(t));
yield return null;
}
image.fillAmount = targetFill;
}
runningEffects.Remove(image);
}
public void HighlightSlot(Image background, Image icon, Transform slotRoot, Color highlightColor, float duration, float popScale)
{
Object key = background != null ? background : icon != null ? icon : slotRoot;
if (key == null)
return;
StopManaged(key);
runningEffects[key] = StartCoroutine(HighlightSlotRoutine(background, icon, slotRoot, highlightColor, Mathf.Max(0.01f, duration), Mathf.Max(1f, popScale), key));
}
private IEnumerator HighlightSlotRoutine(Image background, Image icon, Transform slotRoot, Color highlightColor, float duration, float popScale, Object key)
{
Color? originalBackground = null;
Color? originalIcon = null;
Vector3 originalScale = Vector3.one;
if (background != null)
{
originalBackground = background.color;
Color c = Color.Lerp(background.color, highlightColor, 0.65f);
c.a = 1f;
background.color = c;
}
if (icon != null)
{
originalIcon = icon.color;
Color c = icon.color;
c.a = 1f;
icon.color = c;
}
if (slotRoot != null)
{
if (!originalScales.TryGetValue(slotRoot, out originalScale))
{
originalScale = slotRoot.localScale;
originalScales[slotRoot] = originalScale;
}
}
float half = duration * 0.5f;
float timer = 0f;
while (timer < half)
{
timer += Time.deltaTime;
float t = Mathf.Clamp01(timer / half);
if (slotRoot != null)
slotRoot.localScale = Vector3.Lerp(originalScale, originalScale * popScale, EaseOutCubic(t));
yield return null;
}
timer = 0f;
Vector3 peak = originalScale * popScale;
while (timer < half)
{
timer += Time.deltaTime;
float t = Mathf.Clamp01(timer / half);
if (slotRoot != null)
slotRoot.localScale = Vector3.Lerp(peak, originalScale, EaseOutCubic(t));
if (background != null && originalBackground.HasValue)
background.color = Color.Lerp(background.color, originalBackground.Value, t);
if (icon != null && originalIcon.HasValue)
icon.color = Color.Lerp(icon.color, originalIcon.Value, t);
yield return null;
}
if (slotRoot != null)
slotRoot.localScale = originalScale;
if (background != null && originalBackground.HasValue)
background.color = originalBackground.Value;
if (icon != null && originalIcon.HasValue)
icon.color = originalIcon.Value;
runningEffects.Remove(key);
}
public void StopAllEffects()
{
foreach (Coroutine coroutine in runningEffects.Values)
{
if (coroutine != null)
StopCoroutine(coroutine);
}
runningEffects.Clear();
foreach (KeyValuePair<Transform, Vector3> pair in originalScales)
{
if (pair.Key != null)
pair.Key.localScale = pair.Value;
}
foreach (KeyValuePair<RectTransform, Vector2> pair in originalAnchoredPositions)
{
if (pair.Key != null)
pair.Key.anchoredPosition = pair.Value;
}
}
private void StopManaged(Object key)
{
if (key == null)
return;
if (runningEffects.TryGetValue(key, out Coroutine coroutine) && coroutine != null)
StopCoroutine(coroutine);
runningEffects.Remove(key);
}
private float EaseOutCubic(float t)
{
t = Mathf.Clamp01(t);
t = 1f - Mathf.Pow(1f - t, 3f);
return t;
}
}