140 lines
4.0 KiB
C#
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;
|
|
}
|
|
} |