UniTaskは便利ですが、スクリプトをアタッチしているGameObject や 自身のComponentがDisabledになったとき、またGameObjectがDeleteされた時もタスクが残ってしまいます。
(1)Active all | (2)Disable GameObject | (3)Disable Component | (4)Delete GameObject |
---|---|---|---|
動き続ける | 動き続ける | 動き続ける | 動き続ける |
Coroutineの時とは違い、常に動き続けているので、(1)-(3)の対応は
await UniTask.WaitUntil(() => this.isActiveAndEnabled)
のみでよさそうです。
(4)については、System.Threading.CancellationToken
をタスクに渡すことで自動的にタスクを削除してくれるようになります。
using UnityEngine;
using System.Threading.Tasks;
using Cysharp.Threading.Tasks;
using System.Threading;
[HelpURL("https://cysharp.github.io/UniTask/api/Cysharp.Threading.Tasks.html")]
public class UniTaskActiveCheck : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
Debug.Log("Start");
System.Threading.CancellationToken ct = this.GetCancellationTokenOnDestroy();
Task0(ct).Forget();
}
// Update is called once per frame
void Update()
{
}
async UniTask Task0(CancellationToken ct)
{
int m_count = 0;
while (true)
{
await UniTask.WaitUntil(() => this.isActiveAndEnabled, cancellationToken: ct);
Debug.Log($"Task0: {m_count}");
m_count++;
await Task.Delay(1000, ct);
}
}
private void OnDisable()
{
Debug.Log("OnDisable");
}
private void OnEnable()
{
Debug.Log("OnEnable");
}
private void OnDestroy()
{
Debug.Log("[OnDestroy]");
}
}