using System; using System.Collections; using System.Collections.Generic; using Animancer; using AYellowpaper.SerializedCollections; using BITFALL.Hotkey; using BITKit; using BITKit.Entities; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Interactions; namespace BITFALL.Animate { public sealed class EntityEmojiPlayer : EntityBehavior { [SerializeField]private SerializedDictionary animationClips; [SerializeField] private Optional initialEmojis; [SerializeField]private AnimancerComponent animancerComponent; [SerializeField] private InputActionReference cancelAction; [Inject] private IHotkeyCollection _hotkeyCollection; [Inject] private IEntityOverride _override; [Inject] private IEntityMovement _movement; [Inject] private IHealth _health; private readonly List activeEmojis = new(); private AnimancerState _currentAnimancerState; private readonly InputActionGroup _inputActionGroup = new(); public override void OnStart() { base.OnStart(); _health.OnSetAlive += OnSetAlive; _inputActionGroup.RegisterCallback(cancelAction, Cancel); if (initialEmojis.Allow) { activeEmojis.AddRange(initialEmojis.Value); } foreach (var x in activeEmojis) { _hotkeyCollection.Register(new HotkeyProvider() { Name = x, Description = $"播放表情:{x}", OnPerform = Play, Enabled = true, }); continue; void Play() { if (_movement.IsGrounded is false) return; var state = _currentAnimancerState = animancerComponent.Play(animationClips[x]); _currentAnimancerState.Events.OnEnd += OnEnd; _override.AddOverride(this); return; void OnEnd() { state.Events.OnEnd = null; _override.RemoveOverride(this); state.Stop(); if (state == _currentAnimancerState) { _currentAnimancerState = null; } } } } _inputActionGroup.allowInput.SetElements(_health,_health.IsAlive); } private void Cancel(InputAction.CallbackContext obj) { switch (obj) { case {interaction:PressInteraction, performed:true}: StopInternal(); break; } } private void OnSetAlive(bool obj) { _inputActionGroup.allowInput.SetElements(this,obj); if (obj) return; StopInternal(); } private void StopInternal() { _currentAnimancerState?.Events.OnEnd?.Invoke(); } } }