106 lines
3.4 KiB
C#

using UnityEngine;
using Cysharp.Threading.Tasks;
using System.Threading;
public class WaterLens : MonoBehaviour
{
[Header("Настройки анимации")]
[SerializeField] private Material targetMaterial;
[SerializeField] private Texture2D[] textures;
[SerializeField] private float framesDuration = 1f; // Время прокрутки всех кадров
[SerializeField] private float fadeOutDuration = 1.5f; // Время снижения alpha
[SerializeField][Range(0f, 1f)] private float startAlpha = 0.1f;
//[SerializeField] private string alphaPropertyName = "_Alpha";
[SerializeField] Vector3 localOffset = new Vector3(0f, 0f, 1.6f);
private CancellationTokenSource cancellationToken;
private float timePerFrame;
private Color originalColor;
private void Start()
{
G.PlayerStateModel.PlayerComponent.DiveSystem.Surfaced += start;
}
public void start()
{
PlayAnimation().Forget();
}
private void Awake()
{
// Сохраняем исходный цвет материала
if (targetMaterial != null)
{
originalColor = targetMaterial.color;
Color startColor = originalColor;
startColor.a = 0;
targetMaterial.color = startColor;
}
}
private void LateUpdate()
{
transform.parent = CamerasManager.VR_Camera.transform;
transform.localPosition = localOffset;
transform.localRotation = Quaternion.Euler(-90, 0, 0);
}
/// <summary>
/// Запустить анимацию воды
/// </summary>
public async UniTask PlayAnimation(CancellationToken token = default)
{
// Отменяем предыдущую анимацию
cancellationToken?.Cancel();
cancellationToken = CancellationTokenSource.CreateLinkedTokenSource(token);
var ct = cancellationToken.Token;
// Расчет времени на один кадр
timePerFrame = framesDuration / textures.Length;
// Получаем текущий цвет материала
Color currentColor = targetMaterial.color;
currentColor.a = startAlpha;
targetMaterial.color = currentColor;
// Проигрываем все кадры
for (int i = 0; i < textures.Length; i++)
{
ct.ThrowIfCancellationRequested();
targetMaterial.SetTexture("_BumpMap", textures[i]);
await UniTask.Delay((int)(timePerFrame * 1000), DelayType.DeltaTime, cancellationToken: ct);
}
// Плавно уменьшаем альфу до 0
float elapsed = 0f;
float startAlphaValue = startAlpha;
while (elapsed < fadeOutDuration)
{
ct.ThrowIfCancellationRequested();
elapsed += Time.deltaTime;
float alpha = Mathf.Lerp(startAlphaValue, 0f, elapsed / fadeOutDuration);
Color color = targetMaterial.color;
color.a = alpha;
targetMaterial.color = color;
await UniTask.Yield(ct);
}
// Фиксируем альфу = 0
Color finalColor = targetMaterial.color;
finalColor.a = 0f;
targetMaterial.color = finalColor;
}
private void OnDestroy()
{
if (G.PlayerStateModel != null)
G.PlayerStateModel.PlayerComponent.DiveSystem.Surfaced -= start;
cancellationToken?.Cancel();
}
}