using System; using System.Collections; using System.Collections.Generic; using BITFALL.Player.Movement; using BITFALL.Props; using BITKit; using BITKit.Entities; using Cysharp.Threading.Tasks; using UnityEditor.UI; using UnityEngine; namespace BITFALL.Entities.Player.Movement { [CustomType(typeof(IStunObject))] public class PlayerCharacterControllerStun : EntityBehavior,IStunObject { [Inject] private IEntityMovement _movement; [SerializeField] private float breatheFrequency = 0.5f; // 呼吸的频率,值越大呼吸越快 [SerializeField] private float breatheAmplitude = 0.005f; // 呼吸的幅度,即准星上下移动的最大距离 [SerializeField] private LocationAdditive viewAdditive; [SerializeField] private LocationAdditive inverseAdditive; private readonly ValidHandle allow = new(); public float Weight { get;private set; } public event Action OnWeightChanged; private readonly IntervalUpdate _resetInterval = new(1f); public async void Stun(float distance, float duration) { Weight = 1; OnWeightChanged?.Invoke(Weight); _resetInterval.AddDelay(duration); var id = Guid.NewGuid().GetHashCode(); _movement.ExecuteCommand(new PlayerPauseRunCommand(id,true)); _movement.ExecuteCommand(new PlayerLimitMoveSpeedCommand() { Id = id, Speed =1f, Limit = true, }); _movement.ExecuteCommand(new PlayerLimitSensitivityCommand() { Id = id, Sensitivity = 0.1f, Limit = true, }); allow.AddElement(id); await UniTask.Delay(TimeSpan.FromSeconds(duration)); if(destroyCancellationToken.IsCancellationRequested) return; _movement.ExecuteCommand(new PlayerPauseRunCommand(id,false)); _movement.ExecuteCommand(new PlayerLimitMoveSpeedCommand() { Id = id, Limit = false, }); _movement.ExecuteCommand(new PlayerLimitSensitivityCommand() { Id = id, Limit = false, }); allow.RemoveElement(id); } public override void OnUpdate(float deltaTime) { if (Weight <= 0) return; if(_resetInterval.AllowUpdateWithoutReset) { Weight = Mathf.Clamp(Weight -= deltaTime, 0, 1); OnWeightChanged?.Invoke(Weight); } var breatheOffset = Mathf.Sin(Time.time * breatheFrequency) * breatheAmplitude; breatheOffset *= Weight; if (viewAdditive) viewAdditive.AddRotation(Quaternion.Euler(breatheOffset, breatheOffset, 0), nameof(IStunObject)); if (inverseAdditive) inverseAdditive.AddRotation(Quaternion.Euler(-breatheOffset, -breatheOffset, 0), nameof(IStunObject)); } } }