Unity之组件的生命周期

一、组件的概念

我本身是由Web后端转到了游戏后端,最近因为工作原因在学ET框架。学到了 ECS 编程模式开发(E ------ Entity,C ------ Component , S ------ System)实体、组件、逻辑开发。

我是这么理解的:组件是挂载到实体上的,组件中记录了实体所需要的数据,然后实体的业务和行为在逻辑里编写。


举个例子:关羽拿青龙偃月刀斩了颜良,这里关羽看做实体,青龙偃月刀作为组件挂载在关羽身上,斩颜良是实体关羽所做出来的行为动作。

偷的表情包(手动狗头)

那么问题来了:关羽可以拿刀砍人;我可以拿刀砍人;在看博客的你也可以拿刀砍人,难不成每次写程序都要新写一个刀组件?


写程序就要学会偷懒,游戏引擎的开发者们就把一些可以共用的组件抽出来,比如Unity里的Box Collider ------ 碰撞组件、Rigidbody ------ 重力组件(刚学Unity第二天一共就知道这俩 ------ doge.jpg)

二、创建新组件并挂载

说到这里大家大概明白什么是组件了吧,这里我们创建一个新组件。在项目一栏的空白处点击鼠标右键创建一个C#脚本,我这里给它命名为Move。

如果我们想把组件添加到实体上,我目前知道的有三种方式

或者点击添加组件按钮进行搜索

这样我们就把组件挂到实体上了。

三、组件的生命周期函数

说完了怎么挂载组件我们正式进入正题,来谈谈组件的生命周期。所谓生命周期就是一个事物由创建到销毁的全过程。

我们双击打开创建好的C#脚本,它会打开编辑器,我这里用的是visual studio,打开后会看到下边这段代码:

csharp 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Move: MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
       
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

这里的 Start() 和 Update() 是生命周期中的两种函数,此外还有 Awake() 、OnEnable() 、LateUpdate() 、FixedUpdate() 、OnDisable() 、OnDestroy() ,一共八种,我们来看一下这些生命周期函数。

3.1 Awake()

Awake ------ 唤醒,这是当组件挂载在实体上第一个要执行的函数,庆祝诞生。我们来把 Debug.Log("awake"); 的注释解开在控制台打印输出一下看看。

很简单接着往下看

3.2 OnEnable()

OnEnable() 函数在Awake执行之后执行,每次激活组件都会调用一次,打印一下Log日志

看起来不难,但是这里的每次激活组件都会调用一次

每次激活??都会调用一次?? 来详细看,这个Move脚本旁边的 "√" 勾上就是激活,不勾就是不激活,我们反复勾一下可以看到下边控制台 awake 只执行了一次,而 OnEnable 执行了多次,这就是所谓的 每次激活组件都会调用一次。

3.3 Start()

调用时机是第一次 OnEnable() 调用之后,只调用一次

我们来打印输出一下:

反复激活后可以看到 Start()只执行了一次。

3.4 Update()

Update() 每帧都会调用一次,帧数就是在1秒钟时间里传输的图片的数量 和电脑的性能有关

可以看到我刚运行一会就打印了一千多次了

3.5 LateUpdate()

LateUpdate(),看函数名就能猜出大概的作用,在 Update() 函数执行之后执行

3.6 FixedUpdate()

FixedUpdate() 每隔固定的时间间隔都会运行一次,和帧无关。

我第一次学这个函数的时候差点和 Update() 混了。


举个例子: 当用 Update() 函数的时候,关羽每秒可以砍 60 个人,而我每秒只能砍一个人还差点被反杀。

而当用 FixedUpdate() 函数的话我和关羽每秒砍的人数就一样了 约等于 我和关羽一样强(doge.jpg)


FixedUpdate() 函数默认每隔0.02秒执行一次。这里我们可以修改执行的时间间隔 ------ 在unity界面上边菜单栏里 编辑------》 项目设置 ------》 时间 ------》 固定时间步进

3.7 OnDisable()

非激活状态下调用一次,和OnEnable是相对的关系。OnEnable() 函数懂了大家这个也就懂了吧😃,我们反复激活,来打印输出一下看看

没错,就是大家想的那样,激活 OnEnable()就会执行一次,不激活OnDisable() 就会执行一次。

3.8 OnDestroy()

终于最后一个函数了,当组件销毁的时候被调用,比如进行移除组件操作,要死了写遗书。

我们来移除组件:

移除后 OnDestory 就会打印出来了

csharp 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Move : MonoBehaviour
{
    //组件挂载在实体上第一个执行的函数,庆祝诞生
    private void Awake()
    {
        Debug.Log("awake");
    }

    //在Awake执行之后执行,每次激活组件都会调用一次
    private void OnEnable()
    {
        Debug.Log("OnEnable");
    }

    //唯一调用的,调用时机是第一次 OnEnable 调用之后
    // Start is called before the first frame update
    void Start()
    {
        Debug.Log("Start");
        //Debug.Log("我是move脚本");
    }

    //每一帧都会调用一次,帧和电脑性能有关
    // Update is called once per frame
    void Update()
    {
        //Debug.Log("Update");
    }

    //Update每次执行完都会跟着执行一次
    private void LateUpdate()
    {
        //Debug.Log("LateUpdate");
    }

    //和帧无关,每隔固定的时间间隔都会运行一次,默认每隔0.02秒执行一次
    //在unity界面上边菜单栏里  编辑------》 项目设置 ------》 时间 ------》 固定时间步进
    private void FixedUpdate()
    {
        //Debug.Log("FixedUpdate");
    }

    //非激活状态下调用一次,和OnEnable是相对的关系
    private void OnDisable()
    {
        Debug.Log("OnDisable");
    }

    //当组件销毁的时候被调用,比如进行移除组件操作,要死了写遗书
    private void OnDestroy()
    {
        Debug.Log("OnDestroy");
    }
}

四、组件的执行顺序问题

通过组件的生命周期函数我们知道了8个方法在什么情况下会执行以及执行的顺序,那么组件与组件之间的执行顺序呢? 这是我们通过设置脚本执行顺序来控制的

我们再来创建一个脚本组件test,分别在Start方法里Log输出一下我是test脚本 和 我是Move脚本

然后把这两个组件挂载在同一个实体上,然后对执行顺序进行设置。

我们打印输出一下:设置的数值越小就越先执行

好了,到此本篇博客知识点全部讲完了,拜拜┏(^0^)┛

相关推荐
Thomas游戏开发3 天前
Unity3D 使用 ILRuntime 时的性能问题详解
前端·unity3d·游戏开发
留待舞人归8 天前
【Unity3D优化】AssetBundle的压缩格式优化
游戏·unity·游戏引擎·unity3d
Thomas游戏开发10 天前
Unity3D游戏排行榜制作与优化技术详解
前端框架·unity3d·游戏开发
Thomas_YXQ11 天前
Unity3D Shader 简析:变体与缓存详解
开发语言·前端·缓存·unity3d·shader
Thomas游戏开发12 天前
Unity3D 架构师如何处理大世界地图技术详解
前端框架·unity3d·游戏开发
Thomas游戏开发12 天前
Unity3D MMORPG 任务系统的架构与设计详解
前端框架·unity3d·游戏开发
jojo的奇妙前端23 天前
unity - 排行榜 - 头像(二)
unity3d
scott.cgi1 个月前
「Unity3D」在Unity中使用C#控制显示Android的状态栏
unity·unity3d·android状态栏·c#控制android状态栏·unity显示状态栏
Thomas_YXQ1 个月前
Unity3D项目开发中的资源加密详解
游戏·3d·unity·unity3d·游戏开发
Thomas_YXQ1 个月前
Unity3D 动态骨骼性能优化详解
开发语言·网络·游戏·unity·性能优化·unity3d