ã¯ããã«
ã¤ãã«Unity2023.1ããUnityå
¬å¼çUniTask
ãåºã¾ããã(çµæ§èªå¼ãããããã ã...)
ãã ç¾æ®µéã§ã¯UniTask
ã¨åçã»ãããã¯ãã以ä¸ãªæ©è½ãæã£ã¦ããããã§ã¯ãªãã軽ã触ã£ãéãã¯ã¾ã ã¾ã APIã足ããçºå±éä¸ããªã¨ãã£ãæãã§ãã
ããã段ã ã¨ä½¿ãããããªãã®ã¯ééããªãã§ãããããå¤é¨ã©ã¤ãã©ãªããªãã¹ã使ããããªãæ¹ã«ã¨ã£ã¦é åçãªãã¨ã確ãã§ããä»å¾å©ç¨ãããã±ã¼ã¹ãå¢ãããã¨æãã¾ãã®ã§ãä»ã®ãã¡ãã触ã£ã¦ããã®ãæªããªããã¨æãã¾ãã
ã¡ãªã¿ã«ç¾æ®µéã§ã¯ãã£ããã¨ããããã¥ã¡ã³ãã¯ãªãããã§ã...ã
ç°å¢
Unity2023.1.0
ã©ã¤ããµã¤ã¯ã«ã«ç´ã¥ããCancellationToken
MonoBehavior
ã®ã©ã¤ããµã¤ã¯ã«ã¨ç´ã¥ããCancellationToken
ãMonoBehavior
ã®ããããã£ã¨ãã¦å®è£
ããã¾ããã
ãã®åãMonoBehaviour.destroyCancellationToken
ã§ãã
docs.unity3d.com
// éè¦ãªç®æ以å¤çç¥ namespace UnityEngine { public class MonoBehaviour : Behaviour { private CancellationTokenSource m_CancellationTokenSource; /// <summary> /// <para>Cancellation token raised when the MonoBehaviour is destroyed (Read Only).</para> /// </summary> public CancellationToken destroyCancellationToken { get { if (this.m_CancellationTokenSource == null) { this.m_CancellationTokenSource = new CancellationTokenSource(); this.OnCancellationTokenCreated(); } return this.m_CancellationTokenSource.Token; } } } }
MonoBehavior
ã®Destroy
ã®ã¿ã¤ãã³ã°ã§Cancel
ãããã®ã§ãã³ã«ã¼ãã³ã®ããã«GameObject
ãç ´æ£ãããã¿ã¤ãã³ã°ã§ãå¦çãæ¢ã¾ã£ã¦ãããããã«ãªãã¾ãã(ã¡ããã¨CancellationToken
ãæ±ã£ã¦ããã°ã ã)
public class Sample : MonoBehaviour { private async Awaitable Start() { // 1ç§å¾ 㤠await Awaitable.WaitForSecondsAsync(1, destroyCancellationToken); } }
ã¾ãPlayMode
çµäºæ(Editor
ä¸ã§ã®è©±)ãããã¯ã¢ããªã±ã¼ã·ã§ã³çµäºæã«ãã£ã³ã»ã«ãçºè¡ããApplication.exitCancellationToken
ãªããã®ãç¨æããã¦ãã¾ãã
CancellationToken token = Application.exitCancellationToken;
使ãæ¹
ç¾å¨å®è£
ããã¦ããAwaitable
ã®static
ã¡ã½ããã«ã¤ãã¦åæãã¾ãã
private async Awaitable Start() { // 1ç§å¾ 㤠// Task.Delayã¨ç°ãªããTime.timeScaleã®å½±é¿ãåãã await Awaitable.WaitForSecondsAsync(1f, destroyCancellationToken); // ç¾å¨ã®ãã¬ã¼ã ã®æå¾ã¾ã§å¾ 㤠await Awaitable.EndOfFrameAsync(destroyCancellationToken); // 次ã®FixedUpdateã¾ã§å¾ 㤠await Awaitable.FixedUpdateAsync(destroyCancellationToken); // 次ã®ãã¬ã¼ã ã¾ã§å¾ 㤠await Awaitable.NextFrameAsync(destroyCancellationToken); // å¥ã¹ã¬ããã«ç§»å await Awaitable.BackgroundThreadAsync(); // ã¡ã¤ã³ã¹ã¬ããã«ç§»å await Awaitable.MainThreadAsync(); }
Awaitable.WaitForSecondsAsync
ã¯ã¡ããã¨Time.timeScale
ã®å½±é¿ãåãã¦ãããã¿ããã§ããã
PlayerLoopã®å ´æã«ã¤ãã¦
ããã¯ããã¢ãã¯ãªã®ã§èªã¿é£ã°ãã¦ããã£ã¦å¤§ä¸å¤«ã§ãã
PlayerLoopã®ç´°ããã¤ãã³ããã¡ã¯UniTask
ã®ä½è
ãããGitHubã«è¼ãã¦ããã¦ããã®ã§è¼ãã¦ããã¾ããï¼ä¸é¨UniTask
ã®ã¤ãã³ããå
¥ã£ã¦ãã¾ããä»åã¯ç¡è¦ãã¦ãã ããï¼
Unityããã¢ãªäººã¯å®éPlayerLoop
ã®ã©ãã®ç®æã§å®è¡ããããæ°ã«ãªãã¨æãã®ã§ãããããã®å¦çã®åå¾ã«Debug.Log
ãä»çµãããã«æ¹é ãã¦ã¿ã¾ããã
public struct CustomEvent { } [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] private static void Init() { var playerLoop = PlayerLoop.GetCurrentPlayerLoop(); Set(ref playerLoop); PlayerLoop.SetPlayerLoop(playerLoop); } private static void Set(ref PlayerLoopSystem playerLoop) { playerLoop.subSystemList ??= Array.Empty<PlayerLoopSystem>(); var type = playerLoop.type; playerLoop = new PlayerLoopSystem { type = playerLoop.type, updateDelegate = playerLoop.updateDelegate, subSystemList = playerLoop.subSystemList .Prepend(new PlayerLoopSystem { type = typeof(CustomEvent), updateDelegate = () => Debug.Log($"{type} : Start"), }) .Append(new PlayerLoopSystem { type = typeof(CustomEvent), updateDelegate = () => Debug.Log($"{type} : End"), }) .ToArray(), updateFunction = playerLoop.updateFunction, loopConditionFunction = playerLoop.loopConditionFunction, }; if (playerLoop.subSystemList.Length == 2) return; for(var i = 0; i < playerLoop.subSystemList.Length; i++) { Set(ref playerLoop.subSystemList[i]); } }
PlayerLoopSystem
ãæ§é ä½ãªã®ã§å°ãæéåãã¾ããããã¡ããã¨è¨æ¸¬ã§ãã¦ãããã§ãã
çµæã¨ãã¦ã¯ä»¥ä¸ã®ããã«ãªãã¾ããã
é¢æ°å | awaitå¾ãå®è¡ãããã¿ã¤ãã³ã° |
---|---|
WaitForSecondsAsync | ScriptRunBehaviourUpdate ã¨ScriptRunDelayedDynamicFrameRate ã®éã |
EndOfFrameAsync | PostLateUpdate ã®å¾ãã¤ã¾ãæ¬å½ã«æå¾ã |
FixedUpdateAsync | DirectorFixedUpdatePostPhysics ã¨ScriptRunDelayedFixedFrameRate ã®éã |
NextFrameAsync | ScriptRunBehaviourUpdate ã¨ScriptRunDelayedDynamicFrameRate ã®éã |
è¿ãå¤ãæã¤å ´å
Awaitable<T>
ãã¡ããã¨åå¨ãã¾ãã
private async Awaitable Start() { var value = await HogeAsync(destroyCancellationToken); // 1 Debug.Log(value); } private static async Awaitable<int> HogeAsync(CancellationToken token) { return 1; }
ã¨ã©ã¼ã®é¢ç½ãæ§è³ª
C#
ã§ã¯OperationCanceledException
ã¨ããã¨ã©ã¼ãç¹æ®ã«æ±ã£ã¦ãã¾ãã
å
·ä½çã«ã¯å¼ã³åºãå
ã®ã¡ã½ãããTask
ãAwaitable
ãè¿ãå ´åã¯ã¨ã©ã¼ãåºåãããããã§ã¯ããã¾ããã
private async Awaitable Start() { // ãã°åºåãããããã¢ããªãæ¢ã¾ãããã§ããªã throw new OperationCanceledException(); } private async Task Start2() { // ãã°åºåãããããã¢ããªãæ¢ã¾ãããã§ããªã throw new OperationCanceledException(); } private async void Start3() { // ã¨ã©ã¼ãåºåããã throw new OperationCanceledException(); } private void Start4() { // ã¨ã©ã¼ãåºåããã throw new OperationCanceledException(); }