BITFALL/Assets/Artists/Scripts/Emoji/EntityEmojiPlayer.cs

109 lines
2.4 KiB
C#

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<string, AnimationClip> animationClips;
[SerializeField] private Optional<string[]> 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<string> 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();
}
}
}