using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using Cysharp.Threading.Tasks; using System.Threading; public class VrReloadView : MonoBehaviour { [SerializeField] private List 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; } }