2013年6月9日 星期日

優化Kismet節點AttachToEvent

當在Kismet中設置事件節點時,會需要設定事件的發起者。對於事先放置在場景中的Actor,可以先選取Actor再建立事件,就會自動設定好發起者。然而對於動態產生的Actor,由於無法在編輯時直接參照,就會需要使用AttachToEvent節點來動態設定發起者。

這個節點會在每次觸發時產生事件複本掛到發起者的事件列表下,因為它可以將一個事件掛上多個發起者,如果不複製事件節點,多個發起者將共用同一個事件實例導致per instance data出錯。然而如果不曉得這個特性,將可能導致不必用的複製動作。實際上任何可能對同一個Actor重覆觸發的AttachToEvent都會導致重覆複製的事件實例,它們在條件成立時也會造成多重觸發,這通常不會是想要的結果。

接下來示範一下要怎麼修改AttachToEvent來避免重覆複製。我並不想去動引擎的原始碼,所以另外自訂一個事件叫BindEvent:

2013年5月26日 星期日

原生屬性定義語法

當你需要在UnrealScript類別中定義非UnrealScript型別的欄位時,就會需要使用原生屬性語法,當然你只能在原生類別中定義原生屬性。在此所謂的原生即指C++,也就是說可以使用C++型別來定義屬性。當然因為畢竟UnrealScript還是認不得這些型別,所以不能在UnrealScript中去呼叫這些原生屬性的C++函式,通常是透過原生函式來操作。

原生屬性定義大致上是利用大括號指定C++型別:
var native pointer property_name{ pointee_type };
先來看最簡單的例子:
var native pointer          pv;
上面pv的C++型別其實就是void*。
也可以在屬性名稱右邊加個大括號指定C++型別。例如:
var native pointer          pfile{FILE};
上面pfile的C++型別就會是FILE*。
另外pointer也可和array一起使用:

2013年4月22日 星期一

自訂按鍵綁定格式

UE的按鍵綁定功能可以在ini檔中指定按鍵會觸發的命令,開發者可以在UnrealScript中撰寫exec function,再設定好按鍵綁定即可在遊戲中使用,相當方便。按鍵綁定主要分成按鈕和類比軸兩種,各自有不同的設定格式,詳情可以參考UDN。如果想要自訂新的格式,可以改寫PlayerInput的Exec。

 範例


以下程式碼示範如何自訂一個可以取得按住時間的按鍵綁定格式:

2013年3月27日 星期三

自訂八分樹

在計算機繪圖學中,八分樹是一個常用來加速查詢場景中物件的一種資料結構。UE本身就擁有數個用途不同的八分樹,除了PrimitiveComponent用的八分樹,其他大都利用TOctree類別模板來定義:
template<typename ElementType, typename OctreeSemantics>
class TOctree;
ElementType可以視為跟STL容器的value type是一樣的東西,至於OctreeSemantics則是用來設定八分樹的參數,或是提供八分樹類別操作ElementType物件的方法。其實就是所謂的traits。

OctreeSemantics需要提供的成員如下:
  • MaxElementsPerLeaf:每個葉節點的最大能容納的元素。當新增元素會超過此上限時,會分割葉節點。
  • MaxNodeDepth:最大樹深。
  • GetBoundingBox:傳回元素的邊界盒。
  • SetElementId:TOctree會給予元素一個ID。移除元素時會用到這個ID。

2013年2月28日 星期四

自訂運算子符號

先前有提過如何自訂運算子,如果想進一步自訂UnrealScript沒有支援的運算子符號時,那該怎麼做呢?雖然UnrealScript沒有提供自訂運算子符號的功能,不過其實只要稍微修改一下解析運算子符號的程式碼就可以了。例如如果想要增加一個目前UnrealScript沒有支援的運算子&=:
   
native static final operator int &= ( out int A, int B );
只要修改一下FScriptCompiler的GetToken()函式,增加辨識&=符號即可。

2013年2月25日 星期一

Unreal的通用combo box對話窗

當撰寫編輯器,需要讓使用者先選擇一個選項再進行後續步驟時,可以使用UEd提供WxDlgGenericComboEntry類別,叫出一個combo box對話窗。例如AnimSetViewer選取LOD和bone時,都是利用WxDlgGenericComboEntry來達成。

TArray<FString> Options;
// Add option strings
Options.AddItem( TEXT("Option1") );
Options.AddItem( TEXT("Option2") );
Options.AddItem( TEXT("Option3") );

WxDlgGenericComboEntry Dialog;

if( Dialog.ShowModal( TEXT("MyTitle"), TEXT("MyCaption"), Options, 0, TRUE ) == wxID_OK )
{
    ...
}