using UnityEngine; using System.Collections; /// /// Utility class for common animation coroutines and animation helpers. /// Provides reusable animation patterns used across multiple scripts. /// public static class AnimationUtilities { /// /// Smoothly rotate an object from its current rotation to a target rotation /// public static Coroutine RotateTo(MonoBehaviour source, Transform target, Quaternion targetRotation, float duration) { return source.StartCoroutine(RotateToRoutine(target, targetRotation, duration)); } private static IEnumerator RotateToRoutine(Transform target, Quaternion targetRotation, float duration) { if (duration <= 0) yield break; float elapsedTime = 0f; Quaternion startRotation = target.rotation; while (elapsedTime < duration) { elapsedTime += Time.deltaTime; float t = Mathf.Clamp01(elapsedTime / duration); target.rotation = Quaternion.Slerp(startRotation, targetRotation, t); yield return null; } target.rotation = targetRotation; } /// /// Smoothly move an object from its current position to a target position /// public static Coroutine MoveTo(MonoBehaviour source, Transform target, Vector3 targetPosition, float duration) { return source.StartCoroutine(MoveToRoutine(target, targetPosition, duration)); } private static IEnumerator MoveToRoutine(Transform target, Vector3 targetPosition, float duration) { if (duration <= 0) yield break; float elapsedTime = 0f; Vector3 startPosition = target.position; while (elapsedTime < duration) { elapsedTime += Time.deltaTime; float t = Mathf.Clamp01(elapsedTime / duration); target.position = Vector3.Lerp(startPosition, targetPosition, t); yield return null; } target.position = targetPosition; } /// /// Smoothly rotate an object around a specific axis by a specified angle /// public static Coroutine RotateAround(MonoBehaviour source, Transform target, float targetAngle, Vector3 axis, float duration) { return source.StartCoroutine(RotateAroundRoutine(target, targetAngle, axis, duration)); } private static IEnumerator RotateAroundRoutine(Transform target, float targetAngle, Vector3 axis, float duration) { if (duration <= 0) yield break; float elapsedTime = 0f; Vector3 eulerAngles = target.localEulerAngles; float startAngle = 0; if (axis == Vector3.right) startAngle = eulerAngles.x; else if (axis == Vector3.up) startAngle = eulerAngles.y; else if (axis == Vector3.forward) startAngle = eulerAngles.z; while (elapsedTime < duration) { elapsedTime += Time.deltaTime; float t = Mathf.Clamp01(elapsedTime / duration); float currentAngle = Mathf.Lerp(startAngle, targetAngle, t); eulerAngles = target.localEulerAngles; if (axis == Vector3.right) eulerAngles.x = currentAngle; else if (axis == Vector3.up) eulerAngles.y = currentAngle; else if (axis == Vector3.forward) eulerAngles.z = currentAngle; target.localEulerAngles = eulerAngles; yield return null; } eulerAngles = target.localEulerAngles; if (axis == Vector3.right) eulerAngles.x = targetAngle; else if (axis == Vector3.up) eulerAngles.y = targetAngle; else if (axis == Vector3.forward) eulerAngles.z = targetAngle; target.localEulerAngles = eulerAngles; } /// /// Fade in/out by modifying material color alpha /// public static Coroutine Fade(MonoBehaviour source, Renderer renderer, float targetAlpha, float duration) { return source.StartCoroutine(FadeRoutine(renderer, targetAlpha, duration)); } private static IEnumerator FadeRoutine(Renderer renderer, float targetAlpha, float duration) { if (renderer == null || duration <= 0) yield break; float elapsedTime = 0f; Material material = renderer.material; Color startColor = material.color; while (elapsedTime < duration) { elapsedTime += Time.deltaTime; float t = Mathf.Clamp01(elapsedTime / duration); Color newColor = startColor; newColor.a = Mathf.Lerp(startColor.a, targetAlpha, t); material.color = newColor; yield return null; } Color finalColor = startColor; finalColor.a = targetAlpha; material.color = finalColor; } }