Invoke 是 MonoBehaviour 类中的方法,用于延迟调用方法。
1、基本用法
Invoke()
cs
// 基本语法
Invoke("方法名", 延迟时间);
// 示例
void Start()
{
// 3秒后执行 Shoot 方法
Invoke("Shoot", 3f);
}
void Shoot()
{
Debug.Log("射击!");
}
InvokeRepeating()
cs
// 基本语法
InvokeRepeating("方法名", 首次延迟时间, 重复间隔时间);
// 示例
void Start()
{
// 2秒后第一次执行,之后每隔1秒重复执行
InvokeRepeating("SpawnEnemy", 2f, 1f);
}
void SpawnEnemy()
{
Debug.Log("生成敌人!");
}
CancelInvoke()
cs
// 停止所有通过 Invoke 调用的方法
CancelInvoke();
// 停止特定方法
CancelInvoke("方法名");
IsInvoking()
cs
// 检查是否有任何 Invoke 正在执行
if (IsInvoking())
{
// 有方法正在等待执行
}
// 检查特定方法是否正在等待执行
if (IsInvoking("方法名"))
{
// 该方法正在等待执行
}
2、Invoke与委托结合使用
从 Unity 2017.1 开始,可以使用 Action 委托替代字符串方法名:
cs
// 使用 Invoke 的替代方案
void Start()
{
// 延迟执行
StartCoroutine(DelayedAction(2f, () =>
{
Debug.Log("延迟执行");
}));
// 重复执行
StartCoroutine(RepeatingAction(1f, 0.5f, () =>
{
Debug.Log("重复执行");
}));
}
IEnumerator DelayedAction(float delay, Action action)
{
yield return new WaitForSeconds(delay);
action?.Invoke();
}
IEnumerator RepeatingAction(float startDelay, float interval, Action action)
{
yield return new WaitForSeconds(startDelay);
while (true)
{
action?.Invoke();
yield return new WaitForSeconds(interval);
}
}
与自定义委托结合
cs
public delegate void DelegateTest();
class Program
{
static void Main(string[] args)
{
DelegateTest dele = new DelegateTest(Test1);
dele += Test2;
// 执行
//dele(); // 简化语法
dele.Invoke();
}
static void Test1()
{
Console.WriteLine("Test1");
}
static void Test2()
{
Console.WriteLine("Test2");
}
}
3、最佳实践和注意事项
- 性能考虑:
- 避免频繁使用 Invoke,特别是在 Update 中
- 对于性能敏感的场景,优先使用协程
- 代码维护:
- 字符串方法名容易拼写错误,且重构时不安全
- 考虑使用委托或协程替代
- 对象销毁时:
- GameObject 被销毁时,所有 Invoke 调用会自动取消
- 脚本被禁用时,Invoke 不会自动停止
- 精度问题:
- Invoke 的时间精度不如 Time.deltaTime 精确
- 对于需要精确时间控制的场景,建议使用 Update 配合计时器