diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/RuntimeOnlyAwaitCaller.cs b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/RuntimeOnlyAwaitCaller.cs index 23cc7b592..83665d7a0 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/RuntimeOnlyAwaitCaller.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/RuntimeOnlyAwaitCaller.cs @@ -32,5 +32,51 @@ namespace VRMShaders { return Task.Run(action); } + + /// + /// 指定した時間が経過している場合のみ、NextFrame() を使って1フレーム待つ + /// + /// タイムアウト時間(ミリ秒単位) + /// タイムアウト時はNextFrame()を呼び出す。そうではない場合、Task.CompletedTaskを返す + public Task NextFrameIfTimedOut_(float timeOutInMilliseconds = 1f) + { + if (!CheckTimeOut(timeOutInMilliseconds)) + { + return Task.CompletedTask; + } + _lastBaseTime = 0f; + return NextFrame(); + } + + private bool CheckTimeOut(float timeOutInMilliseconds) + { + float t = UnityEngine.Time.realtimeSinceStartup; + if (_lastBaseTime == 0f) + { + // Reset base time + _lastBaseTime = t; + } + return (t - _lastBaseTime) >= timeOutInMilliseconds * (1f / 1000f); + } + + private float _lastBaseTime; } -} \ No newline at end of file + + internal static class RuntimeOnlyAwaitCallerHelper + { + /// + /// 指定した時間が経過している場合のみ、NextFrame() を使って1フレーム待つ + /// + /// IAwaitCallerのインスタンス + /// タイムアウト時間(ミリ秒単位) + /// タイムアウト時はNextFrame()を呼び出す。そうではない場合、Task.CompletedTaskを返す + internal static Task NextFrameIfTimedOut(this IAwaitCaller iAwaitCaller, float timeOutInMilliseconds) + { + if (iAwaitCaller is RuntimeOnlyAwaitCaller runtimeOnlyAwaitCaller) + { + return runtimeOnlyAwaitCaller.NextFrameIfTimedOut_(timeOutInMilliseconds); + } + return Task.CompletedTask; + } + } +}