14.延迟函数

14.MonoBehavior中的重要内容-延迟函数


14.1 知识点

什么是延迟函数

延迟函数顾名思义,就是会延时执行的函数。我们可以自己设定延时要执行的函数和具体延时的时间。它是MonoBehaviour基类中实现好的方法。

延迟函数的使用

Invoke方法 开启延迟函数

Invoke方法用于在指定时间后调用指定方法。

// 在time秒后调用methodName方法。
// 参数一:函数名字符串
// 参数二:延迟时间,秒为单位
Invoke("DelayDoSomething", 1);
// 注意:
// - 延时函数第一个参数传入的是函数名字符串。即使填错了也不会报错。
// - 延时函数无法传入参数。如果直接调用有参数的函数,会寻找没有参数的重载。
// - 函数名必须是该脚本上声明的函数。如果想调用其他脚本的函数,也要包裹一层在这个脚本无参的函数里。

InvokeRepeating方法 开启延迟重复执行函数

InvokeRepeating方法用于在指定时间后开始重复调用指定方法。

// 在time秒后调用methodName方法,然后每repeatRate秒调用一次。
// 参数一:函数名字符串
// 参数二:第一次执行的延迟时间
// 参数三:之后每次执行的间隔时间
InvokeRepeating("DelaRepeat", 5, 1);
// 注意:它的注意事项和延时函数一致

CancelInvoke方法 取消延迟函数

CancelInvoke方法用于取消所有或者指定延迟函数的执行。

// 不传入参数,取消该脚本上的所有延时函数执行
CancelInvoke();
// 传入参数,取消指定延迟函数
// 只要取消了指定延迟,不管之前该函数开启了多少次延迟执行,都会统一取消
CancelInvoke("DelayDoSomething");

IsInvoking方法 判断是否有延迟函数

IsInvoking方法用于判断是否存在待处理的指定方法调用。

// 是否有任何待处理的methodName调用?
// 不传入参数,判断该脚本上是否存在任何延迟函数
if (IsInvoking())
{
    print("存在延迟函数");
}
// 传入参数,判断该脚本上是否存在指定延迟函数
if (IsInvoking("DelayDoSomething"))
{
    print("存在延迟函数DelayDoSomething");
}

延迟函数受对象失活销毁影响

延迟函数在对象失活时不受影响,但在对象销毁或者移除脚本时无法继续执行。

// 脚本依附对象失活或者脚本自己失活,延迟函数可以继续执行不受影响
// 脚本依附对象销毁或者脚本移除,延迟函数无法继续执行
// 如果需要在对象失活时停止延迟函数,可以在生命周期函数OnEnable和OnDisable中做逻辑
private void OnEnable()
{
    // 对象激活的生命周期函数中,开启延迟(重复执行的延迟)
}

private void OnDisable()
{
    // 对象失活的生命周期函数中,停止延迟
}

总结

  • 继承MonoBehavior的脚本可以使用延时相关函数。
  • 函数相关:
    • Invoke:延时函数
    • InvokeRepeating:延时重复函数
    • CancelInvoke:停止所有或者指定延时函数
    • IsInvoking:判断是否有延时函数待执行
  • 使用相关:
    • 参数都是函数名,无法传参数
    • 只能执行该脚本中申明的函数
    • 对象或脚本失活无法停止延时函数执行,只有销毁组件或者对象才会停止或者代码停止

14.2 知识点代码

Lesson14_MonoBehavior中的重要内容_延迟函数

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Lesson14_MonoBehavior中的重要内容_延迟函数 : MonoBehaviour
{
    public Test t;
    
    void Start()
    {
        #region 知识点一 什么是延迟函数

        //延迟函数顾名思义
        //就是会延时执行的函数
        //我们可以自己设定延时要执行的函数和具体延时的时间
        //是MonoBehaviour基类中实现好的方法

        #endregion

        #region 知识点二 延迟函数的使用

        //MonoBehavior中的Invoke方法 开启延迟函数
        //在 testNum 秒后调用 methodName 方法。
        //参数一:函数名 字符串
        //参数二:延迟时间 秒为单位
        Invoke("DelayDoSomething", 1);
        //注意:
        //延时函数第一个参数传入的是函数名字符串 假如填错了也不会报错
        //延时函数没办法传入参数 假如直接调用有参数的函数会去找这个函数没有参数的重载
        //想调用有参数的函数只能放在没参数的函数 包裹一层
        //函数名必须是该脚本上申明的函数 如果想调用别的脚本的函数 也要包裹一层在这个脚本无参的函数里

        //MonoBehavior中的InvokeRepeating方法 开启延迟重复执行函数
        //在 testNum 秒后调用 methodName 方法,然后每 repeatRate 秒调用一次。
        //参数一:函数名字符串
        //参数二:第一次执行的延迟时间
        //参数三:之后每次执行的间隔时间
        InvokeRepeating("DelaRepeat", 5, 1);
        //注意:它的注意事项和延时函数一致

        //MonoBehavior中的CancelInvoke方法 取消延迟函数
        //不传入参数 取消该脚本上的所有延时函数执行
        //取消该 MonoBehaviour 上的所有 Invoke 调用。
        //CancelInvoke();
        //不传入参数 指定函数名取消延时函数
        //只要取消了指定延迟 不管之前该函数开启了多少次延迟执行 都会统一取消
        //CancelInvoke("DelayDoSomething");

        //MonoBehavior中的IsInvoking方法 判断是否有延迟函数
        //是否有任何待处理的 methodName 调用?
        //不传入参数 判断该脚本上是否存在任何延迟函数
        if (IsInvoking())
        {
            print("存在延迟函数");
        }
        //传入参数 判断该脚本上是否存在指定延迟函数
        if (IsInvoking("DelayDoSomething"))
        {
            print("存在延迟函数DelayDoSomething");
        }

        #endregion

        #region 知识点三 延迟函数受对象失活销毁影响

        //脚本依附对象失活 或者 脚本自己失活 延迟函数可以继续执行 不会受到影响的
        //脚本依附对象销毁或者脚本移除 延迟函数无法继续执行
        //假如现在对象激活开启延迟函数 对象失活取消延迟函数 可以在生命周期函数OnEnable和OnDisable做逻辑

        #endregion

        #region 总结
        //继承MonoBehavior的脚本可以使用延时相关函数
        //函数相关
        //Invoke 延时函数
        //InvokeRepeating 延时重复函数
        //CancelInvoke 停止所有或者指定延时函数
        //IsInvoking 判断是否有延时函数待执行
        //使用相关
        //1.参数都是函数名,无法传参数
        //2.只能执行该脚本中申明的函数
        //3.对象或脚本失活无法停止延时函数执行,只有销毁组件或者对象才会停止或者代码停止
        #endregion
    }

    private void OnEnable()
    {
        //对象激活 的生命周期函数中 开启延迟(重复执行的延迟)
    }

    private void OnDisable()
    {
        //对象失活 的生命周期函数中 停止延迟
    }

    private void DelayDoSomething()
    {
        print("延时执行的函数");

        TestFun(2);

        //newThread.TestFun();
    }

    private void DelaRepeat()
    {
        print("重复执行");
    }

    private void TestFun()
    {
        print("无参重载");
    }

    private void TestFun(int i)
    {
        print("传入参数" + i);
    }

}

Test

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour
{
    public void TestFun()
    {
        print("Test的方法");
    }
}

14.3 练习题

利用延时函数实现一个计秒器

// 使用延迟重复函数,一进来直接调用,然后每隔一秒调用,实现计时器
InvokeRepeating("DelayTimer", 0, 1);

// 直接执行函数 函数里面在写一个普通延迟函数每秒调用自己
DelayTimer2();

private void DelayTimer()
{
    print(time + "秒");
    ++time;
}

private void DelayTimer2()
{
    print(time + "秒");
    ++time;
    Invoke("DelayTimer2", 1);
}

请用两种方式延时销毁一个指定对象

// 通过Destroy来进行延迟销毁
Destroy(this.gameObject, 5);

// 延迟函数销毁,内部使用销毁逻辑,
// 包裹一层,相比于Destroy直接销毁,假如想有其他逻辑也可以写在延迟销毁函数中
Invoke("DelayDestroy", 5);

private void DelayDestroy()
{
    Destroy(this.gameObject);
}

14.4 练习题代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Lesson14_练习题 : MonoBehaviour
{
    private int time = 0;

    void Start()
    {
        #region 练习题一 
        //利用延时函数实现一个计秒器

        //使用延迟重复函数,一进来直接调用,然后每隔一秒调用,实现计时器
        InvokeRepeating("DelayTimer", 0, 1);

        //直接执行函数 函数里面在写一个普通延迟函数没秒调用自己
        DelayTimer2();

        #endregion

        #region 练习题二 
        //请用两种方式延时销毁一个指定对象

        //通过Destroy来进行延迟销毁
        Destroy(this.gameObject, 5);

        //延迟函数销毁,内部使用销毁逻辑,
        //包裹一层,相比于Destroy直接销毁,假如想有其他逻辑也可以写在延迟销毁函数中
        Invoke("DelayDestroy", 5);
        #endregion
    }
    #region 练习题一 
    private void DelayTimer()
    {
        print(time + "秒");
        ++time;
    }

    private void DelayTimer2()
    {
        print(time + "秒");
        ++time;
        Invoke("DelayTimer2", 1);
    }

    #endregion

    #region 练习题二
    private void DelayDestroy()
    {
        Destroy(this.gameObject);
    }
    #endregion

}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏