using System; using System.Collections; using Sirenix.OdinInspector; using UnityEngine; namespace BlueWater { public class FadeableObject : MonoBehaviour { [field: SerializeField] public bool IsFadeable { get; private set; } [SerializeField, ShowIf("@IsFadeable")] private Material _transparentMaterial; [SerializeField, Range(0f, 1f), ShowIf("@IsFadeable")] private float _transparency; [SerializeField, Range(0f, 2f), ShowIf("@IsFadeable")] private float _fadeDuration = 0.5f; private Renderer _currentRenderer; private Material _originalMaterial; private Material _newMaterial; private Coroutine _currentCoroutine; private bool _isTransparent; private void Start() { if (!IsFadeable) return; _currentRenderer = GetComponentInChildren(); _originalMaterial = _currentRenderer.material; _newMaterial = new Material(_transparentMaterial); } private void OnDestroy() { StopAllCoroutines(); } public void SetTransparent() { if (_isTransparent) return; if (_currentCoroutine != null) { StopCoroutine(_currentCoroutine); } _currentCoroutine = StartCoroutine(FadeToTransparent()); } public void RestoreOriginal() { if (!_isTransparent) return; if (_currentCoroutine != null) { StopCoroutine(_currentCoroutine); } _currentCoroutine = StartCoroutine(RestoreMaterial()); } private IEnumerator FadeToTransparent() { _isTransparent = true; _currentRenderer.material = _newMaterial; var startAlpha = _currentRenderer.material.color.a; var duration = _fadeDuration * Mathf.Abs(startAlpha - _transparency); var elapsedTime = 0f; while (elapsedTime < duration) { var alpha = Mathf.Lerp(startAlpha, _transparency, elapsedTime / duration); var color = _currentRenderer.material.color; color.a = alpha; _currentRenderer.material.color = color; elapsedTime += Time.deltaTime; yield return null; } var finalColor = _currentRenderer.material.color; finalColor.a = _transparency; _currentRenderer.material.color = finalColor; } private IEnumerator RestoreMaterial() { _isTransparent = false; var startAlpha = _currentRenderer.material.color.a; var targetAlpha = _originalMaterial.color.a; var duration = _fadeDuration * Mathf.Abs(startAlpha - targetAlpha); var elapsedTime = 0f; while (elapsedTime < duration) { var alpha = Mathf.Lerp(startAlpha, targetAlpha, elapsedTime / duration); var color = _currentRenderer.material.color; color.a = alpha; _currentRenderer.material.color = color; elapsedTime += Time.deltaTime; yield return null; } _currentRenderer.material = _originalMaterial; } } }