140 lines
4.0 KiB
C#

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Cysharp.Threading.Tasks;
using System.Threading;
public class VrReloadView : MonoBehaviour
{
[SerializeField] private List<Image> lamps;
[SerializeField] private Color activeColor = Color.green;
[SerializeField] private Color inactiveColor = Color.gray;
//[SerializeField] private float animationSpeed = 2f; // Скорость зажигания лампочек (лампочек/секунду)
private Weapon _weapon;
private bool _isInitialized;
private CancellationTokenSource _animationCts;
public void Initialize(Weapon weapon)
{
// Защита от повторной инициализации
if (_isInitialized)
{
Debug.LogWarning("VrReloadView already initialized!");
return;
}
_weapon = weapon;
if (_weapon != null)
{
_weapon.OnShoot += OnWeaponShoot;
_isInitialized = true;
// Начальное обновление состояния (все лампочки неактивны)
UpdateLamps(0f);
}
else
{
Debug.LogError("VrReloadView: Weapon is null!");
}
}
private void OnWeaponShoot()
{
if (!_isInitialized || _weapon == null)
{
return;
}
// Запускаем анимацию перезарядки
StartReloadAnimation().Forget();
}
private async UniTaskVoid StartReloadAnimation()
{
// Отменяем предыдущую анимацию
if (_animationCts != null)
{
_animationCts.Cancel();
_animationCts.Dispose();
}
_animationCts = new CancellationTokenSource();
try
{
// После выстрела прогресс перезарядки обнуляется
float currentPercent = 0f;
UpdateLamps(currentPercent);
// Анимируем пока перезарядка не завершится
while (currentPercent < 1f && _weapon != null)
{
_animationCts.Token.ThrowIfCancellationRequested();
// Получаем текущий процент перезарядки
currentPercent = _weapon.ReloadPercent;
// Обновляем лампочки
UpdateLamps(currentPercent);
// Ждем следующий кадр
await UniTask.Yield(_animationCts.Token);
}
// Финальное обновление на 100%
UpdateLamps(1f);
}
catch (System.OperationCanceledException)
{
// Анимация отменена
}
finally
{
if (_animationCts != null)
{
_animationCts.Dispose();
_animationCts = null;
}
}
}
private void UpdateLamps(float percent)
{
if (lamps == null || lamps.Count == 0) return;
percent = Mathf.Clamp01(percent);
// Количество лампочек, которые должны гореть
int targetLampsCount = Mathf.RoundToInt(lamps.Count * percent);
targetLampsCount = Mathf.Clamp(targetLampsCount, 0, lamps.Count);
for (int i = 0; i < lamps.Count; i++)
{
if (lamps[i] != null)
{
bool isActive = i < targetLampsCount;
lamps[i].color = isActive ? activeColor : inactiveColor;
}
}
}
private void OnDestroy()
{
if (_isInitialized && _weapon != null)
{
_weapon.OnShoot -= OnWeaponShoot;
}
if (_animationCts != null)
{
_animationCts.Cancel();
_animationCts.Dispose();
_animationCts = null;
}
_isInitialized = false;
_weapon = null;
}
}