UDN
Search public documentation:

CLIKChatBoxJP
English Translation
中国翻译
한국어

Interested in the Unreal Engine?
Visit the Unreal Technology site.

Looking for jobs and company info?
Check out the Epic games site.

Questions about support via UDN?
Contact the UDN Staff

UE3 ホーム > ユーザーインターフェイスと HUD > Scaleform GFx > 簡単なチャットボックスの作り方

簡単なチャットボックスの作り方


_UDK での前回テスト 2011年9月_

概要


このチュートリアルは、中級から上級レベルに位置しており、ゲームプレイ中に機能する基本的なマルチプレイヤー用複数行チャットウィンドウを作成するために必要となる手順について解説しています。このチャットウィンドウは、あらゆるキーボード入力をキャプチャするとともに、フォーカスされている間はゲームがキーボード入力をキャプチャするのを防ぎます。チャット入力にアクセスする方法は 2 つ提供されます。1 つは、マウスクリックであり、もう 1 つはキーボードコマンドです。

このチュートリアルでは、「Scaleform」および CLIK ウィジェットに関して既にかなり詳しい知識をもっていること、また「Scaleform」ベースの HUD においてマウスカーソルが機能していることが想定されています。さらに、 レプリケーション に関する詳しい知識も必要となります。

ALERT! 重要 : 切り替え可能なマウスのチュートリアル も必要となります。

「Flash」のセットアップ


テキスト入力ボックス

  • CLIK TextInput ウィジェットを HUD にドロップします。 (C:\UDK\UDK-2011-09\Development\Flash\CLIK\components\TextInput.FLA )
  • chatInput というインスタンス名を付けます。
  • Component Inspector (コンポーネン トインスペクター) (CS4) または Component Parameters (コンポーネント パラメータ) のロールアウト (CS5) を開き、actAsButton (ボタンとして動作) を有効にします。

Send ボタン

  • 次に、TextInput ウィジェットのとなりに CLIK Button ウィジェットをドロップします。(C:\UDK\UDK-2011-09\Development\Flash\CLIK\components\Button.FLA)
  • chatSendBtn というインスタンス名を付けます。
  • Component Inspector (CS4) または Component Parameters のロールアウト (CS5) を開き、ボタンのラベルフィールドに Send を入力します。

複数行に渡るスクロール可能なチャットログ

  • CLIK Text Area ウィジェットを TextInput ウィジェットの上方にドロップします。(C:\UDK\UDK-2011-09\Development\Flash\CLIK\components\TextArea.FLA)
  • chatLog というインスタンス名を付けます。
  • Component Inspector (CS4) または Component Parameters のロールアウト (CS5) を開き、editable (編集可能) を無効にします。
  • CLIK Scroll Bar ウィジェットを TextInput ウィジェットの右側にドロップします。 (C:\UDK\UDK-2011-09\Development\Flash\CLIK\components\Scrollbar.FLA )
  • chatScrollBar というインスタンス名を付けます。
  • Component Inspector (CS4) または Component Parameters のロールアウト (CS5) を開き、Text Area の scrollBar フィールドを chatScrollBar にセットします。

チャットフォーム

  • 4 つのウィジェットをステージ上に並べて、互いを接近させ、ボックスを形成するようにします。必要に応じて、ウィジェットを拡張する (非均等スケール) ことができます。
  • ステージ上にある 4 つのウィジェットをすべて選び、右クリックし、Convert to Symbol (シンボルに変換) を選択します。
  • Name を chatForm にセットします。
  • Type を Movie Clip にセットします。
  • Export for ActionScript および Export in frame 1 を有効にします。
  • Identifier を chatForm にセットします。
  • Class を gfx.core.UIComponent にセットします。
  • [OK] をクリックします。
  • ステージから chatForm ムービークリップを削除します。その際、ライブラリには残したままにします。

チャットウィンドウ

  • \Development\Flash\CLIK\demos\com\Scaleform\Window .as ファイルを、\Development\Flash\CLIK\gfx\controls\Window.as にコピーします。
  • このクラスファイルを開き、7 行目 (クラス宣言の行) を次のように変更します。

ActionScript
class gfx.controls.Window extends UIComponent {

  • \Development\Flash\CLIK\demos\WindowDemo.FLA ファイルを開きます。
  • このファイルの Library パネルに進みます。
  • WindowSkinned シンボルを選択します。
  • WindowSkinned シンボルを右クリックして、Copy を選択します。
  • HUD FLA ファイルに戻ります。
  • ステージ上で右クリックして、Paste (ペースト) を選択し、Window シンボルを適所にペーストします。
  • ステージの最下部の左付近にウィンドウを並べます。
  • chatWindow というインスタンス名を付けます。
  • chatWindow がステージで選択された状態で、Component Inspector (CS4) または Component Parameters のロールアウト (CS5) を開きます。
  • formSource を chatForm にセットします。
  • 必ず、formType が symbol にセットされるようにします。
  • maxHeight および maxWidget を 400 にセットします。
  • minHeight と minWidget を 200 にセットします。
  • offsetBottom を 24 に、offsetLeft を 20 に、offsetRight を 20 に、offsetTop を 46 にセットします。あるいは、テストした後でうまく機能する値にセットします。
  • title (タイトル) を Chat にセットします。
  • Library Panel で WindowSkinned シンボルを右クリックし、Properties (プロパティ) を選択します。
  • Class フィールドを gfx.controls.Window に変更し、[OK] をクリックします。
  • シンボルを再度右クリックし、Component Definition (コンポーネントの定義) を選択します。
  • Class フィールドを gfx.controls.Window に変更し、[OK] をクリックします。
  • 通常どおりに SWF ファイルを保存およびパブリッシュし、UDK にインポートします。これで、ドラッグ可能なチャットウィンドウがステージ上にできます。これには、チャット入力、チャットエリア、send ボタン、スクロールバーが含まれています。

HUD クラス UnrealScript


HUD クラスは、GFxMoviePlayer を拡張しなければなりません。以下の新たな変数を、UnrealScript HUD クラスファイルに追加します。

YourHUD.uc
var WorldInfo ThisWorld;
var SFPlayerController PC;

var array<string> chatMessages; // this will hold all the chat messages
var bool bChatting;

// These are our CLIK widgets for the chat system
var GFxClikWidget MyChatInput, MyChatSendButton, MyChatLog;

Start()/Init() 関数を次のように変更します。(赤線を追加)。

YourHUD.uc
function Init(optional LocalPlayer player)
{
  super.Init(player);
  ThisWorld = GetPC().WorldInfo;

  Start();
  Advance(0);

  // ... other initialization code here ...

  // Register the HUD with the PlayerController
  PC = SFPlayerController(GetPC());
  PC.registerHUD(self);
}

(以前の Mouse チュートリアルから) ToggleCursor() 関数を変更します。

YourHUD.uc
/** Toggles mouse cursor on/off */
function ToggleCursor(bool showCursor, float mx, float my)
{
  if (showCursor)
  {
    MouseContainer = CreateMouseCursor();
    MouseCursor = MouseContainer.GetObject("my_cursor");
    MouseCursor.SetPosition(mx,my);
    MouseContainer.SetBool("topmostLevel", true);
  }
  else
  {
    MouseContainer.Invoke("removeMovieClip", args);
    MouseContainer = none;
  }

  if (!bChatting)
  {
    bCaptureInput = showCursor;
    bIgnoreMouseInput = !showCursor;
  }
  else
  {
    bCaptureInput = true;
    bIgnoreMouseInput = false;
  }
}

次に、HUD の WidgetInitialized() 関数を変更し、チャットテキスト入力フィールドおよびチャット送信 (send) ボタン上のマウスクリックイベントのためのイベントリスナーをセットアップします。

YourHUD.uc
event bool WidgetInitialized(name WidgetName, name WidgetPath, GFxObject Widget)
{
  switch(WidgetName)
  {
  case ('chatInput'):
    MyChatInput = GFxClikWidget(Widget);
    MyChatInput.AddEventListener('CLIK_press', OnChat);
    break;

  case ('chatSendBtn'):
    MyChatSendButton = GFxClikWidget(Widget);
    MyChatSendButton.AddEventListener('CLIK_press', OnChatSend);
    break;

  case ('chatLog'):
    MyChatLog = GFxClikWidget(Widget);
    break;

  default:
    break;
  }

  return true;
}

OnChat() イベント ハンドラを追加します。

YourHUD.uc
// Event Handler - handles when the player clicks on the chat box text input field.
function OnChat(GFxClikWidget.EventData ev)
{
  bChatting = true;
}

OnChatSend() 関数を追加します。この関数は、Send ボタンがクリックされるとメッセージを伝達するとともに、制御をゲームに返します。

YourHUD.uc
function OnChatSend(GFxClikWidget.EventData ev)
{
  local string Msg;

  Msg = MyChatInput.GetString("text");

  if (Msg != "")
  {
    PC.SendTextToServer(PC, Msg);
  }

  MyChatInput.SetString("text", "");
  self.bCaptureInput = false;
  bChatting = false;
}

次の関数は、チャットエリアを更新し、Broadcast() 関数から受け取った各メッセージを表示するものです。

YourHUD.uc
function UpdateChatLog(string message)
{
  local string displayMsg;
  local int i;

  chatMessages.AddItem(message);

  displayMsg = "";

  for (i = 0; i < chatMessages.length; i++)
  {
    displayMsg @= chatMessages[i];
    displayMsg @= "\n";
  }

  MyChatLog.SetString("text", displayMsg);
  MyChatLog.SetFloat("position", MyChatLog.GetFloat("maxscroll"));
}

ウィジェットのバインディングおよびその他重要な変数を defaultproperties (デフォルトプロパティ) で追加します。

YourHUD.uc
defaultproperties
{
    WidgetBindings.Add((WidgetName="chatInput",WidgetClass=class'GFxClikWidget'))
    WidgetBindings.Add((WidgetName="chatSendBtn",WidgetClass=class'GFxClikWidget'))
    WidgetBindings.Add((WidgetName="chatLog",WidgetClass=class'GFxClikWidget'))

    bIgnoreMouseInput = true;
    bCaptureInput = false;
}

GameInfo クラスのセットアップ


GameInfo クラスを開きます。

GameInfo クラス が UTGame を拡張したものではないか、UTGame の小クラスではない場合は (例 : UTDeathmatch)、以下の変数のみをGameInfo クラスに追加します。これらの変数がすでに宣言されている場合は、コンパイル時に警告が出されます。その場合は、GameInfo クラスから変数を削除してください。

YourGameInfo.uc
var class<BroadcastHandler> BroadcastHandlerClass;
var BroadcastHandler BroadcastHandler;   // handles message (text and localized) broadcasts

次に GameInfo クラスの InitGame() 関数に、次の行を追加します。

YourGameInfo.uc
event InitGame( string Options, out string ErrorMessage )
{
    Super.InitGame(Options, ErrorMessage);
    BroadcastHandler = spawn(BroadcastHandlerClass);
}

GameInfo クラス内部で、\Development\Src\Engine\Classes\GameInfo.uc の Broadcast イベントクラスをオーバーライドします。

YourGameInfo.uc
event Broadcast(Actor Sender, coerce string Msg, optional name Type)
{
  local SFPlayerController PC;
  local PlayerReplicationInfo PRI;

  // This code gets the PlayerReplicationInfo of the sender. We'll use it to get the sender's name with PRI.PlayerName
  if (Pawn(Sender) != None)
  {
    PRI = Pawn(Sender).PlayerReplicationInfo;
  }
  else if (Controller(Sender) != None)
  {
    PRI = Controller(Sender).PlayerReplicationInfo;
  }

  // This line executes a "Say"
  BroadcastHandler.Broadcast(Sender, Msg, Type);

  // This is where we broadcast the received message to all players (PlayerControllers)
  if (WorldInfo != None)
  {
    ForEach WorldInfo.AllControllers(class'SFPlayerController',PC)
    {
      `Log(Self$":: Sending "$PC$" a broadcast message from "$PRI.PlayerName$" which is '"$Msg$"'.");
      PC.ReceiveBroadcast(PRI.PlayerName, Msg);
    }
  }
}

最後に、次の各行を GameInfo クラスの defaultproperties に追加します。ご自分のクラス名を使用して変更する必要があります。

YourGameInfo.uc
defaultproperties
{
  PlayerControllerClass=class'SFPlayerController'
  BroadcastHandlerClass=class'Engine.BroadcastHandler'
  HUDType=class'SFTutorial.SFHudWrapper'
  bUseClassicHUD=true
}

PlayerController クラスのセットアップ


PlayerController クラスを作成して開きます。(この例では、SFPlayerController)。

SFPlayerController.uc
class SFPlayerController extends UTPlayerController;

まず、PlayerController 内部で HUD を登録する関数を作成することによって、PlayerController から HUD 内の関数を簡単に呼び出せるようにします。

SFPlayerController.uc
var SFHud MySFHud;

function registerHUD(SFHud hud)
{
  MySFHud = hud;
}

次の関数は、メッセージをサーバーに送信するために使用されます。

SFPlayerController.uc
exec function SendTextToServer(SFPlayerController PC, String TextToSend)
{
  `Log(Self$":: Client wants to send '"$TextToSend$"' to the server.");
  ServerReceiveText(PC, TextToSend);
}

次の関数は、サーバーのメッセージを受信し、さらにそれを伝達するために使用されます。

SFPlayerController.uc
reliable server function ServerReceiveText(SFPlayerController PC, String ReceivedText)
{
  WorldInfo.Game.Broadcast(PC, ReceivedText, 'Say');
}

最後に、サーバーからの伝達をリッスンして、それをチャットウィンドウに送るためのクライアント関数を作成する必要があります。

SFPlayerController.uc
reliable client function ReceiveBroadcast(String PlayerName, String ReceivedText)
{
    `Log(Self$":: The Server sent me '"$ReceivedText$"' from "$PlayerName$".");
    MySFHud.UpdateChatLog(PlayerName @ ": " @ ReceivedText);
}

キーボードコマンドを使ってチャットを有効化する (Enter キーを押す)

このステップのためには、Enter キーを使用して、チャットを開始するとともにチャットのメッセージを送信 (完了) することにします。ただし、どのようなキーを使用しても構いません。

キーバインディングを追加する

DefaultInput.ini を開き、次の行を追加します。

.Bindings=(Name="Enter",Command="ChatHandler")

ALERT! 注意: キーが押された時にチャットが有効になるためには、次の行をコメントアウトするか削除する必要があります。

.Bindings=(Name="Enter",Command="GBA_Use")

HUDWrapper クラスのセットアップ

HUDWrapper を開きます。このクラスは、HUD をインスタンス化します。キーが押された時に実行される関数を追加します。

YourHUDWrapper.uc
exec function ChatHandler()
{
  HudMovie.ToggleChat(); // Replace HudMovie with the reference name of your HUD movie.
}

HUD クラスのセットアップ

HUD クラスを開きます。

まず、選択したキーが、決して HUD ムービーによって入力としてキャプチャされることがないようにします。そのためには、focus ignore key (フォーカス時に無視されるキー) リストにこのキーを追加します。次の行を Start()/Init() 関数に追加します。

AddFocusIgnoreKey('Enter');

次に、キーボードコマンドによってチャットを有効化する関数を追加します。この関数は、HUDWrapper によって呼び出されます。

function ToggleChat()
{
  if (!bChatting)
  {
    bCaptureInput = true;
    OnChat();
  }
  else
  {
    bCaptureInput = false;
    OnChatSend();
  }
}

次に、OnChat() および OnChatSend() 関数のパラメータを変更して、optional となるようにします。

function OnChat(optional GFxClikWidget.EventData ev)
function OnChatSend(optional GFxClikWidget.EventData ev)

ここで、次のコードを追加して OnChat() 関数を変更します。

MyChatInput.SetBool("focused", true);

最後に、次のコードを用いて OnChatSend() 関数を変更します。

MyChatLog.SetBool("focused", true);

スクリプトを再コンパイルして、HUD をテストします。

ダウンロード


  • UDK_September2011_ScaleformSandboxFiles.zip を ここ からダウンロードすることができます。