2014年1月31日 星期五

自訂效能記錄

在UE的命令列中輸入stat xxx可以觀看對應系統的所花費的時間,優化時可以方便初步縮小範圍,找出可能的瓶頸。這個指令其實UE也有提供擴充的功能,本篇就來看一下如何自訂效能記錄。

自訂效能記錄需要用到以下三個巨集:

  • DECLARE_STATS_GROUP(group_name, group_id):宣告效能記錄群組,當使用stat指令時需要輸入的參數即為此群組名稱。開發者使用的群組ID要大於等於STATGROUP_LicenseeFirstStatGroup所對應的數值。
  • DECLARE_CYCLE_STAT(stat_name, stat_id, group_id):宣告隸屬某個群組中的單筆效能記錄。開發者使用的記錄ID要大於等於STAT_LicenseeFirstStat所對應的數值。
  • SCOPE_CYCLE_COUNTER(stat_id):定義一個效能記錄器。把它放在想要測量的函式內即可。它會記錄一個畫面中被呼叫的次數和執行所花的時間。

範例


以下程式碼示範如何自訂效能記錄:

2013年12月26日 星期四

編輯器的復原和重做功能

UEd裡的許多編輯器有提供常見的復原(Undo)和重做(Redo)功能,例如AnimSet Editor、Matinee、PhAT等,它們其實都是透過交易(Transaction)功能實作出來的。本篇就來介紹一下如何利用交易為自訂的編輯器寫出復原和重做功能。

首先要知道交易功能是利用UObject的序列化(Serialization)實作出來的功能,概念上就是把變更前後的物件狀態儲存起來,然後復原時恢復成變更前的狀態,重做時回到變更後的狀態。所以你想要復原的狀態必需是某個UnrealScript類別的欄位。

基本上復原和重做功能就是在變更物件時順便建立一份交易資料,然後利用它復原或重做。建立交易資料的步驟如下:

2013年11月17日 星期日

擴充分割視窗

UE3內建支援四個分割視窗,可分別對應到四個本地玩家。本篇將介紹相關的類別,以及如何擴充到更多的分割視窗。

分割視窗主要和LocalPlayer和GameViewportClient這兩個類別有關係。

LocalPlayer存放本地玩家的相關資料,包括個別玩家的視埠位置和大小。LocalPlayer物件存放在Engine的GamePlayers陣列裡,有幾個本地玩家就有幾個LocalPlayer。
  • Origin [ Vector2d ]:本地玩家視埠在畫面中的位置,以左上角為準。值域正規化在[0,1]之間。
  • Size [ Vector2d ]:本地玩家視埠在畫面中的長寬。值域正規化在[0,1]之間。
  • ControllerId [ int ] :指定這個本地玩家使用哪個遊戲控制器。

GameViewportClient負責視埠的相關功能,並且繪製出每個本地玩家的視埠畫面。 它定義了一個分割視窗的列舉型別叫做ESplitScreenType對應到一到四個分割視窗的排版,例如兩個分割視窗就可分成水平和垂直分割兩種:
水平分割
垂直分割

2013年10月17日 星期四

自訂UnrealScript型別轉換

UnrealScript跟其他程式語言一樣,有型別轉換的功能。每個型別轉換對應到一個轉換指令,可在一個二維全域陣列GConversions中查表找出對應的指令代碼,再到全域函式指標陣列GCasts中找到對應的轉換函式。

如果要自訂型別轉換,大致需要以下步驟:
  • 在列舉型別ECastToken中新增一個成員代表這個轉換指令。
  • GConversions的第一個索引是目標型別,第二個索引是來源型別。我們需要修改對應的GConversions元素成自訂的轉換指令。
  • 撰寫對應的轉換函式並且註冊到GCasts。
 

範例


本例示範如何新增一個從物件轉成名稱的型別轉換,轉換後變成該物件的名稱。首先新增CST_ObjectToName代表這個轉換:

2013年9月19日 星期四

自訂UnrealScript常數

UnrealScript跟其他程式語言一樣,有提供常數這個語言構件,本篇來介紹一下要怎麼擴充自訂的常數型別。

在UnrealScript中,常數實際上是用一個編成位元組碼(byte code)的指令代表。要自訂新的常數,大致上需要以下的步驟:
  • 找一個還未使用的位元組碼當作自訂的常數指令碼
  • 如果這個常數需要使用新的名稱,可以在UnNames.h註冊新的名字
  • 修改UByteCodeSerializer使得新增的指令可以正確地序列化
  • 撰寫對應的函式並且註冊到GNatives
  • 修改FTokenBase使解析器可以記錄新的常數型別
  • 修改FScriptCompiler讓編譯器認得新的指令

2013年8月31日 星期六

修正UnrealScript不能使用out bool array的問題

在UnrealScript中不允許使用宣告使用out bool參數的函式,例如:
function TestOutBool(out bool Bool);
編譯器會回報"Booleans may not be out parameters"。

這是因為布林變數實作上其實只是個bitfield,在編譯時同一個類別的布林屬性會湊在一起,儘量減少總共需要的大小。然而如果把上述宣告為原生函式,要產生C++標頭檔時,會遇到無法在C++中表示reference to bitfield的問題。雖然可以為這種情況作特殊處理,不過其實只要改為宣告為out byte就可以解決了。

然而宣告使用out array<bool>參數的函式會遇到編譯器回報同樣的錯誤:
function TestOutBoolArray(out array<bool> Array);