最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Unity3D中腳本的執(zhí)行順序和編譯順序

 更新時間:2014年11月11日 10:28:04   投稿:hebedich  
在Unity中可以同時創(chuàng)建很多腳本,并且可以分別綁定到不同的游戲?qū)ο笊希鼈兏髯远荚谧约旱纳芷谥羞\行。與腳本有關(guān)的也就是編譯和執(zhí)行啦,本文就來研究一下Unity中腳本的編譯和執(zhí)行順序的問題。

事件函數(shù)的執(zhí)行順序

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

我們可以做一個小實驗來測試一下:
在Hierarchy視圖中創(chuàng)建三個游戲?qū)ο?,在Project視圖中創(chuàng)建三條腳本,如下圖所示,然后按照順序?qū)⒛_本綁定到對應(yīng)的游戲?qū)ο笊希?


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

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;
        }
    }
}

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


接著我們再做一個測試,把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;
        }
    }
}

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


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

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

后臺的方法Awake、Update、LateUpdate等等,都是按照順序,等所有游戲?qū)ο笊夏_本中的Awake執(zhí)行完畢之后,再去執(zhí)行Start、Update、LateUpdate等方法的。

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

腳本的執(zhí)行順序然后我們來看看這樣一種情況:在腳本0的Awake方法中創(chuàng)建一個立方體對象,然后在腳本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);
    }
}

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

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

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

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


腳本的編譯順序

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

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

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

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


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

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

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

2、對于每一種腳本語言,根據(jù)腳本放置的位置(其實也部分根據(jù)腳本的作用,比如編輯器擴展腳本,就必須放在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

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

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

好了,到此為止,我們可以很容易地判斷出上面舉的實例中,腳本的編譯順序(實際上,我已經(jīng)把順序?qū)懺诹四_本的文件名中了)

小練習(xí)

一個Unity3d的工程中,最多可以產(chǎn)生多少個工程文件呢?

4*3*2=24

相關(guān)文章

  • 淺析C#中結(jié)構(gòu)與類的區(qū)別

    淺析C#中結(jié)構(gòu)與類的區(qū)別

    本文主要對C#結(jié)構(gòu)與類的區(qū)別進行簡要分析,文中舉了實例,便于理解,具有很好的參考價值,需要的朋友一起來看下吧
    2016-12-12
  • 利用Aspose.Word控件實現(xiàn)Word文檔的操作

    利用Aspose.Word控件實現(xiàn)Word文檔的操作

    偶然一次機會,一個項目的報表功能指定需要導(dǎo)出為Word文檔,因此尋找了很多篇文章,不過多數(shù)介紹的比較簡單一點,于是也參考了官方的幫助介紹,終于滿足了客戶的需求。下面我由淺入深來介紹這個控件在實際業(yè)務(wù)中的使用過程吧
    2013-05-05
  • C#實現(xiàn)六大設(shè)計原則之單一職責(zé)原則

    C#實現(xiàn)六大設(shè)計原則之單一職責(zé)原則

    這篇文章介紹了C#實現(xiàn)六大設(shè)計原則之單一職責(zé)原則的方法,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-02-02
  • C#一個方法返回多個值示例

    C#一個方法返回多個值示例

    這篇文章主要介紹了C#一個方法返回多個值示例,需要的朋友可以參考下
    2014-02-02
  • C#對JSON與對象的序列化與反序列化

    C#對JSON與對象的序列化與反序列化

    這篇文章介紹了C#對JSON與對象的序列化與反序列化,文中通過示例代碼介紹的非常詳細。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • C#使用Free Spire.Doc批量將Word轉(zhuǎn)換為PDF的使用方案

    C#使用Free Spire.Doc批量將Word轉(zhuǎn)換為PDF的使用方案

    在日常企業(yè)信息化項目中,批量文檔轉(zhuǎn)換是一個常見但容易被低估的環(huán)節(jié)例如,合同歸檔系統(tǒng)需要將海量 Word 文檔統(tǒng)一轉(zhuǎn)為 PDF,以便后續(xù)檢索、審計和防篡改,所以本文給大家介紹了C#使用Free Spire.Doc批量將Word轉(zhuǎn)換為PDF的使用方案,需要的朋友可以參考下
    2025-08-08
  • C#實現(xiàn)公式計算驗證碼的示例詳解

    C#實現(xiàn)公式計算驗證碼的示例詳解

    現(xiàn)在很多的平臺已經(jīng)不使用普通的數(shù)字、字母等驗證碼了,取而代之的是拼圖類、選圖類、旋轉(zhuǎn)類或者計算類的驗證碼。本文將利用C#實現(xiàn)一個公式計算驗證碼,感興趣的可以了解一下
    2022-10-10
  • C#中AS和IS關(guān)鍵字的用法

    C#中AS和IS關(guān)鍵字的用法

    這篇文章主要介紹了C#中AS和IS關(guān)鍵字的用法的相關(guān)資料,需要的朋友可以參考下
    2016-03-03
  • C#實現(xiàn)的上傳圖片、保存圖片、加水印、生成縮略圖功能示例

    C#實現(xiàn)的上傳圖片、保存圖片、加水印、生成縮略圖功能示例

    這篇文章主要介紹了C#實現(xiàn)的上傳圖片、保存圖片、加水印、生成縮略圖功能,結(jié)合實例形式較為詳細的分析了C#圖片上傳、保存、水印、縮略圖等相關(guān)操作技巧,需要的朋友可以參考下
    2019-02-02
  • C# 實現(xiàn)拖拉控件改變位置與大小的方法

    C# 實現(xiàn)拖拉控件改變位置與大小的方法

    下面小編就為大家分享一篇C# 實現(xiàn)拖拉控件改變位置與大小的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01

最新評論

凤山县| 景宁| 云林县| 宜春市| 库车县| 仁布县| 荥阳市| 喀什市| 乌拉特前旗| 静乐县| 宿迁市| 内黄县| 昭平县| 葵青区| 汉中市| 克东县| 包头市| 云南省| 泸水县| 信丰县| 永昌县| 保康县| 天台县| 三都| 沙洋县| 正宁县| 皋兰县| 年辖:市辖区| 兴仁县| 永顺县| 抚顺县| 东安县| 额济纳旗| 河东区| 修文县| 冷水江市| 徐州市| 沙洋县| 临桂县| 麦盖提县| 长垣县|