亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

Unity3D中腳本的執行順序和編譯順序

2020-01-24 02:17:09
字體:
來源:轉載
供稿:網友

事件函數的執行順序

先說一下執行順序吧。
官方給出的腳本中事件函數的執行順序如下圖:

我們可以做一個小實驗來測試一下:
在Hierarchy視圖中創建三個游戲對象,在Project視圖中創建三條腳本,如下圖所示,然后按照順序將腳本綁定到對應的游戲對象上:


三條腳本的代碼完全一樣,只是做了一點名稱上的區分:

using UnityEngine;
using System.Collections;
public class Scring0 : MonoBehaviour
{
    void Awake()
    {
        Debug.Log("Script0 ======= Awake");
    }
    bool isUpdate = false;
    void Update()
    {
        if(!isUpdate)
        {
            Debug.Log("Script0 ======= Update");
            isUpdate = true;
        }
    }
    bool isLateUpdate = false;
    void LateUpdate()
    {
        if(!isLateUpdate)
        {
            Debug.Log("Script0 ======= LateUpdate");
            isLateUpdate = true;
        }
    }
}

播放游戲,看看它們的執行順序。如下圖所示,Awake、Update、LateUpdate,無論運行游戲多少次,它們的執行順序是完全一樣的。


接著我們再做一個測試,把Script0的Update方法注釋掉?。?

using UnityEngine;
using System.Collections;
public class Script0 : MonoBehaviour
{
    void Awake ()
    {
        Debug.Log("Script0 ========= Awake");
    }
//  bool isUpdate = false;
//  void Update ()
//  {
//      if(!isUpdate)
//      {
//          Debug.Log("Script0 ========= Update");
//          isUpdate = true;
//      }
//  }
    bool isLateUpdate = false;
    void LateUpdate()
    {
        if(!isLateUpdate)
        {
            Debug.Log("Script0 ========= LateUpdate");
            isLateUpdate = true;
        }
    }
}

再次運行游戲,看看它的結果。腳本的執行順序和以前完全一樣,Script0即便刪除掉了Update方法,但是它也不會直接執行LateUpdate方法,而是等待Script1和Script2中的Update方法都執行完畢以后,再去執行所有的LateUpdate方法。


通過這兩個例子,我們就可以很清楚地斷定,Unity后臺是如何執行腳本的了。每個腳本的Awake、Start、Update、LateUpdate、FixedUpdate等等,所有的方法在后臺都會被匯總到一起:

后臺的Awake()
{
    // 這里暫時按照上圖中的腳本執行順序,后面會談到其實可以自定義該順序的
    腳本2中的Awake();
    腳本1中的Awake();
    腳本0中的Awake();
}

后臺的方法Awake、Update、LateUpdate等等,都是按照順序,等所有游戲對象上腳本中的Awake執行完畢之后,再去執行Start、Update、LateUpdate等方法的。

后臺的Update()
{
    // 這里暫時按照上圖中的腳本執行順序,后面會談到其實可以自定義該順序的
    腳本2中的Update();
    腳本1中的Update();
    腳本0中的Update();
}

腳本的執行順序然后我們來看看這樣一種情況:在腳本0的Awake方法中創建一個立方體對象,然后在腳本2的Awake方法中去獲取這個立方體對象。代碼如下:

// Script0.cs
using UnityEngine;
using System.Collections;
public class Script0 : MonoBehaviour
{
    void Awake ()
    {
        GameObject.CreatePrimitive(PrimitiveType.Cube);
    }
}
// Script2.cs
using UnityEngine;
using System.Collections;
public class Script2 : MonoBehaviour
{
    void Awake ()
    {
        GameObject go = GameObject.Find("Cube");
        Debug.Log(go.name);
    }
}

如果腳本的執行順序是先執行Script0,然后再執行Script2,那么Script2中的Awake就可以正確地獲取到該立方體對象;可是如果腳本的執行順序是先執行Script2,然后是Script0,那么Script2肯定會報空指針錯誤的。

那么實際項目中的腳本會非常多,它們的先后執行順序我們誰也不知道(有人說是按照棧結構來執行的,即后綁定到游戲對象上的腳本先執行。這一點可以從上面的例子中得到,但官方并沒有這么說,還得進一步深入研究)。但一般的,建議在Awake方法中創建游戲對象或Resources.Load(Prefab)對象,然后在Start方法中去獲取游戲對象或者組件,因為事件函數的執行順序是固定的,這樣就可以確保萬無一失了。
另外,Unity也提供了一個方法來設置腳本的執行順序,在Edit -> Project Settings -> Script Execution Order菜單項中,可以在Inspector面板中看到如下圖所示:

點擊右下角的"+"將彈出下拉窗口,包括游戲中的所有腳本。腳本添加完畢后,可以用鼠標拖動腳本來為腳本排序,腳本名后面的數字也越小,腳本越靠上,也就越先執行。其中的Default Time表示沒有設置腳本的執行順序的那些腳本的執行順序。

按照上面這張圖的設置,我們再來看一下控制臺的輸出結果,來確認一下我們的設置是否起作用(注意:把Script0腳本中的Update方法取消注釋):


腳本的編譯順序

關于腳本的編譯順序很是頭疼,官方的說法有點模糊,請看官方的解釋:

由于腳本的編譯順序會涉及到特殊文件夾,比如上面提到的Plugins、Editor還有Standard Assets等標準的資源文件夾,所以腳本的放置位置就非常重要了。下面用一個例子來說明不同文件夾中的腳本的編譯順序:

實際上,如果你細心的話會發現,如果在你的項目中建立如上圖所示的文件夾層次結構時,編譯項目之后會在項目文件夾中生成一些文件名中包含Editor、firstpass這些字樣的項目文件。比如按照上圖的文件夾結構,我們打開項目文件夾來看一下產生的項目文件是什么樣的?

下面就來詳細探討一下這些個字樣是什么意思?它們與腳本的編譯順序有著怎樣的聯系?


1、首先從腳本語言類型來看,Unity3d支持3種腳本語言,都會被編譯成CLI的DLL

如果項目中包含有C#腳本,那么Unity3d會產生以Assembly-CSharp為前綴的工程,名字中包含”vs”的是產生給Vistual Studio使用的,不包含”vs”的是產生給MonoDevelop使用的。
項目中的腳本語言 工程前綴 工程后綴 C# Assembly-CSharp csproj UnityScript Assembly-UnityScript unityproj Boo Assembly-Boo booproj

如果項目中這三種腳本都存在,那么Unity將會生成3種前綴類型的工程。

2、對于每一種腳本語言,根據腳本放置的位置(其實也部分根據腳本的作用,比如編輯器擴展腳本,就必須放在Editor文件夾下),Unity會生成4中后綴的工程。其中的firstpass表示先編譯,Editor表示放在Editor文件夾下的腳本。

在上面的示例中,我們得到了兩套項目工程文件:分別被Virtual Studio和MonoDevelop使用(后綴包不包含vs),為簡單起見,我們只分析vs項目。得到的文件列表如下:
Assembly-CSharp-filepass-vs.csproj
Assembly-CSharp-Editor-filepass-vs.csproj
Assembly-CSharp-vs.csproj
Assembly-CSharp-Editor-vs.csproj

根據官方的解釋,它們的編譯順序如下:
(1)所有在Standard Assets、Pro Standard Assets或者Plugins文件夾中的腳本會產生一個Assembly-CSharp-filepass-vs.csproj文件,并且先編譯;
(2)所有在Standard Assets/Editor、Pro Standard Assets/Editor或者Plugins/Editor文件夾中的腳本產生Assembly-CSharp-Editor-filepass-vs.csproj工程文件,接著編譯;
(3)所有在Assets/Editor外面的,并且不在(1),(2)中的腳本文件(一般這些腳本就是我們自己寫的非編輯器擴展腳本)會產生Assembly-CSharp-vs.csproj工程文件,被編譯;
(4)所有在Assets/Editor中的腳本產生一個Assembly-CSharp-Editor-vs.csproj工程文件,被編譯。

之所以按照這樣建立工程并按此順序編譯,也是因為DLL間存在的依賴關系所決定的。

好了,到此為止,我們可以很容易地判斷出上面舉的實例中,腳本的編譯順序(實際上,我已經把順序寫在了腳本的文件名中了)

小練習

一個Unity3d的工程中,最多可以產生多少個工程文件呢?

4*3*2=24

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产成人精品在线观看| 欧美成人免费小视频| 国产成人精品视频在线| 日韩中文在线视频| 久久久97精品| 欧美一级片一区| 久久久亚洲国产| 欧美视频在线观看免费网址| 欧美一级免费视频| 国产亚洲欧美视频| 亚洲aaaaaa| 成人写真视频福利网| 欧美大人香蕉在线| 亚洲人成77777在线观看网| 在线观看免费高清视频97| 日韩精品极品在线观看| 欧美视频第一页| 中文字幕日韩在线播放| 91免费视频国产| 自拍偷拍免费精品| 亚洲乱码av中文一区二区| 欧美精品一区二区免费| 日韩国产高清视频在线| 97福利一区二区| 日韩一区二区久久久| 成人免费午夜电影| 色诱女教师一区二区三区| 久久久久久久网站| 日韩一级裸体免费视频| 亚洲aⅴ男人的天堂在线观看| 91亚洲精品久久久| 国产午夜精品美女视频明星a级| 国产日韩欧美视频| 久久久久国产一区二区三区| 日韩欧美中文在线| 欧美大人香蕉在线| 国外视频精品毛片| 日韩欧美在线视频日韩欧美在线视频| 欧美性少妇18aaaa视频| 欧美高跟鞋交xxxxhd| 国产欧美精品xxxx另类| 亚洲综合av影视| 欧美激情精品久久久久久免费印度| 国产精品aaa| 日韩在线观看免费高清| 欧美日产国产成人免费图片| 九九热在线精品视频| 亚洲精品日韩久久久| 91免费精品视频| 欧美日韩精品在线播放| 国产欧美一区二区三区四区| 91精品视频在线| 国产一区二区三区三区在线观看| 一个色综合导航| 国产精品一区二区av影院萌芽| 亚州国产精品久久久| 成人精品网站在线观看| 欧美日韩国产专区| 中文字幕日韩欧美| 91高清免费视频| 久久99久国产精品黄毛片入口| 国产精品极品美女在线观看免费| 亚洲一区国产精品| 日产日韩在线亚洲欧美| 情事1991在线| 国产精品视频区| 国产高清在线不卡| 日本精品在线视频| 国产精品永久免费在线| 日韩欧美精品网站| 性欧美办公室18xxxxhd| 中文字幕av一区| 精品久久久久久亚洲精品| 中文字幕久热精品视频在线| 欧美精品videos另类日本| 97超级碰碰人国产在线观看| 欧美精品久久久久久久免费观看| www.久久撸.com| 在线播放精品一区二区三区| 成人欧美一区二区三区在线湿哒哒| 91免费电影网站| 成人黄色av网站| 国产欧美日韩丝袜精品一区| 亚洲伊人第一页| 欧美高跟鞋交xxxxxhd| 欧美视频在线免费| 欧美专区在线观看| 超碰97人人做人人爱少妇| 久久亚洲精品一区二区| 91在线免费观看网站| 久热在线中文字幕色999舞| 亚洲欧美日本另类| 国产小视频国产精品| 一区二区欧美日韩视频| 国产精品久久国产精品99gif| 日韩av网址在线观看| 欧美亚洲激情视频| 国产精品日日摸夜夜添夜夜av| 在线观看久久av| 亚洲国产精品电影在线观看| 欧美日韩一区二区在线| 日韩欧美精品免费在线| 国产97免费视| 最新91在线视频| 性夜试看影院91社区| 国语自产精品视频在线看| 精品久久久久久久久久久久久| 亚洲aⅴ日韩av电影在线观看| 亚洲国产91精品在线观看| 91国偷自产一区二区三区的观看方式| 亚洲qvod图片区电影| 亚洲第一区在线观看| 欧美日韩国产一区中文午夜| 国产精品久久久久久久9999| 成人看片人aa| 不卡在线观看电视剧完整版| 欧美极品少妇xxxxⅹ喷水| 国产精品免费小视频| 国产精品视频网址| 亚洲欧美一区二区三区久久| 久久久久久久激情视频| 日韩av在线网址| 欧美性猛交xxxx乱大交| 最新日韩中文字幕| 欧美黄色小视频| 成人精品网站在线观看| 日韩精品免费在线视频| 久久精品中文字幕| 岛国av一区二区在线在线观看| 91av网站在线播放| 亚洲精品久久久久久久久久久久久| 亚洲欧美国产制服动漫| 91在线高清免费观看| 国产999精品久久久| 亚洲最大福利视频| 国产69久久精品成人| 国产精品日韩一区| 国产一区二区三区高清在线观看| 亚洲在线视频福利| 另类天堂视频在线观看| 中文字幕日韩精品有码视频| 欧美日韩亚洲视频一区| 亚洲自拍偷拍福利| 5252色成人免费视频| 97视频com| 亚洲国产精品字幕| 久久综合色影院| 91社区国产高清| 亚洲国产精品久久久| 91精品国产91久久久久久吃药| 午夜精品蜜臀一区二区三区免费| www.日韩av.com| 在线午夜精品自拍| 日韩欧美综合在线视频| 日韩视频免费在线| 欧美性猛交xxxx富婆| 日韩av在线精品| 亚洲奶大毛多的老太婆| 日韩中文av在线| 91久久国产精品91久久性色| 日韩欧美有码在线| 美女福利精品视频| 亚洲自拍偷拍第一页| 国产日韩精品在线播放|