1. 程式人生 > >Unity3D 官方教程:WebGL(二)

Unity3D 官方教程:WebGL(二)

部署壓縮工程

當你在釋出模式下構建WebGL專案時,Unity會將你工程的輸出檔案進行壓縮,以降低工程下載的份量。你可以在釋出設定中的壓縮格式選項裡,選擇壓縮的型別(選單:Edit->Project Settings -> Player -> Publishing Settings):

  • gzip:這是預設選項。gzip檔案比Brotli檔案更大,但構建速度更快,並且被所有瀏覽器在http協議和https協議都原生支援。檔名會有.gzip的額外字尾。
  • Brotli:Brotli壓縮提供了最棒的壓縮率。Brotli壓縮檔案明顯比gzip檔案小,但會花很長時間來壓縮,增加了你釋出版工程的迭代時間。Brotli押送被Chrome和Firefox在https協議中原生支援(檢視WebGL瀏覽器相容性來獲得更多資訊)。Brotli壓縮檔案會有.br字尾。
  • Disabled:這禁用了壓縮功能。如果你希望在預處理指令碼中實現你自己的壓縮,使用這個選項。

壓縮構建的Unity工程可以在任何瀏覽器上工作。Unity 包含了一個用JavaScript編寫的軟體解壓器,當伺服器端不啟用http壓縮傳輸時,它會回退。資料被瀏覽器從伺服器上下載,並且被Unity的載入器程式碼所解壓縮。當這些完成時,在你瀏覽器的JavaScript控制檯中出現資訊(包含了你的檔名而不是這裡的例子):

82毫秒完成解壓縮<Example/MyProject.jsgz>。如果你設定網頁瀏覽器使用壓縮來管理檔案,你可以移除這個延遲。

這裡,82毫秒只是個例子;花費的毫秒數量依賴於內容大小,以及計算機的速度。更大的工程花費更長的解壓縮時間,更快的計算機消耗更少的時間。將解壓縮時間打出,以提示你:你可以通過讓瀏覽器掌控解壓縮,來節約多少啟動時間。

進階:瀏覽器本地解壓

瀏覽器可以在它下載Unity工程的資料時就在本地進行解壓。這有避免了因在JavaScript中解壓縮檔案而產生額外延遲的好處,減少了啟動時間。為了讓瀏覽器進行本地解壓,需要配置網頁伺服器用正確的http頭提供壓縮檔案:這告訴瀏覽器,資料使用gzip或者Brotli方式壓縮,從而瀏覽器在資料開始傳輸時就解壓。Brotli壓縮被Firefox和Chrome僅在https協議中支援,而gzip壓縮被所有瀏覽器支援。檢視WebGL browser compatibility 來獲取更多資訊。

設定網頁伺服器

對瀏覽器本地解壓的設定過程依賴於你的網頁伺服器。本頁的說明適用於兩種最主流的網頁伺服器,Apache和IIS。注意,這些在預設設定下可用,但可能需要調整以匹配你的個性化設定。尤其,如果你已經有了另一個伺服器端配置來壓縮本地檔案時,可能會有妨礙這裡設定的問題。

Apache

Apache使用不可見的.htaccess檔案進行伺服器設定。下方的樣例程式碼展示了一個.htaccess檔案的例子,你可以放進你的發行目錄來配置Apache,以掌控你的壓縮檔案。

<IfModule mod_rewrite.c>

  <IfModule mod_mime.c>

Options +SymLinksIfOwnerMatch

RewriteEngine on

RewriteCond %{HTTP:Accept-encoding} br

RewriteCond %{REQUEST_FILENAME}br -f

RewriteRule ^(.*)\.(js|data|mem|unity3d)$ $1.$2br [L]

AddEncoding br .jsbr

AddEncoding br .databr

AddEncoding br .membr

AddEncoding br .unity3dbr


RewriteCond %{HTTP:Accept-encoding} gzip

RewriteCond %{REQUEST_FILENAME}gz -f

RewriteRule ^(.*)\.(js|data|mem|unity3d)$ $1.$2gz [L]

AddEncoding gzip .jsgz

AddEncoding gzip .datagz

AddEncoding gzip .memgz

AddEncoding gzip .unity3dgz


  </IfModule>

</IfModule>

當Apache接收到一個對檔案的請求(例如Release/mgame.js),這裡的配置檢查,客戶端是否允許Brotli-編碼的資料(RewriteCond %{HTTP:Accept-encoding} br),然後檢查在 Release/mygame.jsb**r 是否有檔案 (RewriteCond %{REQUEST_FILENAME}br -f)。如果兩種情況都匹配,Apach重寫請求到.jsbr檔案中,並響應。AddEncoding br .jsbr 通知Apache通過新增頭部來告訴客戶端,檔案使用Brotli編碼。
隨後的樣例程式碼塊對gzip做相同設定。因此,如果 Release/mygame.jsgz 檔案存在、但Brotli壓縮的條件不成立,Apache會用.gzip格式檔案處理。

IIS

IIS使用web.config檔案進行伺服器配置。以下樣例程式碼展示了一個web.config檔案的例子,你可以放到你的Release目錄中來配置IIS如何處理壓縮檔案。
為了使用這個,你需要安裝Microsoft的IIS URL Rewrite IIS 模組;否則,瀏覽器會丟擲一個500 內部伺服器錯誤。如果你沒有安裝這個模組,你扔可以使用這個檔案,但沒有在< rewrite>和< /rewrite>之間的程式碼。這無法讓壓縮傳輸可用,但讓IIS可以處理檔案擴充套件。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>

    <staticContent>

        <remove fileExtension=".mem" />

        <remove fileExtension=".data" />

        <remove fileExtension=".unity3d" />

        <remove fileExtension=".jsbr" />

        <remove fileExtension=".membr" />

        <remove fileExtension=".databr" />

        <remove fileExtension=".unity3dbr" />

        <remove fileExtension=".jsgz" />

        <remove fileExtension=".memgz" />

        <remove fileExtension=".datagz" />

        <remove fileExtension=".unity3dgz" />

        <mimeMap fileExtension=".mem" mimeType="application/octet-stream" />

        <mimeMap fileExtension=".data" mimeType="application/octet-stream" />

        <mimeMap fileExtension=".unity3d" mimeType="application/octet-stream" />

        <mimeMap fileExtension=".jsbr" mimeType="application/octet-stream" />

        <mimeMap fileExtension=".membr" mimeType="application/octet-stream" />

        <mimeMap fileExtension=".databr" mimeType="application/octet-stream" />

        <mimeMap fileExtension=".unity3dbr" mimeType="application/octet-stream" />

        <mimeMap fileExtension=".jsgz" mimeType="application/octet-stream" />

        <mimeMap fileExtension=".memgz" mimeType="application/octet-stream" />

        <mimeMap fileExtension=".datagz" mimeType="application/octet-stream" />

        <mimeMap fileExtension=".unity3dgz" mimeType="application/octet-stream" />

    </staticContent>

    <rewrite>

        <rules>

            <rule name="Append br suffix to WebGL content requests">

                <match url="(.*)\.(js|data|mem|unity3d)$" />

                <conditions>

                    <add input="{HTTP_ACCEPT_ENCODING}" pattern="br" />

                    <add input="{REQUEST_FILENAME}br" matchType="IsFile" />

                </conditions>

                <action type="Rewrite" url="{R:1}.{R:2}br" />

            </rule>

            <rule name="Append gz suffix to WebGL content requests">

                <match url="(.*)\.(js|data|mem|unity3d)$" />

                <conditions>

                    <add input="{HTTP_ACCEPT_ENCODING}" pattern="gzip" />

                    <add input="{REQUEST_FILENAME}gz" matchType="IsFile" />

                </conditions>

                <action type="Rewrite" url="{R:1}.{R:2}gz" />

            </rule>

        </rules>

        <outboundRules>

            <rule name="Append br Content-Encoding header to the rewritten responses">

                <match serverVariable="RESPONSE_Content-Encoding" pattern=".*" />

                <conditions>

                    <add input="{REQUEST_FILENAME}" pattern="\.(js|data|mem|unity3d)br$" />

                </conditions>

                <action type="Rewrite" value="br" />

            </rule>

            <rule name="Append gzip Content-Encoding header to the rewritten responses">

                <match serverVariable="RESPONSE_Content-Encoding" pattern=".*" />

                <conditions>

                    <add input="{REQUEST_FILENAME}" pattern="\.(js|data|mem|unity3d)gz$" />

                </conditions>

                <action type="Rewrite" value="gzip" />

            </rule>

        </outboundRules>

    </rewrite>

</system.webServer>


如果這些擴充套件可以在更高一級的目錄結構中被覆蓋,你只需要 《remove fileExtension=”.*” 》這一行。

WebGL工程的除錯及問題捕獲

Unity WebGL內容無法正確地被除錯用MonoDevelop或者Visual Studio,這讓你很難找出到底是什麼東西出錯了。這裡有些提示關於如何從你的工程中獲得資訊。

瀏覽器的JavaScript控制檯

Unity WebGL 沒有對你檔案系統的存取,所以無法像其它平臺那樣寫入一個日誌檔案。然而,它會將所有可能寫入日誌的資訊(例如Debug.Log,Console.WriteLine 或者Unity的內部日誌)寫到瀏覽器的JavaScript控制檯中。

  • 對於Firefox,你可以通過在Windows系統中按下Ctrl-Shift-K 、或者在Mac中按下 Command-Option-K 開啟JavaScript控制檯。
  • 對於Chrome,你可以通過在Windows系統中按下 Ctrl-Shift-J 、或者在Mac中按下Command-Option-J 開啟JavaScript控制檯。
  • 對於Safari,你可以通過在Preferences中的Advanced表內啟用開發選單,然後按下 Command-Option-C來開啟JavaScript控制檯。
  • 對於Microsoft Edge 或者Internet Explorer,你可以通過按下F12來開啟JavaScript控制檯。

開發模式工程

出於除錯目的,你可能希望在Unity中建立一個開發模式的工程(開發模式工程選項框在構建設定視窗中)。開發模式工程允許你連線分析工具,並且他們不會被壓縮,這樣產生的JavaScript程式碼會仍然包含可讀的函式名(儘管C++處理了)。當你執行到一個瀏覽器錯誤,或者當你丟擲一個異常、並且異常支援被禁用,或者在使用Debug.LogError時,這可以通過瀏覽器顯示棧追蹤來使用分析工具。不像在啟用完整異常支援(見下方)時你可以得到可控的棧追蹤,這些棧追蹤會有奇怪的名字,並且不僅包含託管程式碼,也包括了內部的Unity引擎程式碼。

異常支援Exception support

WebGL有不同級別的異常支援(檢視Building for WebGL頁面)。預設情況下,Unity WebGL會僅支援明顯丟擲的異常。你可以啟用完全異常支援,這會額外選擇在IL2CPP生成程式碼,在你的程式碼中捕獲對空引用及越界陣列元素的存取。這些額外的選項會明顯影響到執行效能,增加程式碼大小及載入時間,所以這個模式僅推薦在除錯中使用。
完整異常支援也將函式名發射來對於你的程式碼生成棧追蹤。這樣,對於未捕獲的異常及Debug.Log狀態,你會在控制檯中看到棧追蹤,並且你可以使用 System.Environment.Stacktrace 來得到棧追蹤字串。