UEd裡的許多編輯器有提供常見的復原(Undo)和重做(Redo)功能,例如AnimSet Editor、Matinee、PhAT等,它們其實都是透過交易(Transaction)功能實作出來的。本篇就來介紹一下如何利用交易為自訂的編輯器寫出復原和重做功能。
首先要知道交易功能是利用UObject的序列化(Serialization)實作出來的功能,概念上就是把變更前後的物件狀態儲存起來,然後復原時恢復成變更前的狀態,重做時回到變更後的狀態。所以你想要復原的狀態必需是某個UnrealScript類別的欄位。
基本上復原和重做功能就是在變更物件時順便建立一份交易資料,然後利用它復原或重做。建立交易資料的步驟如下:
2013年12月26日 星期四
2013年11月17日 星期日
擴充分割視窗
UE3內建支援四個分割視窗,可分別對應到四個本地玩家。本篇將介紹相關的類別,以及如何擴充到更多的分割視窗。
分割視窗主要和LocalPlayer和GameViewportClient這兩個類別有關係。
LocalPlayer存放本地玩家的相關資料,包括個別玩家的視埠位置和大小。LocalPlayer物件存放在Engine的GamePlayers陣列裡,有幾個本地玩家就有幾個LocalPlayer。
GameViewportClient負責視埠的相關功能,並且繪製出每個本地玩家的視埠畫面。 它定義了一個分割視窗的列舉型別叫做ESplitScreenType對應到一到四個分割視窗的排版,例如兩個分割視窗就可分成水平和垂直分割兩種:
分割視窗主要和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中找到對應的轉換函式。
如果要自訂型別轉換,大致需要以下步驟:
本例示範如何新增一個從物件轉成名稱的型別轉換,轉換後變成該物件的名稱。首先新增CST_ObjectToName代表這個轉換:
如果要自訂型別轉換,大致需要以下步驟:
- 在列舉型別ECastToken中新增一個成員代表這個轉換指令。
- GConversions的第一個索引是目標型別,第二個索引是來源型別。我們需要修改對應的GConversions元素成自訂的轉換指令。
- 撰寫對應的轉換函式並且註冊到GCasts。
範例
本例示範如何新增一個從物件轉成名稱的型別轉換,轉換後變成該物件的名稱。首先新增CST_ObjectToName代表這個轉換:
2013年9月19日 星期四
自訂UnrealScript常數
UnrealScript跟其他程式語言一樣,有提供常數這個語言構件,本篇來介紹一下要怎麼擴充自訂的常數型別。
在UnrealScript中,常數實際上是用一個編成位元組碼(byte code)的指令代表。要自訂新的常數,大致上需要以下的步驟:
在UnrealScript中,常數實際上是用一個編成位元組碼(byte code)的指令代表。要自訂新的常數,大致上需要以下的步驟:
- 找一個還未使用的位元組碼當作自訂的常數指令碼
- 如果這個常數需要使用新的名稱,可以在UnNames.h註冊新的名字
- 修改UByteCodeSerializer使得新增的指令可以正確地序列化
- 撰寫對應的函式並且註冊到GNatives
- 修改FTokenBase使解析器可以記錄新的常數型別
- 修改FScriptCompiler讓編譯器認得新的指令
2013年8月31日 星期六
修正UnrealScript不能使用out bool array的問題
在UnrealScript中不允許使用宣告使用out bool參數的函式,例如:
這是因為布林變數實作上其實只是個bitfield,在編譯時同一個類別的布林屬性會湊在一起,儘量減少總共需要的大小。然而如果把上述宣告為原生函式,要產生C++標頭檔時,會遇到無法在C++中表示reference to bitfield的問題。雖然可以為這種情況作特殊處理,不過其實只要改為宣告為out byte就可以解決了。
然而宣告使用out array<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);
2013年7月29日 星期一
自訂UnrealScript指令
UDN花了許多篇幅解釋UnrealScript底層的運作,不過卻沒提如何自訂新的指令。本篇將透過一個簡單的範例說明如何擴充UnrealScript的指令。
UnrealScript並未提供擴充機制,讓開發者可以在自己的專案裡撰寫程式碼自訂新的指令。雖然增加擴充機制不會太難,主要是讓FScriptCompiler和UByteCodeSerializer可以subclassing,不過由於不是這次的主題,所以本例中就直接修改底層的程式碼。
要自訂新的指令,大致上需要以下的步驟:
UnrealScript並未提供擴充機制,讓開發者可以在自己的專案裡撰寫程式碼自訂新的指令。雖然增加擴充機制不會太難,主要是讓FScriptCompiler和UByteCodeSerializer可以subclassing,不過由於不是這次的主題,所以本例中就直接修改底層的程式碼。
要自訂新的指令,大致上需要以下的步驟:
- 找一個還未使用的位元碼(byte code)當作自訂指令碼
- 如果這個指令需要使用一個新的名稱,可以在UnNames.h註冊一個新的名字
- 修改UByteCodeSerializer使得新增的指令可以正確地序列化。
- 撰寫對應的函式並且註冊到GNatives
- 修改FScriptCompiler讓編譯器認得新的指令
訂閱:
文章 (Atom)

