{
  "schemaVersion": "0.11.0",
  "canonical": "https://www.pystone.net/notes/unity-script-lifecycle-execution-order/",
  "atlas": "https://www.pystone.net/?node=unity-script-lifecycle-execution-order#knowledge-atlas",
  "markdown": "https://www.pystone.net/notes/unity-script-lifecycle-execution-order.md",
  "context": "https://www.pystone.net/notes/unity-script-lifecycle-execution-order.context.json",
  "knowledgeVersion": "224c990773de.5fa8af6e39fa",
  "build": {
    "siteCommit": "224c990773de166d23a886306577dd90379529ce",
    "notesCommit": "5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a",
    "builtAt": "1970-01-01T00:00:00.000Z",
    "version": "224c990773de.5fa8af6e39fa"
  },
  "id": "note:unity-script-lifecycle-execution-order",
  "slug": "unity-script-lifecycle-execution-order",
  "title": "关于脚本的生命周期、函数的执行顺序",
  "type": "note",
  "visibility": "public",
  "idStability": "rename-stable",
  "author": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "publisher": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "aliases": [],
  "summary": "关于脚本的生命周期、函数的执行顺序",
  "contentRole": "unspecified",
  "isMoc": false,
  "mocRecognition": "none",
  "generated": false,
  "attribution": "unspecified",
  "domain": "10-计算机、信息技术与工程",
  "tags": [],
  "mocs": [],
  "contentHash": "3cb1a57ea51e2f92128595bb1c9a7fbb8e4aebf98dd561740a516a1da35baba8",
  "assets": [],
  "headings": [
    {
      "depth": 1,
      "text": "关于脚本的生命周期、函数的执行顺序",
      "anchor": "关于脚本的生命周期函数的执行顺序",
      "citation": "https://www.pystone.net/notes/unity-script-lifecycle-execution-order/#%E5%85%B3%E4%BA%8E%E8%84%9A%E6%9C%AC%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%87%BD%E6%95%B0%E7%9A%84%E6%89%A7%E8%A1%8C%E9%A1%BA%E5%BA%8F"
    },
    {
      "depth": 2,
      "text": "Editor和Engine脚本的执行顺序",
      "anchor": "editor和engine脚本的执行顺序",
      "citation": "https://www.pystone.net/notes/unity-script-lifecycle-execution-order/#editor%E5%92%8Cengine%E8%84%9A%E6%9C%AC%E7%9A%84%E6%89%A7%E8%A1%8C%E9%A1%BA%E5%BA%8F"
    },
    {
      "depth": 2,
      "text": "例子",
      "anchor": "例子",
      "citation": "https://www.pystone.net/notes/unity-script-lifecycle-execution-order/#%E4%BE%8B%E5%AD%90"
    }
  ],
  "claims": [],
  "outgoing": [],
  "incoming": [
    {
      "id": "note:game-graphics-and-runtime",
      "title": "游戏图形与运行时",
      "url": "https://www.pystone.net/notes/game-graphics-and-runtime/",
      "atlas": "https://www.pystone.net/?node=game-graphics-and-runtime#knowledge-atlas",
      "label": "游戏图形与运行时",
      "origin": "explicit",
      "humanReviewed": true,
      "context": "Unity中的“关于脚本的生命周期、函数的执行顺序”导航项",
      "citation": "https://www.pystone.net/notes/game-graphics-and-runtime/#unity"
    }
  ],
  "contentMarkdown": "# 关于脚本的生命周期、函数的执行顺序\n\n> 创建时间：2020/7/24 16:39\n\n## Editor和Engine脚本的执行顺序\n\n在Editor中，非PlayMode下，编辑器执行函数会在一帧里面跑。\n进入PlayMode时，会Reload程序集（Assemblies），Reset脚本（Scripts），没有明确的回调函数可以注册，使Editor脚本中函数可以在刚进入PlayMode的时候调用。\n\n脚本使用`[InitializeOnLoad]`属性，可以使脚本可以在刚进入PlayMode的时候初始化（调用静态构造函数）。而这个初始化的时机处在开始进入PlayMode和真正开始Play之前，此时\n\n  * EditorApplication.isPlaying 为 false\n\n  * EditorApplication.isPlayingOrWillChangePlaymode 为 true\n\n  * Unity已经完成了程序集的Reload和脚本的Reset\n\n在此时实例化物体，Unity会报错：Some objects were not cleaned up when closing the scene. (Did you spawn new GameObjects from OnDestroy?)。\n这个时候实例化的物体加不到Hierarchy当中，但是会加载到内存当中，显示在Scene当中，Unity会判断内存当中有一块儿不属于当前场景的Object。 判断的结果类似于内存泄漏。\n\n因此，解决方法是，在Static 实例化方法中，使用`EditorApplication.update += Update`给编辑器程序的Update注册函数，想要执行的逻辑在Update当中执行，也就是在下一帧（完全进入Play Mode）时执行。\n静态初始化函数调用后到PlayMode第一次Update的时间段中，bu’y’h\n\n## 例子\n\n```csharp\nclass Program\n{\n    static void Main(string[] args)\n    {\n        dynamic dyn = 1;\n        object obj = 1;\n        dyn = dyn + 3;\n        //obj = obj + 3; 报错\n\n        // Rest the mouse pointer over dyn and obj to see their\n        // types at compile time.\n        System.Console.WriteLine(dyn.GetType());\n        System.Console.WriteLine(obj.GetType());\n    }\n}\n\n```\n"
}
