Skip to content

Commit 8bed65a

Browse files
committed
Add functions to invoke after a delay
1 parent a80ee7e commit 8bed65a

File tree

1 file changed

+68
-1
lines changed

1 file changed

+68
-1
lines changed

UnityHelper/Extensions/UnityExtensions.cs

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
using System.Collections.Generic;
1+
using BepInEx.Logging;
2+
using System;
3+
using System.Collections;
4+
using System.Collections.Generic;
25
using System.Linq;
36
using UnityEngine;
47
using UnityEngine.SceneManagement;
8+
using Logger = BepInEx.Logging.Logger;
59

610
namespace Silksong.UnityHelper.Extensions;
711

@@ -10,6 +14,8 @@ namespace Silksong.UnityHelper.Extensions;
1014
/// </summary>
1115
public static class UnityExtensions
1216
{
17+
private static readonly ManualLogSource Log = Logger.CreateLogSource($"{nameof(UnityHelperPlugin)}.{nameof(UnityExtensions)}");
18+
1319
/// <summary>
1420
/// Get the first component on a game object of a given type.
1521
///
@@ -87,4 +93,65 @@ public static string GetNameInHierarchy(this Transform t)
8793

8894
return root.FindChild(pathParts[1]);
8995
}
96+
97+
/// <summary>
98+
/// Execute the given action after the specified number of seconds.
99+
/// </summary>
100+
/// <param name="component">The component used to start the coroutine. Often a plugin instance or <see cref="GameManager.instance"/>.</param>
101+
/// <param name="toInvoke">An Action to invoke.</param>
102+
/// <param name="seconds">The number of seconds to wait before invoking.</param>
103+
public static void InvokeAfterSeconds(this MonoBehaviour component, Action toInvoke, float seconds)
104+
{
105+
component.StartCoroutine(doInvoke());
106+
107+
IEnumerator doInvoke()
108+
{
109+
yield return new WaitForSeconds(seconds);
110+
111+
try
112+
{
113+
toInvoke();
114+
}
115+
catch (Exception ex)
116+
{
117+
Log.LogError($"Error invoking action {toInvoke.Method.Name}\n" + ex);
118+
}
119+
}
120+
}
121+
122+
/// <summary>
123+
/// Execute the given action after the specified number of frames.
124+
/// </summary>
125+
/// <param name="component"><inheritdoc cref="InvokeAfterSeconds"/></param>
126+
/// <param name="toInvoke"><inheritdoc cref="InvokeAfterSeconds"/></param>
127+
/// <param name="numFrames">The number of frames to wait.</param>
128+
public static void InvokeAfterFrames(this MonoBehaviour component, Action toInvoke, int numFrames)
129+
{
130+
component.StartCoroutine(doInvoke());
131+
132+
IEnumerator doInvoke()
133+
{
134+
for (int i = 0; i < numFrames; i++)
135+
{
136+
yield return null;
137+
}
138+
139+
try
140+
{
141+
toInvoke();
142+
}
143+
catch (Exception ex)
144+
{
145+
Log.LogError($"Error invoking action {toInvoke.Method.Name}\n" + ex);
146+
}
147+
}
148+
}
149+
150+
/// <summary>
151+
/// Execute the given action after 1 frame has passed.
152+
/// </summary>
153+
/// <param name="component"><inheritdoc cref="InvokeAfterSeconds"/></param>
154+
/// <param name="toInvoke"><inheritdoc cref="InvokeAfterSeconds"/></param>
155+
public static void InvokeNextFrame(this MonoBehaviour component, Action toInvoke) => component.InvokeAfterFrames(toInvoke, 1);
156+
90157
}

0 commit comments

Comments
 (0)