public class Sandbox1 : MonoBehaviour { public void Start() { var channel = Channel.CreateSingleConsumerUnbounded<ICommand>(); SetupWriter(channel.Writer); SetupReader(channel.Reader).Forget(); } private void SetupWriter(ChannelWriter<ICommand> channelWriter) { Observable .EveryUpdate() .Where(_ => Input.GetKeyDown(KeyCode.A)) .Subscribe(_ => { Debug.Log($"Write CommandA {Time.time:0.00}"); channelWriter.TryWrite(new CommandA { Time = Time.time }); }) .AddTo(this); Observable .EveryUpdate() .Where(_ => Input.GetKeyDown(KeyCode.B)) .Subscribe(_ => { Debug.Log($"Write CommandB {Time.time:0.00}"); channelWriter.TryWrite(new CommandB { Time = Time.time }); }) .AddTo(this); } private async UniTask SetupReader(ChannelReader<ICommand> channelReader) { await foreach (var command in channelReader.ReadAllAsync(this.GetCancellationTokenOnDestroy())) { Debug.Log($"アニメ開始 {command} {command.Time:0.00}"); await UniTask.Delay(TimeSpan.FromSeconds(1)); Debug.Log($"アニメ修了 {command} {command.Time:0.00}"); } } } public interface ICommand { float Time { get; } } public class CommandA : ICommand { public float Time { get; set; } } public class CommandB : ICommand { public float Time { get; set; } }
説明を簡単にするため、SingleConsumerUnboundedChannelを使うことにします。
channelWriter.TryWrite
すると、どんどんQueueに積まれていきます。
channelReader.ReadAsync
または channelReader.ReadAllAsync
などで、それを先頭から読んでいけます。
これによりAボタンやBボタンをたくさん入力しても、アニメは順番に再生される。という先行入力が実現できます。