2013年11月17日 星期日

擴充分割視窗

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

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

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

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


GameViewportClient還提供了幾個測試函式讓你可以不需要有多支搖桿才能測試分割視窗:
  • DebugCreatePlayer( ControllerId ):增加一個新的LocalPlayer,必須指定一個新的控制器ID才能正常的接收輸入訊號。
  • DebugRemovePlayer( ControllerId ):移除第一個對應到控制器ID的本地玩家。
  • SSSwapControllers():將本地玩家的控制器ID交換給下一個玩家,輪到最後一個時會換給第一個。沒有足夠的搖桿時,就可以利用這個函式一一測試各別的視埠。
  • SetSplit( SplitScreenType ):直接設定分割視窗模式,數值跟ESplitScreenType相對應。但是設定的模式必須符合目前的本地玩家數目。

GameViewportClient主要的分割視窗相關成員列出如下:
  • ActiveSplitScreenType [ESplitScreenType]:目前使用中的分割視窗模式。
  • DesiredSplitScreenType [ESplitScreenType]:想要切換的分割視窗模式。SetSplit就是設定此值。
  • SplitScreenInfo [array<SplitScreenData>]:這個陣列的索引值對應到ESplitScreenType,它儲存每種分割視窗模式的視埠排版。
  • UpdateActiveSplitscreenType():根據目前本地玩家的數量和DesiredSplitScreenType更新DesiredSplitScreenType的值。
  • LayoutPlayers():引擎會在每個畫面要繪製前呼叫這個函式來更新每個本地玩家的視埠位置。它呼叫UpdateActiveSplitscreenType更新DesiredSplitScreenType然後在SplitScreenInfo查出對應的排版資訊更新到LocalPlayer裡的相關欄位。

範例


雖說一般不會用到超過四個分割視窗,不過還是本著動口不如動手的精神來示範一下如何修改GameViewportClient支援更多視窗。

其實只要修改一下UpdateActiveSplitscreenType和SplitScreenInfo就可以了,在UDKGameViewportClient類別裡修改會比較乾淨:
class UDKGameViewportClient extends GameViewportClient
...

function UpdateActiveSplitscreenType()
{
 switch ( GamePlayers.Length )
 {
 case 5:
  ActiveSplitscreenType = 6;
  break;

 case 6:
  ActiveSplitscreenType = 7;
  break;

 default:
  super.UpdateActiveSplitscreenType();
 }
}

defaultproperties
{
 SplitscreenInfo(6)={(PlayerData=(
          (SizeX=1.0f,SizeY=0.4f,OriginX=0.0f,OriginY=0.0f),
          (SizeX=0.5f,SizeY=0.3f,OriginX=0.0f,OriginY=0.4f),
          (SizeX=0.5f,SizeY=0.3f,OriginX=0.5f,OriginY=0.4f),
          (SizeX=0.5f,SizeY=0.3f,OriginX=0.0f,OriginY=0.7f),
          (SizeX=0.5f,SizeY=0.3f,OriginX=0.5f,OriginY=0.7f))
          )}

 SplitscreenInfo(7)={(PlayerData=(
          (SizeX=0.5f,SizeY=0.4f,OriginX=0.0f,OriginY=0.0f),
          (SizeX=0.5f,SizeY=0.4f,OriginX=0.5f,OriginY=0.0f),
          (SizeX=0.5f,SizeY=0.3f,OriginX=0.0f,OriginY=0.4f),
          (SizeX=0.5f,SizeY=0.3f,OriginX=0.5f,OriginY=0.4f),
          (SizeX=0.5f,SizeY=0.3f,OriginX=0.0f,OriginY=0.7f),
          (SizeX=0.5f,SizeY=0.3f,OriginX=0.5f,OriginY=0.7f))
          )}
}
測試的結果如下:
五分割
六分割

沒有留言:

張貼留言