Last active
September 27, 2022 04:42
-
-
Save JanikHelbig/74398ba1d9d4726d8faab1c228acefa7 to your computer and use it in GitHub Desktop.
Asynchronous equivalent of .NET's System.Action and System.Action<T> using UniTask for Unity
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public delegate UniTask ActionAsync(CancellationToken cancellationToken); | |
public delegate UniTask ActionAsync<in T>(T value, CancellationToken cancellationToken); | |
public static class ActionAsyncExtensions | |
{ | |
public static UniTask InvokeAsync(this ActionAsync handler, CancellationToken cancellationToken) | |
{ | |
Delegate[] delegates = handler?.GetInvocationList(); | |
if (delegates == null || delegates.Length == 0) | |
return UniTask.CompletedTask; | |
var tasks = new UniTask[delegates.Length]; | |
for (var i = 0; i < delegates.Length; i++) | |
tasks[i] = (UniTask) delegates[i].DynamicInvoke(cancellationToken); | |
return UniTask.WhenAll(tasks); | |
} | |
public static UniTask InvokeAsync<T>(this ActionAsync<T> handler, T value, CancellationToken cancellationToken) | |
{ | |
Delegate[] delegates = handler?.GetInvocationList(); | |
if (delegates == null || delegates.Length == 0) | |
return UniTask.CompletedTask; | |
var tasks = new UniTask[delegates.Length]; | |
for (var i = 0; i < delegates.Length; i++) | |
tasks[i] = (UniTask) delegates[i].DynamicInvoke(value, cancellationToken); | |
return UniTask.WhenAll(tasks); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Door : MonoBehaviour | |
{ | |
public event ActionAsync OnOpening; | |
public event Action OnOpened; | |
public event ActionAsync OnClosing; | |
public event Action OnClosed; | |
public async UniTask OpenDoor(CancellationToken cancellationToken) | |
{ | |
await OnOpening.InvokeAsync(cancellationToken); | |
OnOpened?.Invoke(); | |
} | |
public async UniTask CloseDoor(CancellationToken cancellationToken) | |
{ | |
await OnClosing.InvokeAsync(cancellationToken); | |
OnClosed?.Invoke(); | |
} | |
} | |
public class DoorAnimationBehaviour : MonoBehaviour | |
{ | |
[SerializeField] | |
private Door door; | |
[SerializeField] | |
private Animator doorAnimator; | |
private void OnEnable() | |
{ | |
door.OnOpening += AnimateDoorOpening; | |
door.OnClosing += AnimateDoorClosing; | |
} | |
private void OnDisable() | |
{ | |
door.OnOpening -= AnimateDoorOpening; | |
door.OnClosing -= AnimateDoorClosing; | |
} | |
private async UniTask AnimateDoorOpening(CancellationToken cancellationToken) | |
{ | |
doorAnimator.SetBool("IsOpen", true); | |
await UniTask.WaitWhile(() => doorAnimator.GetCurrentAnimatorStateInfo(0).IsName("Opening"), PlayerLoopTiming.Update, cancellationToken); | |
} | |
private async UniTask AnimateDoorClosing(CancellationToken cancellationToken) | |
{ | |
doorAnimator.SetBool("IsOpen", false); | |
await UniTask.WaitWhile(() => doorAnimator.GetCurrentAnimatorStateInfo(0).IsName("Closing"), PlayerLoopTiming.Update, cancellationToken); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment