Awake在MonoBehavior创建后就立刻调用,Start将在MonoBehavior创建后在该帧Update之前,在该Monobehavior.enabled == true的情况下执行。

void Awake (){
//初始化函数,在游戏开始时系统自动调用。一般用来创建变量之类的东西。
}
void Start(){
//初始化函数,在所有Awake函数运行完之后(一般是这样,但不一定),在所有Update函数前系统自动条用。一般用来给变量赋值。
}

我们通常书写的脚本,并不会定义[ExecuteInEditMode]这个Attribute,所以Awake和Start都只有在Runtime中才会执行。


<例1:>

public class Test : MonoBehaviour {
void Awake () {
Debug.Log("Awake");
enabled = false;
} void Start () {
Debug.Log("Start");
}
}

以上代码,在Awake中我们调用了enabled = false; 禁止了这个MonoBehavior的update。由于Start, Update, PostUpdate等属于runtime行为的一部分,这段代码将使Start不会被调用到!

在游戏过程中,若有另外一组代码有如下调用:

Test test = go.GetComponent<Test>();
test.enabled = true;

这个时候,若该MonoBehavior之前并没有触发过Start函数,将会在这段代码执行后触发Start函数!


<例2:>
player.cs

private Transform handAnchor = null;
void Awake () {
  handAnchor = transform.Find("hand_anchor");
}
//void Start () {
//  handAnchor = transform.Find("hand_anchor");
//}
void GetWeapon ( GameObject go ) {
if ( handAnchor == null ) {
Debug.LogError("handAnchor is null");
return;
}
go.transform.parent = handAnchor;
}

other.cs

...
GameObject go = new GameObject("player");
player pl = go.AddComponent<player>(); // Awake invoke right after this!
pl.GetWeapon(weaponGO);
...

以上代码中,我们应该在player Awake的时候去为handAnchor赋值。如果我们将这步操作放在Start里,那么在other.cs中,当执行GetWeapon的时候就会出现handAnchor是null reference。

<总结:> 我们尽量将其他Object的reference设置等事情放在Awake处理。然后将这些reference的Object的赋值设置放在Start()中来完成。


当我们为MonoBehavior定义了[ExecuteInEditMode]后,我们还需要关心Awake和Start在编辑器中的执行状况。

当该MonoBehavior在编辑器中被赋于给GameObject的时候,Awake, Start 将被执行。
当Play按钮被按下游戏开始以后,Awake, Start 将被执行。
当Play按钮停止后,Awake, Start将再次被执行。
当在编辑器中打开包含有该MonoBehavior的场景的时候,Awake, Start将被执行。

值得注意的是,不要用这种方式来设定一些临时变量的存储(private, protected)。因为一旦我们触发Unity3D的代码编译,这些变量所存储的内容将被清为默认值。


下面再来看看Unity圣典中的解释。

Awake()
当一个脚本实例被载入时Awake被调用。Awake用于在游戏开始之前初始化变量或游戏状态。在脚本整个生命周期内它仅被调用一次。Awake在所有对象被初始化之后调用,所以你可以安全的与其他对象对话或用诸如 GameObject.FindWithTag 这样的函数搜索它们。每个游戏物体上的Awake以随机的顺序被调用。因此,你应该用Awake来设置脚本间的引用,并用Start来传递信息。Awake总是在Start之前被调用。它不能用来执行协同程序。

Start()
Start仅在Update函数第一次被调用前调用。Start在behaviour的生命周期中只被调用一次。它和Awake的不同是Start只在脚本实例被启用时调用。 你可以按需调整延迟初始化代码。Awake总是在Start之前执行。这允许你协调初始化顺序。


总结——个人理解

Awake

  • 初始化函数,游戏开始时系统自动调用
  • 一般用来声明变量
  • 所挂载的物体被激活时,才能被调用
  • 当被添加到物体身上时,就立即被调用
  • 无论该脚本组件是否激活,都会被调用
  • 所有的Awake函数被调用的先后顺序不一定(暂且存疑)
  • 在所有的Start函数之前被调用

Start

  • 初始化函数,在所有Awake函数运行完之后,Update函数首次运行之前,被调用
  • 一般用来给变量赋值
  • 所挂载的物体被激活时,才能被调用
  • 脚本在代码中被实例化时才开始调用
  • 只有该脚本组件被激活时,才能被调用

注意:只要场景中有已激活的物体身上承载该脚本,无论该脚本是否被激活,Awake函数都会被调用。但是只有脚本已被激活,Start函数才能被调用。

【Unity笔记】Awake()和Start()的区别的更多相关文章

  1. 【Unity笔记】碰撞器(Collision)与触发器(Trigger)的区别

    当碰撞器Collision组件身上的属性IsTrigger勾选为True时,该碰撞器就成了触发器. 区别:1.能够产生的回调和函数不同.碰撞器:MonoBehaviour.OnCollisionEnt ...

  2. (转)Unity笔记之编辑器(UnityEditor)

    在使用unity3d的过程中,时常会需要从场景中寻找或者调用一个对象,而Unity就提供了一个贴心的功能——拖拽.用鼠标拖一下中比写堆代码直观的多吧!但是Unity提供的远远不止这一丢丢,下面我们来简 ...

  3. Unity 笔记

    摄像机 Main Camera 跟随主角移动,不看 UI 剧情摄像机 当进入剧情时,可以关闭 main camera,启用剧情摄像机,不看 UI UI 摄像机 看 UI Unity编辑器常用的sett ...

  4. 学习笔记_Java get和post区别(转载_GET一般用于获取/查询资源信息,而POST一般用于更新资源信息)

    转载自:[hyddd(http://www.cnblogs.com/hyddd/)] 总结一下,      Get是向服务器发索取数据的一种请求      而Post是向服务器提交数据的一种请求,在F ...

  5. Java学习笔记--Collection和Collections的区别

    转自 http://pengcqu.iteye.com/blog/492196 比较Collection 和Collections的区别.   1.java.util.Collection 是一个集合 ...

  6. Unity扩展 四种Menu的区别

    [MenuItem("Tools\AddColor")] :  在Unity菜单中添加一种快捷,执行public static方式 [AddComponentMenu(" ...

  7. ES6笔记① var 和 let的区别

    let 和 var的区别    答:不同点在于作用域 1.(全局下)首先  let关键字声明的变量是这样写会导致错误. let声明的变量类似于”本地变量“,函数内如何不重新声明,还是会被改变 var ...

  8. 【Unity笔记】打包安卓APK时Build Setting中的三种Build System

    Internal(Default):Unity内置,仅需Android SDK支持.不能导出工程,适用于仅适用Unity开发的工程. Gradle(New):使用Gradle进行构建,需要Androi ...

  9. 【Unity笔记】静态碰撞体的陷阱

    概念 静态碰撞体(Static Collider):物体勾选为静态Static,有Collider组件,无Rigidbody组件. 静态碰撞体的陷阱 Unity在游戏初始化时,会把所有的静态碰撞体合并 ...

随机推荐

  1. 用 Qt Creator 开发非 Qt 的 C/C++ 程序

    在Windows还是习惯用VS2005但是现在到了Linux下,开发起来C/C++程序就没有那么得心应手的IDE了.虽然很多人推荐E开头那个主要作为Java开发的IDE,不过安上插件后感觉不大好,一个 ...

  2. 【laravel5.4】关键字【use】使用

    1.在namespace 和 class 之间使用,是引入类文件的意思,命名空间过长或者类文件同名,可以使用[as]区别 2.在class 类里面使用[use],是导入trait  类的意思,多继承的 ...

  3. 利用Aspose.BarCode生成条码

    生成条码有很多控件,大部分好的控件,做出来的条码精确清晰,但是往往该部分的控件费用都很高,这里推荐大家使用6.0版本的破解版,可以生成无水印,下方也可以不显示文字. 1.下图是 onbarcode 控 ...

  4. HDUOJ ------1398

    http://acm.hdu.edu.cn/showproblem.php?pid=1398 Square Coins Time Limit: 2000/1000 MS (Java/Others)   ...

  5. 学会快速装系统 图解硬盘分区软件Norton Ghost使用

    http://edu.itbulo.com/200909/126313_5.htm即使你拥有最先进的电脑,采用传统的方法,Windows的安装速度仍然是令人头痛的!有没有什么重装系统的简便方法呢?当然 ...

  6. Web前端开发必备工具推荐

    http://gaohaixian.blog.163.com/blog/static/12326010520114265223489/不管你做前端开发还是网页重构,前端工具都起着非常重要的作用,这里向 ...

  7. Android开发学习之浅谈显示Intent和隐式Intent

    Intent寻找目标组件的两种方式: 显式Intent:通过指定Intent组件名称来实现的,它一般用在知道目标组件名称的前提下,一般是在相同的应用程序内部实现的. 隐式Intent:通过Intent ...

  8. 非IE内核浏览器如何支持activex插件

    原文地址:https://blog.csdn.net/johnson2008t/article/details/46126605 之前在一个B/S项目中遇到一个需求,就是客户需要在页面上对报表的布局以 ...

  9. IIS6.0中布署MVC站点

    http://www.cnblogs.com/anny-1980/articles/2616657.html

  10. Android 实现 HttpClient 请求Https

    如题,默认下,HttpClient是不能请求Https的,需要自己获取 private static final int SET_CONNECTION_TIMEOUT = 5 * 1000; priv ...