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_YXQ28 分钟前
Unity3D 测试驱动开发(TDD)框架设计
java·开发语言·驱动开发·全文检索·unity3d·lucene·tdd
Thomas游戏开发10 天前
Unity3D事件驱动架构设计指南
前端框架·unity3d·游戏开发
古力德13 天前
Unity中造轮子:定时器
c#·unity3d
Mapmost15 天前
【数据融合实战手册·进阶篇】模型融合总出错?先看看这些“对齐”了没!
unity3d
北桥苏17 天前
如何在 Unity3D 导入 Spine 动画
unity3d
Thomas游戏开发18 天前
Unity3D状态管理器实现指南
前端框架·unity3d·游戏开发
土豆宝23 天前
Unity Visual Scripting(可视化脚本) 自定义节点 踩坑教程
unity3d
Thomas游戏开发24 天前
Unity3D光照层级与动态切换指南
前端框架·unity3d·游戏开发
Thomas游戏开发1 个月前
Unity3D 崩溃分析工具的集成与优化
前端框架·unity3d·游戏开发
Thomas游戏开发1 个月前
Unity3D网格简化与LOD技术详解
前端框架·unity3d·游戏开发