Blueprints In-Depth (1)

windkey
NeoBards
Published in
5 min readJul 17, 2019
“person drafting on blueprint” by Daniel McCullough on Unsplash

Unreal 官方公佈了兩個有關 Blueprints 深度介紹的影片:

Blueprints In-depth — Part 1 | Unreal Fest Europe 2019 | Unreal Engine
Blueprints In-depth — Part 2 | Unreal Fest Europe 2019 | Unreal Engine

投影片

本文章是摘錄 Part 1 的重點。

Author

作者說他自己是 Artist designer,而非程式出身,所以內容可能有一些是身為程式人員本來就會知道的事情。

Introduction

Blueprints (BP) 是 Unreal Engine 4 很重要核心的功能:

  • 學習 BP 很容易,就像畫流程圖一樣
  • BP 的 UI 介面其實跟程式的 .h 以及 .cpp 是很類似的,所以也容易理解
  • 使用 BP 很簡單,但是重點在於如何正確使用

Feature

Feature 這邊介紹了 BP 跟各種功能、資料類型、類別的關係與說明。

The Big picture

基本上與寫程式想法差不多:

  • 如何讓 BP 盡可能的簡潔?
  • 如果有人要接手我的工作,怎麼樣才好理解我寫的 BP?
  • 在做 BP 的時候有沒有一併考慮記憶體以及效能相關的問題?
  • 有沒有考慮到這個 BP 未來好不好擴張的情況?

以一個門做為範例。
首先開始的是一個很簡單的 BP,一個靠近就會開門的 BP。
之後隨著需求增加了好幾個門的 BP,每個功能都有些微的不同。
然後把有相同的部分往上抽了底層,成為 base BP class(名為 BP_EnvironmentObject)。

隨著複雜度提升,繼續往 C++ 層抽,把複雜的功能放進 C++。
但是可能玩家會去開門,所以玩家會跟門有關。開門的時候會跟動作有關,所以玩家的動畫 BP 也會跟門有關。而為了提示門可以開,所以 HUD 也來跟門參一腳了。可能有開門相關的獎盃,所以獎盃也來攪和。
槍可能可以把門打穿,所以……。

以上就是一個從一個簡單的 BP 到整個複雜專案的情況。

Run Time Performance

接下來談到執行的效能部分。

  • BP 比 C++ 慢,但有的時候效能問題的主因不一定是 BP 造成的
  • 有很多 BP 轉 C++ 目的不一定是為了改善效能
  • 不過錯誤使用 BP 有可能造成嚴重的效能問題
  • BP 比 C++ 慢 10 倍,不過實際上還是要根據不同的情況才能算數

BP 效能不好的幾個原因:

  1. 太多的節點互相連接
  2. 數學運算或是複雜的邏輯運算寫在 BP 是昂貴的
  3. 在 BP 使用迴圈是昂貴的
  4. 在 BP 巡訪大量的 actors/classes 是昂貴的
  5. 在 BP 處理 Tick 的行為是昂貴的,也是 BP 造成效能不好的主因之一

BP 的效能根據不同的執行方式,如:
編輯器執行(Play In Editor)、Development(Packaged)、Shipping(Packaged)是有很大的差異的。

Tick

造成 BP 效能問題的主因之一就是 Tick
這裡的 Tick 指的是廣泛的 Tick,例如 BP 裡面的 Tick、AnimBP 的UpdateAnimation、UMG 裡面的 binding。

大部分的情況你不需要使用 Tick,甚至於可以關掉 Tick。例如使用 Timer,或是使用事件控制,或是只在某些條件成立的時候才執行 Tick,或是距離近/玩家面向此 Actor 的時候才 Tick 等等。

有些時候也可以透過 material 來處理 BP 要做的事情。

Profiling and Debugging

BP 的除錯介面很方便,從圖中就可以知道現在正在執行那些節點,也可以透過 Filter 功能只看某一個想關注的 actor。

透過 watch 介面也可以即時的看到變數值。

Visual Logger

Visual Logger 功能也是很好的除錯對象,在 BP 內也可以使用,不管是寫一串文字,畫一個 sphere、capsule、一個區段等等。
在 Editor 可以直接叫起 Visual Logger 並且錄製除錯資訊。

Console Command

Stat game 可以快速地看到 BP 的效能資訊,dumpticks 可以把當下所有含有 tick 的 actor 資訊寫進 outputlog 內,可以仔細的觀察有多少 actor 在 tick。

Others

UE4 內建的 profiller 還是最詳細的工具,裡面可以列出哪個 Actor 的哪個函式占用多少 CPU 時間。
BP 也可以實作自動化測試,只要繼承 FunctionalTest 這個 class 並實作對應的函式,以及計算結果的正確與否。

Memory and Loading

  • BP 對記憶體與程式讀取時間的影響是很大的
  • BP 與 C++ 的讀取的行為從本質上就有很大的差別
  • BP 是被視為 content、Asset
  • C++ class 則是在程式/遊戲啟動的時候就已經載入到記憶體了,BP 則是有需要用到的時候才會觸發讀取。

BP 什麼時候會被觸發讀取可以使用 Editor 內的 Reference Viewer 來查看。
由左往右連接的意思代表讀取左邊的 Asset 也會一併讀取右邊的 Asset。
BP 內的 Cast 也會建立相依(Reference)。
Editor 內的 SizeMap 也可以看出這個 BP 的大小是因為哪些相關連的 Assets 組成的。
避免一個 BP reference 到許多其他的 BP/Asset。

有需要可以透過增加一層 C++ 的 base class 來迴避 BP 彼此 reference 的問題。BP 的 Function Libraries 使用要很小心,如果 libraries 連結到很多不同的 class,就會造成災難。使用 Soft reference 可以讓 BP 真的有需要這個 asset 的時候才作讀取。
Editor 與 packaged project 在讀取時間有很大的差別。

--

--

windkey
NeoBards

位於台灣遊戲業的程式設計師,樂於分享遊戲引擎相關的心得與開發技術。