Unity3D初学者经常把Awake和Start混淆。

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

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

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

例1:

  1. public class Test : MonoBehaviour {
  2. void Awake () {
  3. Debug.Log("Awake");
  4. enabled = false;
  5. }
  6. void Start () {
  7. Debug.Log("Start");
  8. }
  9. }

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

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

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

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

例2:

player.cs

  1. private Transform handAnchor = null;
  2. void Awake () { handAnchor = transform.Find("hand_anchor"); }
  3. // void Start () { handAnchor = transform.Find("hand_anchor"); }
  4. void GetWeapon ( GameObject go ) {
  5. if ( handAnchor == null ) {
  6. Debug.LogError("handAnchor is null");
  7. return;
  8. }
  9. go.transform.parent = handAnchor;
  10. }

other.cs

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

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

总结:我们尽量将其他Object的reference设置等事情放在Awake处理。然后将这些reference的Object的赋值设置放在Start()中来完成。
当MonoBehavior有定义[ExecuteInEditMode]时

当我们为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 这样的函数搜索它们。每个游戏物体上的Awke以随机的顺序被调用。因此,你应该用Awake来设置脚本间的引用,并用Start来传递信息。Awake总是在Start之前被调用。它不能用来执行协同程序。

Start()

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

[Unity3D]脚本中Start()和Awake()的区别的更多相关文章

  1. [Unity3D]脚本中Start()和Awake()的差别

    Unity3D刚開始学习的人常常把Awake和Start混淆. 简单说明一下,Awake在MonoBehavior创建后就立马调用,Start将在MonoBehavior创建后在该帧Update之前. ...

  2. unity3D脚本中,update ,fixupdate 和lateupdate的区别

    1.MonoBehaviour.Update 更新 当MonoBehaviour启用时,其Update在每一帧被调用. 2.MonoBehaviour.FixedUpdate 固定更新 当MonoBe ...

  3. Unity3d碰撞检测中碰撞器与触发器的区别

    要产生碰撞必须为游戏对象添加刚体(Rigidbody)和碰撞器,刚体可以让物体在物理影响下运动.碰撞体是物理组件的一类,它要与刚体一起添加到游戏对象上才能触发碰撞.如果两个刚体相互撞在一起,除非两个对 ...

  4. Unity3D中Update和Lateupdate的区别

    Unity中Update和Lateupdate的区别.Lateupdate和Update每一祯都被执行,但是执行顺序不一样,先执行Updatee然后执行lateUpdate. 如果你有两个脚本JS1. ...

  5. [置顶] perl脚本中defined,exists和delete关键字的用法和区别

    刚学习perl脚本的时候,喜欢频繁使用defined关键字判断一个hash中某个key是否存在,后来程序出了问题才去perl官方文档查看关于defined关键字的准确使用方法.因此,这里我把perl中 ...

  6. shell 脚本中双引号 单引号 反引号 的区别

    转自:http://blog.csdn.net/iamlaosong/article/details/54728393 最近要编个shell脚本处理数据,需要检测数据文件是否存在,文件名中包含日期,所 ...

  7. Unity3D 在自定义脚本中实现Button组件上的OnClick面板

    下述内容不对c#语法做过多讲解,仅对已入门并有兴趣的同学做为学习和拓展的资料 大家在Unity制作的过程中一定都使用过UI功能,那么很多人也一定见过这个面板: 那么我们如何能在自己的脚本中添加上像On ...

  8. [转]unity3d 脚本参考-技术文档

    unity3d 脚本参考-技术文档 核心提示:一.脚本概览这是一个关于Unity内部脚本如何工作的简单概览.Unity内部的脚本,是通过附加自定义脚本对象到游戏物体组成的.在脚本对象内部不同志的函数被 ...

  9. Unity3D脚本中文系列教程(八)

    ◆ static var matrix : Matrix4x4 描述:设置用于渲染所有gizmos的矩阵. 类方法 ◆ Static function DrawCube(center:Vector3, ...

随机推荐

  1. FineUI第八天----下拉列表控件

    下拉列表控件 3.模拟树的下拉列表: 其他的控件都跟Asp.net的差不多.

  2. 在mac上安装nodejs

    文章转载自我的个人博客  www.iwangzheng.com node.js最初是2009年发布的,目标是为聊实现事件驱动和非阻塞I/O的web服务器,应用的场景非常的广泛,有web服务器.实时应用 ...

  3. 秀尔算法:破解RSA加密的“不灭神话”

    RSA加密 VS 秀尔算法 作为RSA加密技术的终结者——“太多运算,无法读取”的秀尔算法(Shor’s algorithm)不是通过暴力破解的方式找到最终密码的,而是利用量子计算的并行性,可以快速分 ...

  4. KMP算法心得

    今天又看了一遍KMP,感觉真的懂了...就来这儿发一下心得吧. KMP算法其实就是暴力的改进版.让我们看看暴力的匹配. Original string: ababababcbbababababc Pa ...

  5. Linux下列格式化工具 - column

    [root@localhost ~]# mount/dev/sda2 on / type ext4 (rw)proc on /proc type proc (rw)sysfs on /sys type ...

  6. Java数据类型中String、Integer、int相互间的转换

    1.Integer转换成int的方法 Integer i;  int k = i.intValue(); 即Integer.intValue(); 2.int转换成Integer int i; Int ...

  7. js如何往数组Array中添加元素

    转载自:http://blog.sina.com.cn/s/blog_95fa28e60101mwup.html unshift:将参数添加到原数组开头,并返回数组的长度  pop:删除原数组最后一项 ...

  8. object-c学习笔记

    原文地址 最近开始学习object-c,分享一下学习oc的经验以及对oc的理解,其中难免会有错误,请大家理解. 对初学者来说,objective-c存在了很多令人费解的写法,当然也包括我! 我刚开始看 ...

  9. MFC添加鼠标相应事件

    Class View (类视图)窗口中选中 你要添加事件的类(比如C***View.CPP),切换到properties窗口. 点击上面的Message图标(在Event图标[一个闪电形状的图标] 右 ...

  10. jsp 格式化变量

    <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> <fmt:f ...