コールバック版
using Kogane; using System; using UnityEngine; public class Example : MonoBehaviour { private readonly Hoge m_hoge = new Hoge(); private void Update() { if ( Input.GetKeyDown( KeyCode.Z ) ) { Hoge( "AAA" ); } if ( Input.GetKeyDown( KeyCode.X ) ) { Hoge( "BBB" ); } if ( Input.GetKeyDown( KeyCode.C ) ) { Hoge( "CCC" ); } } private void Hoge( string message ) { m_hoge.Play( () => Debug.Log( message ) ); } } public class Hoge { private enum State { IDLE, PLAYING, COMPLETE, } private Action m_onComplete; private State m_state; public void Play( Action onComplete ) { if ( m_state == State.COMPLETE ) { onComplete(); return; } if ( m_state == State.PLAYING ) { m_onComplete += onComplete; return; } m_state = State.PLAYING; m_onComplete += onComplete; CoroutineUtils.CallWaitForSeconds ( 3, () => { m_state = State.COMPLETE; m_onComplete(); m_onComplete = null; } ); } }
UniTask 版
using Cysharp.Threading.Tasks; using System; using UnityEngine; public class Example : MonoBehaviour { private readonly Hoge m_hoge = new Hoge(); private void Update() { Process().Forget(); } private async UniTaskVoid Process() { if ( Input.GetKeyDown( KeyCode.Z ) ) { await m_hoge.Play( () => UniTask.Delay( 3000 ) ); Debug.Log( "AAA" ); } if ( Input.GetKeyDown( KeyCode.X ) ) { await m_hoge.WaitForCompletion(); Debug.Log( "BBB" ); } if ( Input.GetKeyDown( KeyCode.C ) ) { await m_hoge.WaitForCompletion(); Debug.Log( "CCC" ); } } } public class Hoge { private enum State { IDLE, PLAYING, COMPLETE, } private State m_state = State.IDLE; private UniTaskCompletionSource m_source; public async UniTask Play( Func<UniTask> action ) { if ( m_state == State.COMPLETE ) { Debug.Log( "完了済み" ); return; } if ( m_state == State.PLAYING ) { Debug.Log( "完了待ち" ); await m_source.Task; return; } m_state = State.PLAYING; if ( m_source == null ) { m_source = new UniTaskCompletionSource(); } Debug.Log( "開始" ); await action(); Debug.Log( "完了" ); m_state = State.COMPLETE; m_source.TrySetResult(); } public async UniTask WaitForCompletion() { if ( m_state == State.COMPLETE ) { Debug.Log( "完了済み" ); return; } if ( m_source == null ) { m_source = new UniTaskCompletionSource(); } Debug.Log( "完了待ち" ); await m_source.Task; } }