Danro/Assets/Scripts/Entities/VanishingPlatform.cs

203 lines
7.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections;
using UnityEngine;
public class VanishingPlatform : MonoBehaviour
{
[Header("Настройки исчезновения платформы")]
[SerializeField] private float vanishDuration = 0.5f;
[SerializeField] private float reappearDelay = 2f;
[SerializeField] private float reappearDuration = 0.5f;
private CompositeCollider2D _compositeCollider;
private Rigidbody2D _rigidbody;
private SpriteRenderer[] _spriteRenderers;
private Coroutine _vanishCoroutine;
private Coroutine _reappearCoroutine;
private Color[] _initialColors;
private void Awake()
{
_compositeCollider = GetComponent<CompositeCollider2D>();
_rigidbody = GetComponent<Rigidbody2D>();
_spriteRenderers = GetComponentsInChildren<SpriteRenderer>();
if (_compositeCollider == null)
Debug.LogWarning($"[{nameof(VanishingPlatform)}] CompositeCollider2D не найден на {gameObject.name}.");
if (_rigidbody == null)
Debug.LogWarning($"[{nameof(VanishingPlatform)}] Rigidbody2D не найден на {gameObject.name}. CompositeCollider2D требует Rigidbody2D.");
if (_spriteRenderers == null || _spriteRenderers.Length == 0)
Debug.LogWarning($"[{nameof(VanishingPlatform)}] SpriteRenderer'ы не найдены на {gameObject.name} и его дочерних объектах.");
}
private void OnCollisionEnter2D(Collision2D other)
{
if (!other.gameObject.CompareTag("Player")) return;
// Если в процессе была корутина Reappear — её отменяем
if (_reappearCoroutine != null)
{
StopCoroutine(_reappearCoroutine);
_reappearCoroutine = null;
}
if (_vanishCoroutine != null)
StopCoroutine(_vanishCoroutine);
_vanishCoroutine = StartCoroutine(Vanish());
}
private void OnCollisionExit2D(Collision2D other)
{
if (!other.gameObject.CompareTag("Player")) return;
// Если в процессе была корутина Vanish — её отменяем
if (_vanishCoroutine != null)
{
StopCoroutine(_vanishCoroutine);
_vanishCoroutine = null;
}
if (_reappearCoroutine != null)
StopCoroutine(_reappearCoroutine);
_reappearCoroutine = StartCoroutine(Reappear());
}
private IEnumerator Vanish()
{
if (_spriteRenderers == null || _spriteRenderers.Length == 0)
yield break; // нечего анимировать
// Сохраняем начальные цвета для всех рендереров (если ещё не сохранены)
if (_initialColors == null || _initialColors.Length != _spriteRenderers.Length)
{
_initialColors = new Color[_spriteRenderers.Length];
for (int i = 0; i < _spriteRenderers.Length; i++)
_initialColors[i] = _spriteRenderers[i].color;
}
// Запоминаем текущую альфу для каждого рендерера
float[] startAlphas = new float[_spriteRenderers.Length];
for (int i = 0; i < _spriteRenderers.Length; i++)
startAlphas[i] = _spriteRenderers[i].color.a;
float elapsed = 0f;
while (elapsed < vanishDuration)
{
elapsed += Time.deltaTime;
float t = vanishDuration > 0f ? Mathf.Clamp01(elapsed / vanishDuration) : 1f;
for (int i = 0; i < _spriteRenderers.Length; i++)
{
Color c = _initialColors[i];
float alpha = Mathf.Lerp(startAlphas[i], 0f, t);
_spriteRenderers[i].color = new Color(c.r, c.g, c.b, alpha);
}
yield return null;
}
// Принудительно установить 0 альфу
for (int i = 0; i < _spriteRenderers.Length; i++)
{
Color c = _initialColors[i];
_spriteRenderers[i].color = new Color(c.r, c.g, c.b, 0f);
}
// Отключаем физику через Rigidbody2D.simulated, что отключает и CompositeCollider2D
if (_rigidbody)
_rigidbody.simulated = false;
_vanishCoroutine = null;
}
private IEnumerator Reappear()
{
if (_spriteRenderers == null || _spriteRenderers.Length == 0)
yield break; // нечего анимировать
// Убедимся, что у нас есть базовые цвета — если нет, прочитаем текущие
if (_initialColors == null || _initialColors.Length != _spriteRenderers.Length)
{
_initialColors = new Color[_spriteRenderers.Length];
for (int i = 0; i < _spriteRenderers.Length; i++)
_initialColors[i] = _spriteRenderers[i].color;
}
// Задержка перед появлением (как в предыдущей логике)
yield return new WaitForSeconds(reappearDelay);
// Запоминаем текущую альфу для каждого рендерера
float[] startAlphas = new float[_spriteRenderers.Length];
for (int i = 0; i < _spriteRenderers.Length; i++)
startAlphas[i] = _spriteRenderers[i].color.a;
float elapsed = 0f;
while (elapsed < reappearDuration)
{
elapsed += Time.deltaTime;
float t = reappearDuration > 0f ? Mathf.Clamp01(elapsed / reappearDuration) : 1f;
for (int i = 0; i < _spriteRenderers.Length; i++)
{
Color c = _initialColors[i];
float alpha = Mathf.Lerp(startAlphas[i], 1f, t);
_spriteRenderers[i].color = new Color(c.r, c.g, c.b, alpha);
}
yield return null;
}
// Принудительно установить полную непрозрачность
for (int i = 0; i < _spriteRenderers.Length; i++)
{
Color c = _initialColors[i];
_spriteRenderers[i].color = new Color(c.r, c.g, c.b, 1f);
}
// Включаем физику обратно
if (_rigidbody)
_rigidbody.simulated = true;
_reappearCoroutine = null;
}
/// <summary>
/// Внешний метод для немедленного запуска анимации исчезновения (например, вызов из других скриптов).
/// </summary>
public void TriggerVanish()
{
if (_reappearCoroutine != null)
{
StopCoroutine(_reappearCoroutine);
_reappearCoroutine = null;
}
if (_vanishCoroutine != null)
StopCoroutine(_vanishCoroutine);
_vanishCoroutine = StartCoroutine(Vanish());
}
/// <summary>
/// Внешний метод для немедленного запуска анимации появления (например, вызов из других скриптов).
/// </summary>
public void TriggerReappear()
{
if (_vanishCoroutine != null)
{
StopCoroutine(_vanishCoroutine);
_vanishCoroutine = null;
}
if (_reappearCoroutine != null)
StopCoroutine(_reappearCoroutine);
_reappearCoroutine = StartCoroutine(Reappear());
}
}