using System; using System.Collections; using System.Collections.Generic; using System.Threading; using BITKit; using BITKit.Entities; using BITKit.Tween; using Cysharp.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Net.Project.B.Damage; using Net.Project.B.Health; using Project.B.Entities; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.UI; namespace Net.Project.B.Feel { public class PlayerHealthFeel : MonoBehaviour { [SerializeField] private Image bloodyScreen; [SerializeField] private Volume volume; [SerializeField] private Volume hitVolume; private IEntity _entity; private CancellationTokenSource _hitCts; private Color _initialColor; private async void Start() { if (hitVolume) { hitVolume.weight = 0; } if(bloodyScreen) _initialColor = bloodyScreen.color; SetValue(0); await BITApp.WalkUntilInitialize.Task; var playerFactory = BITApp.ServiceProvider.GetRequiredService(); var healthService = BITApp.ServiceProvider.GetRequiredService(); var damageService = BITApp.ServiceProvider.GetRequiredService(); playerFactory.OnEntityCreated += OnEntityCreated; healthService.OnHealthChanged += OnHealthChanged; if (hitVolume) { damageService.OnDamaged += OnDamaged; } await destroyCancellationToken.WaitUntilCanceled(); healthService.OnHealthChanged -= OnHealthChanged; playerFactory.OnEntityCreated -= OnEntityCreated; damageService.OnDamaged -= OnDamaged; } private async void OnDamaged(IDamageReport obj) { if(_entity is null || obj.Target!=_entity.Id)return; _hitCts?.Cancel(); _hitCts = new(); try { await BITween.Lerp(x => hitVolume.weight = x, 0f, 1, 0.1f, Mathf.Lerp, _hitCts.Token) .AttachExternalCancellation(destroyCancellationToken); await BITween.Lerp(x => hitVolume.weight = x, 1f, 0, 0.24f, Mathf.Lerp, _hitCts.Token) .AttachExternalCancellation(destroyCancellationToken); } catch (OperationCanceledException) { } } private void OnHealthChanged(int arg1, int arg2, int arg3, object arg4) { if(_entity is null || arg1!=_entity.Id)return; var t = Mathf.Clamp01(1 - arg3 * 0.01f); SetValue(t); } private UniTask OnEntityCreated(string arg1, IEntity arg2) { _entity = arg2; if(bloodyScreen) bloodyScreen.color = Color.clear; _entity.CancellationToken.Register(DisposeEntity); return UniTask.CompletedTask; void DisposeEntity() { SetValue(0); } } private void SetValue(float t) { if(!volume)return; if (volume) { volume.weight = t; } _initialColor.a = t; if (bloodyScreen) { bloodyScreen.color = _initialColor; } } } }