【Unity基础知识】认识常用的生命周期函数(Awake、Start、Update...)
一、了解帧的概念
游戏的本质就是一个死循环
每一次循环都会处理游戏逻辑 并 更新一次游戏画面
之所以能看到画面在动 是因为
切换画面速度达到一定速度时
人眼就会认为画面是动态且流畅的
一帧就是执行了一次循环
Unity底层已经封装好了这个死循环
我们只需要利用Unity的生命周期函数的规则来执行游戏逻辑即可
FPS(Frames Per Second)
即每秒钟帧数
一般我们说60帧30帧
意思是1秒更新60次、30次画面
1s = 1000ms
60帧:1帧为 1000ms/60 ≈ 16.66ms
30帧:1帧为 1000ms/30 ≈ 33.33ms
游戏卡顿的原因:
跑1帧游戏逻辑的计算量过大,或者硬件性能过低,无法在一帧的时间内处理完所有游戏逻辑
二、生命周期函数的概念
所有继承MonoBehavior的脚本 最终都会挂载到GameObject游戏对象上
生命周期函数就是该脚本对象依附的GameObject对象从出生到消亡整个生命周期中
会通过反射自动调用的一些特殊函数
Unity帮助我们记录了一个GameObject对象依附了哪些脚本
会自动地得到这些对象,通过反射去执行一些固定名字的函数(就是生命周期函数)
三、生命周期函数
注意:
生命周期函数的访问修饰符一般为private和protected
因为不需要在外部手动调用生命周期函数,都是Unity自动帮我们调用

3-1.Awake
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lesson1 : MonoBehaviour
{
//当一个对象(自己这个类对象 而不是依附的GameObject)被创建时,会调用该生命周期函数
//作用:Awake是类似构造函数的存在,我们可以在一个类对象刚被创建时,进行一些初始化操作
//Awake只会被执行一次
private void Awake()
{
//补充知识点:在Unity中打印信息的两种方式
//1.如果没有继承MonoBehaviour,可以使用debug.Log();
Debug.Log("我是打印的信息");
Debug.LogWarning("警告!");
Debug.LogError("出错了!");
//2.如果继承了MonoBehaviour 有一个现成的方法可以实现打印
print("我是打印的信息");
}
}
3-2.OnEnable
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lesson1 : MonoBehaviour
{
//依附的GameObject对象每次被激活时 会被调用
//作用:想要当一个对象被激活时 进行一些逻辑处理,就可以写在本函数中
private void OnEnable()
{
print("我依附的GameObject被激活了");
}
}

3-2.Start
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lesson1 : MonoBehaviour
{
//从自己被创建出来后,第一次帧更新之前被调用
//作用:还是用于初始化信息的,但是它相对Awake来说,要执行的晚一些
// 因为它是在对象进行帧更新之前才会被执行
//一个对象只会调用一次
private void Start()
{
print("我在第1帧更新前被执行");
}
}
3-4.FixedUpdate
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lesson1 : MonoBehaviour
{
//固定间隔时间执行,间隔的时间可以设置
//作用:用于进行物理相关的更新(如碰撞检测)
// 它是每一帧都会执行的,但是这里的帧和游戏帧有点不同
private void FixedUpdate()
{
print("我会固定间隔时间循环执行");
}
}


3-5.Update
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lesson1 : MonoBehaviour
{
//逻辑帧更新
//每秒更新多少次是可以设置的,如果不设置 默认会以最快的速度更新
//作用:用于处理游戏核心逻辑更新
private void Update()
{
print("我一帧被执行一次");
}
}
3-6.LateUpdate
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lesson1 : MonoBehaviour
{
//每帧执行 于Update之后执行
//作用:一般用来处理摄像机位置更新相关内容
// 在Update和LateUpdate之间,Unity进行了一些处理,处理动画相关的更新
private void LateUpdate()
{
print("我每针都会被执行,但晚于Update");
}
}
3-7.OnDisable
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lesson1 : MonoBehaviour
{
//依附的GameObject对象每次失活时被调用(对象被销毁时也会被调用)
//作用:想要当一个对象失活时 进行一些逻辑处理,就可以写在本函数中
private void OnDisable()
{
print("我依附的GameObject失活了");
}
}

3-8.OnDestroy
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lesson1 : MonoBehaviour
{
//对象被销毁时被调用(依附的GameObject对象被删除时)
private void OnDestroy()
{
print("我被销毁了");
}
}
四、生命周期函数支持继承和多态

Lesson1的脚本如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lesson1 : MonoBehaviour
{
//把Awake写成一个虚函数
protected virtual void Awake()
{
print("父类的Awake");
}
}
Lesson1Son的脚本如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lesson1Son : Lesson1
{
//可以重写父类Lesson1的虚函数
protected override void Awake()
{
base.Awake();
print("子类的Awake");
}
}

运行:可以看到,父类的Awake和子类的Awake都被执行了,所以生命周期函数支持继承和多态

五、补充:关于继承Mono的类的构造函数
要知道,虽然不建议在继承MonoBehavior的类中写构造函数
但是不意味着不能写,当在继承MonoBehavior的类中写无参构造函数时
会发现在编辑模式下或者运行后,只要该脚本挂载在场景中,那么该无参构造函数是会被自动执行
因为Unity的工作原理中提到的反射机制,实际上Unity通过反射帮助我们实例化了该脚本对象
既然要实例化那么肯定是需要new的,只不过Unity中不需要我们自己new继承了MonoBehavior的类,只要挂载后Unity就帮助我们做了这件事
那么为什么不建议继承MonoBehavior的类写构造函数呢?
1.Unity的规则就是,继承MonoBehavior的脚本不能new只能挂载
2.生命周期函数的Awake是类似构造函数的存在,当对象出生就会自动调用
3.写构造函数反而在结构上会破坏Unity设计上的规范
总结:
如果继承MonoBehavior的脚本想要进行初始化相关,可以在Awake或者Start中进行,搞清这两个生命周期函数的执行时机,根据需求选择在哪里进行初始化。
切记!!继承MonoBehavior的脚本不要new,不要new,不要new!!
六、补充:不同对象的声明周期函数是在同一个线程中执行的吗?
Unity中所有对象上挂载的生命周期函数都是在一个主线程中按先后执行的
Unity会主动把场景上的对象,对象上挂载的脚本都统统记录下来,
在主线程的死循环中,按顺序按时机的通过反射,执行记录的对象身上挂载的脚本的对应生命周期函数
【Unity基础知识】认识常用的生命周期函数(Awake、Start、Update...)的更多相关文章
- Shell编程(二)——shell的基础知识及常用命令
shell的基础知识 一.bash有以下特点: 1.记录命令历史 2.指令和文件名补全 3.别名 alias rm='rm -i' 4.通配符 * 0个或多个字符 ?匹配一个字符 5 输入输出重定向 ...
- 【Unity基础知识】基础游戏单位GameObject中常用的属性和API
一.GameObject中的成员变量 主要思想:得到该脚本依附的GameObject的相关信息 现有: Lesson4的代码: using System.Collections; using Syst ...
- Unity基础知识学习笔记一
1,Unity 4.5.4这个版本,在打包ios应用程序的时候.会生成一个xcode工程,但是这个工程无法在xcode6上变异,无法生成ios8上发布.所以unity在ios8发布3天内就发了4. ...
- Unity基础知识学习笔记二
1,object Instantiate(object original,Vector3 position,Quaternion rotation) 克隆原始物体,并返回克隆物体. ...
- loadrunder之脚本篇——脚本基础知识和常用操作
1)编码工具设置 自动补全输入Tools->General Options->Environment->Auto complete word 显示功能语法Tools->Genr ...
- Hive HiveQL基础知识及常用语句总结
基础语句 CREATE DROP 建表.删表 建表 -------------------------------------- -- 1. 直接建表 ------------------------ ...
- MySQL基础知识和常用命令总结
说明:以下内容是阅读书籍<<MySQL必知必会>>的摘要和总结 检索数据 排序检索数据 过滤数据 使用通配符过滤 使用正则表达式进行搜索 创建计算字段 使用数据处理函数 汇总数 ...
- Git基础知识与常用命令
一:相关概念: 1:工作区(Working Directory): 就是你在电脑里能看到的目录 2:版本库(Repository): 工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库. ...
- 【Unity基础知识之三】Unity Assets目录下的特殊文件夹名称
Unity3D的特殊目录名称 Unity预留了一些目录名称,这些目录有着特殊的含义.比较重要的有: Resources这个目录下的所有文件都会被打包到发布版本中,程序可以通过文件路径来访问它们.这 ...
随机推荐
- systemd进程管理工具实战教程
关注「开源Linux」,选择"设为星标" 回复「学习」,有我为您特别筛选的学习资料~ 1. systemd介绍 systemd是目前Linux系统上主要的系统守护进程管理工具,由于 ...
- CRM项目的整理---第一篇
CRM:cunstomer relationship management 客户管理系统 1.项目的使用者:销售 班主任 讲师 助教 2.项目的需求分析 2.1.注册 2.2.登录 2.3 ...
- .NET 中 GC 的模式与风格
垃圾回收(GC)是托管语言必备的技术之一.GC 的性能是影响托管语言性能的关键.我们的 .NET 既能写桌面程序 (WINFROM , WPF) 又能写 web 程序 (ASP.NET CORE),甚 ...
- wsgiref模块、web框架、django框架简介
"""web框架:将前端.数据库整合到一起的基于互联网传输的python代码 web框架也可以简单的理解为是软件开发架构里面的'服务端'""" ...
- 软件开发架构,网络编程简介,OSI七层协议,TCP和UDP协议
软件开发架构 什么是软件开发架构 1.软件架构是一个系统的草图. 2.软件架构描述的对象是直接构成系统的抽象组件. 3.各个组件之间的连接则明确和相对细致地描述组件之间的通讯. 4.在实现阶段,这些抽 ...
- vivo 万台规模 HDFS 集群升级 HDFS 3.x 实践
vivo 互联网大数据团队-Lv Jia Hadoop 3.x的第一个稳定版本在2017年底就已经发布了,有很多重大的改进. 在HDFS方面,支持了Erasure Coding.More than 2 ...
- PPP PPOE详解
PPP协议是在串行线IP协议SLIP(Serial Line Internet Protocol)的基础上发展起来的.由于SLIP协议具有只支持异步传输方式.无协商过程(尤其不能协商如双方IP地址等网 ...
- Android 12(S) 图像显示系统 - GraphicBuffer同步机制 - Fence
必读: Android 12(S) 图像显示系统 - 开篇 一.前言 前面的文章中讲解Android BufferQueue的机制时,有遇到过Fence,但没有具体讲解.这篇文章,就针对Fence这种 ...
- 【NodeJS】替换模糊查询字符里包含的正则关键字
问题:正则匹配时字符串中包含了一些特殊字符,导致查询失败 例如,下面的字符包含了( 和 ),这在正则中属于特殊字符 (-)-magnocurarine 正则中的特殊字符如下图 思路: 1.映射查询字符 ...
- 场景实践:使用RDS和ECS搭建个人博客
体验简介 本教程将使用一台基础环境为CentOS7.7的云服务器ECS实例, 搭配您已有的云数据库RDS实例,帮助您快速搭建属于自己的云上博客. 背景知识 本场景主要涉及以下云产品和服务: 阿里云关系 ...