UDN
Search public documentation:

DevelopmentKitFirstScriptProjectJP
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

初めて UnrealScript プロジェクトを作成する前に

ドキュメントの概要: Unreal Development Kit で初めて UnrealScript プロジェクトを作成するユーザー向けのガイド。

ドキュメントの変更ログ: サンプルゲームの冒頭部分。

概要

このチュートリアルでは、UDK を使って UnrealScript (Unreal スクリプト) プロジェクトを初めて設定する手順を段階的に示しています。UDK を使った完全なゲームの作成は扱われておらず、ゲームフレームワークの詳細な説明も、既に UDK にあるのでここには含まれていません。

環境設定

プログラミングを開始する前に、開発環境を設定する必要があります。

UDK の設定

まず 最新バージョンの UDK を入手します。インストーラーを実行し、画面の手順に従います。UDK はシステム内で簡単に見つけられる場所にインストールして、Program Files ディレクトリ内で埋もれてしまわないようにするのが良いでしょう。というのは、この UDK ディレクトリを開発作業中に何度も参照するためです。

新しいバージョンの UDK が定期的に発表されますが、先走って最新バージョンが出ると同時に飛びついて更新するのは賢明ではありません。何かが変更されたために、現在のプロジェクトが動かなくなる可能性もあります。新しい UDK バージョンがリリースされたときには、まず作業中のプロジェクトが安定した状態にあることを確認してから、新しいバージョンに移行し、すべてが今までとおり機能することを確認します。

UDK ディレクトリのレイアウト

UDK のインストール ディレクトリのレイアウトは以下のとおりです (ディレクトリの一部には、UDK の初回起動時まで存在しないものもあります)。

  • Binaries ; 各種ユーティリティを格納します。
    • ActorX ; 各種の 3D モデリングプログラム用の ActorX プラグイン。
    • FaceFXPlugins ; 各種の 3D モデリングプログラム用の FaceFX プラグイン。
    • InstallData ; UDK のインストール時に使われるファイル。
    • SpeedTreeModeler ; SpeedTree のツール。
    • Win32 ; UDK 実行ファイルと各種の必須ライブラリを格納します。
    • Win64 ; 64 ビットバージョンの UnrealLightmass? を格納します。
    • Windows ; UDK が必要とする各種のラインタイムライブラリをインストールするための、インストールファイルを格納します。これらのライブラリは、セットアップ中にシステムにインストールされます。
  • Development ; 開発関連のディレクトリ。
    • Src ; UnrealScript のソースファイルを含むすべてのソースファイルを格納するのに使います。UDK に同梱されている UnrealScript (Unreal スクリプト) のコードのソースファイルが既に格納されており、ユーザーが作成したソースファイルもこのディレクトリに追加します。
  • Engine ; このディレクトリは、UnrealEngine のベースファイルを格納します。このディレクトリの内容を変更しないでください。変更する場合は=UTGame= ディレクトリを使用します。このディレクトリ内のすべてのファイルは、商用の UDK アプリケーションを含めて、任意のアプリケーションを作成する場合に使用できます。
    • Config ; ベース構成ファイルを格納します。通常これらのファイルは、=UTGame= ディレクトリ内の構成ファイルが継承します。
    • Content ; コンテンツ パッケージ。
    • EditorResources ; エディタで使用されるリソースファイル。
    • Localization ; ローカライズファイル。各言語ごとにローカライズ ファイルを格納するサブディレクトリがあります。
    • Shaders ; シェーダーソースファイル。
    • Stats ; さまざまな開発統計のレポート生成に使用するテンプレートファイル。
  • UTGame ; 新しいコンテンツを追加するディレクトリです。
    • Build
    • Config ; このディレクトリには、デフォルトの構成ファイルと、経時的に更新される、実行された構成ファイルの 2 つのタイプの構成ファイルがあります。デフォルトの構成ファイルはシステムのデフォルト構成を提供し、エンジンによって更新されることはありません。
    • Content ; アプリケーションのすべてのコンテンツパッケージ (レベルを含む) を格納します。商用アプリケーションの作成時には、このディレクトリのコンテンツを使用してはいけません。サブディレクトリには決まった設定はなく、すべて構成によって決まります。
    • Localization ; ローカライズファイル。
    • Logs ; ログファイルとクラッシュレポートの格納に使用します。
    • Movies ; ゲーム中に再生可能な Bink ムービー専用のディレクトリです。注意: 作成するアプリケーション内に UE3_logo.bik ムービーを含めて、これを再生することが義務付けられています。
    • Script ; コンパイルしたスクリプトパッケージを格納します。
    • Splash ; エディタおよびゲーム起動時のスプラッシュスクリーンを格納します。

IDE/エディタ

UDK には、UnrealScript 作成エディタは含まれていません。UnrealScript は Java に非常に似たところがあり、ソースコードは標準テキストファイルに保存されるので、コードの記述にはお気に入りのテキストエディタを使うことができます。

しかし、多彩な機能を提供する優れたエディタがいくつかあります。

nFringe

現在最も注目すべきエディタは、Pixel Mine Games 社の nFringe です。これは UE3 の完全総合開発環境を提供し、したがって UDK との統合も可能です。nFringe はMicrosoft の Visual Studio IDE に基づいて構築され、Visual Studio の Professional バージョンはもちろんフリーの Visual Studio Express とも連動します。

nFringe は非商用プロジェクトには無料で使用できます。nFringe に関するその他の情報は こちら に掲載されています。

nFridge をインストールするには、このリンク先に掲載されている手順 に従います。

"General/Mod Project" モードではなく、Licensee Project モードで nFringe を使用することをお勧めします。その理由は、nFridge からのアクセスは UnrealScript だけに制限されていても、このモードならば UDK の機能は正式に使用許諾された UE3 とほぼ同じだからです。

プロジェクト設定では 1 つのパッケージを特定の対象とするのではなく、UDK 全体をひとつのプロジェクトの対象とします。そのため、前述の説明に従いプロジェクトとソリューションファイルは UDK\Development\src に保存することをお勧めします。

nFringe は UnrealScript パッケージを自動管理しません。パッケージごとの適切なディレクトリ構造の作成と、コンパイルプロセスに適切なパッケージが含まれるように構成を更新する作業は、手動で行う必要があります。詳細は プロジェクトの設定 を参照してください。

WOTgreal

UnrealEngine 用に特に構築されたもう 1 つの IDE は WOTgreal です。WOTgreal は UnrealEngine3 を一部しかサポートせず、WOTgreal の各種機能は UE3 設定とはうまく連動しませんが、それでも UnrealScript を作成したり、code insight および code completion などの機能をそのまま利用できます。

WOTgreal を使用するには、まず最新の安定版リリースを ダウンロード します。その次に最新の開発リリースをダウンロードし、それをインストール ディレクトリに解凍して以前のファイルを上書きします。Windows Vista で WOTgreal を使用するには、管理者特権ユーザーとして実行します。

WOTGrealConfig1.png
WOTgreal を UDK 用に設定するにはいくつかのステップがあります。起動したら、まず [game type] (ゲームタイプ) を設定する必要があります。[Tools] (ツール) メニューで [Game Types Configurations] (ゲームタイプの設定) を選択します。[Configure Game Types] ダイアログで新しいゲームタイプを追加し、以下の情報を指定します。

WOTGrealConfig2.png
Display name
UDK (または任意の名前)
Game EXE name
udk
Menu name
UDK
Use "extends" instead of "expands"
Game Architecture
"UE3"

その他の設定は、現在のところは特に役に立ちません。[OK] ボタンを押して設定を保存し、メインの WOTgreal 画面に戻ります。

[Options] (オプション) メニューから [Preferences] (環境設定) を開きます。[Preferences] ウィンドウで [Game Information] (ゲーム情報) を選択します。リストからゲームタイプ [UDK] を選択 します。

WOTGrealConfig3.png
次に以下の設定を更新します。ここで、{UDK directory} とは UDK のインストール ディレクトリです。

UCC.exe File
{UDK directory}\binaries\win32\udk.com
Game Root Dir
{UDK directory}
Source Root Dir
{UDK directory}\Development\Src

注意: udk.exe ではなく、=udk.com= である点に注意してください。

WOTGrealConfig4.png
WOTGrealConfig5.png
次に [Compiling & Debugging] (コンパイル & デバッグ) セクションに移動します。 [Pre-Compile] タブで、[Do nothing for pre-compilation] (プリコンパイルでは何も実行しない) オプションを選択します。 [compile] タブで、[Run this program/... to compile] (このプログラムを実行.. コンパイル) オプションを選択し、次の値を入力します。 c:\windows\system32\cmd.exe /C {UDK directory}\binaries\win32\udk.com make

[Post-Compile] タブで、ログ名として次の場所を指定します。 {UDK directory}\UTGame\Logs\Launch.log

これらのステップを終了すると、WOTgreal を使用できるようになります。F5 を押してパッケージとクラスツリーを読み込みます。これには多少時間がかかります。

WOTgreal は UnrealScript インターフェースを表示しませんが、エディタを使ってそれらを書くことはできます。Pre-processor ディレクティブも認識しませんが、それらを宣言で使わない限り問題に遭遇することはありません。

nFringe とは異なり、WOTgreal では UnrealScript パッケージに対応するディレクトリ構造を適切に作成しますが、構成を自動更新してコンパイル中にパッケージを含める作業は行いません。その他の情報は プロジェクトの設定 を参照してください。

その他のエディタ

もちろん、お気に入りのテキストエディタを選択して使用してもかまいません。UnrealScript の構文ハイライト機能や他の高度な機能を備えたエディタが多数存在します。その他のエディタの詳細は、コミュニティ主導型の UnrealWiki ページを参照してください。

標準テキスト エディタを使用する場合は、UnCodeX というツールの使用もお勧めします。このツールは nFringe や WOTgreal にあるようなクラスおよびパッケージツリーを提供するほかに、標準テキストエディタの強力な味方となるその他の諸機能を備えています。最新の安定版リリースをダウンロードしてインストールしてから、UE3 のサポートを提供する最新の開発リリースをダウンロードしてください。

その他の重要事項

アプリケーション開発に着手する段階に到達したら、次に バージョン管理システム の使用について検討されることをお勧めします。バージョン管理システムには 2 つの重要な役割があります。最も大切な役割は開発作業のバックアップおよび追跡記録を提供することで、作業中に間違えても、その前のバージョンを簡単に復元できます。2 番目の役割は、同じプロジェクトで複数のメンバーと作業できることです。

サンプル アプリケーション

このセクションでは、小さな UDK アプリケーションの開発を紹介します。このアプリケーションを CluOne と呼ぶことにします。

この小さなアプリケーションはほとんど何も行わず、現在注目しているゲーム要素に関する情報を要求するという、簡単なシステムを提供します。

プロジェクトの設定

SrcDir.png

前述のとおり、=UDK\Development\src= ディレクトリはソースコードを格納する場所で、このディレクトリには既に UDK 内のすべての UnrealScript クラスのソースコードが含まれています。個々のサブディレクトリはそれぞれ 1 つのパッケージに対応します。

CluOne のソースコードもこのディレクトリに追加してください。サンプル アプリケーションは小さなアプリケーションなので、パッケージも 1 つで十分です。=UDK\Development\src= ディレクトリに CluOne という名前のディレクトリを作成し、その CluOne ディレクトリ内に Classes という名前の別のディレクトリを作成します。UnrealScript コンパイラは、=UDK\Development\src\*\Classes= ディレクトリ内を探して UnrealScript コードを見つけます。パッケージディレクトリ内の他のコンテンツはすべて無視されます。

CluOne ディレクトリは src ディレクトリにありますが、コンパイラはこれに気が付きません。そのため、構成ファイルを更新しして、=CluOne= パッケージを有効な UnrealScript パッケージとして登録する必要があります。ファイル UDK\UTGame\Config\UTEngine.ini を開き、 [UnrealEd.EditorEngine] セクションを探します。このセクションには、=EditPackages= という名前の項目がいくつかあり、これらはコンパイラがコンパイルに含めるデフォルトパッケージです。=EditPackages= は UDK の基本パッケージ用で、カスタムパッケージは ModEditPackages として追加します。そこで、=CluOne= パッケージは「ModEditPackages=CluOne」のように追加します。=EditPackages= と ModEditPackages にパッケージを追加する順序が大切で、これはパッケージがコンパイルされる順番を定義し、クラス階層に影響します。親クラスがコンパイルされていないクラスはコンパイルできません。UnrealScript コンパイラは Java コンパイラほど洗練されたものではなく、コンパイル順序を自力で見つけることはできません。

UnrealScript クラスの階層

UDK には多数の UnrealScript クラス (2000 以上) が用意されています。これらのクラスの機能をすべて理解する必要はありません。nFringe、WOTgreal または UnCodeX を使い、クラス全体の階層を調べるのが一番よい方法です。

この中には、2 つの非常に重要かつ異なるクラスがあります。1 つ目のクラスは基本クラス Object で、さまざまな演算子を含む多くのコア関数が定義されています。2 つ目の大切なクラスは Actor で、これはゲーム内で "動く" または "生きる" すべての要素に関する基本クラスです。 レベル内で可視可能なすべての要素は Actors ですが、=Actors= がすべて可視可能というわけではありません。例えば Info のサブクラスは、デフォルトではすべて非表示です。=Object= クラスは、ユーティリティまたは影響の少ない機能に使われますが、ユーザーインターフェースにも使われます。ネットワーク機能 (クライアントとサーバー間の通信) が必要な UnrealScript クラスは、=Actor= のサブクラスである必要があります。

このチュートリアルでは、以下のクラスを拡張します。

GameInfo
ゲームロジックの主要クラスで、UDK を用いてのアプリケーション作成では、大抵はこのゲームのサブクラスを作成することになります。
PlayerController
このクラスはプレーヤーを表しますが、見える部分ではなく、入力を処理してアクションを実行します。プレーヤーの実際の表現は (存在する場合) Pawn サブクラスが実行します。

...

GameInfo サブクラス

大半のアクションの開始点となるのが GameInfo サブクラスで、作成する PlayerController クラスと、その他各種の重要なゲームロジッククラスをこのクラスで定義します。このチュートリアルではクラスについて簡単に説明しているだけですが、実際に説明に値する情報はあまりありません。

クラス宣言

新しいクラスを作成するには、=Classes= ディレクトリ内にそのクラスを格納するパッケージファイルを作成し、クラスの名前と同じ名前を付けます。例えば CluOne アプリケーションの場合、=CluOneGame= という名前の GameInfo サブクラスを作成し、それをファイル UDK\Development\Src\CluOne\Classes\CluOneGame.uc に保存します。

UnrealScript クラスのクラス宣言は次のとおりです。

class CluOneGame extends GameInfo;

セミコロン (;) が行末にあり、中カッコがない点に注意してください。クラス宣言の下にあるものはすべてそのクラスに属し、1 つのファイルに 1 つのクラスしか宣言できません。

新しいプレーヤーコントローラー

CluOne アプリケーションは新しい PlayerController クラスを使用します。ユーザーがゲームに接続すると、=GameInfo= クラスはこのユーザーのコントローラーを作成します。=GameInfo= クラスが正しいクラスを作成するために、ソースコードの末尾に以下のコードを追加します。

defaultproperties
{
    PlayerControllerClass=class'CluOnePlayerController'
}

defaultproperties ブロックでは特定変数のデフォルト値を宣言します。これは他のプログラミング言語の変数初期化と同様に機能します (ただし、まったく同じではありません)。デフォルトの GameInfo 実装では、=PlayerControllerClass= 変数の値に基づいて PlayerController インスタンスが作成されます。もちろん、正しいクラスインスタンスを作成する方法は他にもありますが、これが一番簡単で最良の方法です。

ユーザーへの挨拶

GameInfo クラスには、ユーザーがサーバーに接続するとトリガされる一連のイベントがあります。これら 3 つのイベントは、=PreLogin=、=Login= および PostLogin です。 イベント名からイベント順序が分かります。=PostLogin= イベントでは、ユーザーは完全に接続を確立し、対話可能な状態にあります。

この時点でユーザーへの挨拶が必要です。

event PostLogin( PlayerController NewPlayer )
{
    super.PostLogin(NewPlayer);
    NewPlayer.ClientMessage("Welcome to the grid "$NewPlayer.PlayerReplicationInfo.PlayerName);
    NewPlayer.ClientMessage("Point at an object and press the left mouds button to retrieve the target's information");
}

デフォルトのプレーヤー名は変数 DefaultPlayerName で定義されます。これはローカライズ文字列として定義します。デフォルト名を適切に変更するには、ローカライズファイルを更新しますが、ここでは次の関数を用いてプレーヤー名をハードコードしてみます。

event PlayerController Login(string Portal, string Options, const UniqueNetID UniqueID, out string ErrorMessage)
{
	local PlayerController PC;
	PC = super.Login(Portal, Options, UniqueID, ErrorMessage);
	ChangeName(PC, "Clu", true);
    return PC;
}

PlayerController サブクラス

最も面白い内容が展開されるのが、カスタムの PlayerController クラスです。

まずはこのクラスの簡単な宣言から始めましょう。

class CluOnePlayerController extends PlayerController;

クロスヘア (crosshair、照準)

デフォルトでは、PlayerController クラスはクロスヘアを表示せず、さまざまな既存のサブクラスで表示します。クロスヘアを最終的に画面に描画する方法はさまざまで、プレーヤーが現在保持しているインベントリ項目にデリゲートすることも、HUD から描画することも、直接 PlayerController から描画することもできます。

PlayerController で現在の HUD から DrawHud(...) 関数が呼び出され、画面に追加項目を描きます。次のコードは、画面中央に小さな緑の十字を描きます。

/**
 * クロスヘアを描画する。この関数は Engine.HUD クラスにより呼び出される。
 */
function DrawHUD( HUD H )
{
	local float CrosshairSize;
	super.DrawHUD(H);

	H.Canvas.SetDrawColor(0,255,0,255);

	CrosshairSize = 4;

	H.Canvas.SetPos(H.CenterX - CrosshairSize, H.CenterY);
	H.Canvas.DrawRect(2*CrosshairSize + 1, 1);

	H.Canvas.SetPos(H.CenterX, H.CenterY - CrosshairSize);
	H.Canvas.DrawRect(1, 2*CrosshairSize + 1);
}

Fire ボタン

これで視点をあわせる照準が見えるようになりました。次に、この「何かに注目する」行為を開始する手段が必要です。眺めることはいつでもできますが、特定の情報を求めるときにはユーザーは左マウスボタンを押します。

それは、入力処理システムによって左マウスボタンが fire アクションにマッピングされているからです。Fire アクションは、実際には「コンソールコマンド」の実行シーケンスです (ファイル Engine\Config\BaseInput.ini を参照してください)。

特定のクラス (player controller クラスなど) で exec 修飾子を使って定義される関数は、いわゆる「コンソールコマンド」として受け入れられます。 Fire アクションとして実行されるコンソールコマンドの 1 つが StartFire で、=StartFire= コマンドは PlayerController クラスに定義されています。カスタムのプレーヤーコントローラークラスでは、この関数をオーバーライドして独自のロジックを追加することにします。

/*
 * プレーヤーコントローラーのデフォルトステート
 */
auto state PlayerWaiting
{
	/*
	 * この関数は、ユーザーが fire キー (デフォルトでは左マウスボタン) を押すと呼び出される。
	 */
	exec function StartFire( optional byte FireModeNum )
	{
		showTargetInfo();
	}
}

見てのとおり、この StartFire 関数は PlayerWaiting というステートにおいて宣言されています。UnrealEngine のアクタ関連クラスは「潜在ステートマシン (状態機械)」であり、つまりアクタの現在のステートに応じて、関数の特定の実装を呼び出すことを意味します。言い換えると、アクタのステートによっては、Fire ボタンを押したときの振る舞いが異なる可能性があります。プレーヤーコントローラーのデフォルトのステート (すなわち "auto state") は、=PlayerWaiting= ステートなので、そのステートにある StartFire 関数をオーバーライドしたのです。

注目の対象物に関する情報を表示する実際のコードは、=showTargetInfo= 関数に実装されています。

注目の対象物

現在のプレーヤーの注目の先を判別するには、その視線が最初に遭遇するものまでトレースする必要があります。これは、=Actor= クラスに定義されている trace(...) 関数を用いて行います。Trace 関数は、物体が見えるかどうかの判定、または武器発射の標的を設定する場合に多数使用されます。

ここでは、この関数を使って視線が最初に遭遇するゲーム要素を検知することにします。何かに遭遇したらサウンドを再生し、その要素に関する数行の情報を出力します。

/*
 * 注目の対象物に関する情報を出力する
 */
function showTargetInfo()
{
	local vector loc, norm, end;
	local TraceHitInfo hitInfo;
	local Actor traceHit;

	end = Location + normal(vector(Rotation))*32768; // "infinity" までトレース
	traceHit = trace(loc, norm, end, Location, true,, hitInfo);

	ClientMessage("");

	if (traceHit == none)
	{
		ClientMessage("Nothing found, try again.");
		return;
	}

	// 情報確認のサウンドを再生
	ClientPlaySound(SoundCue'A_Vehicle_Cicada.SoundCues.A_Vehicle_Cicada_TargetLock');

	// デフォルトでは、一度に 4 件のコンソールメッセージを表示するだけ
 	ClientMessage("Hit: "$traceHit$"  class: "$traceHit.class.outer.name$"."$traceHit.class);
 	ClientMessage("Location: "$loc.X$","$loc.Y$","$loc.Z);
 	ClientMessage("Material: "$hitInfo.Material$"  PhysMaterial: "$hitInfo.PhysMaterial);
	ClientMessage("Component: "$hitInfo.HitComponent);
}

始点から、指定された終点までトレースが行われます。始点には、プレーヤーコントローラーの現在の位置を使用しています。終点は "infinity" を指すようにして、そのためにプレーヤーコントローラーの現在の回転ベクトルを正規化し、それを用いて現在の位置を延長しています。この回転はカメラ角度を定義し、正規化したベクトルに、ワールド (この大きさは -32767 から 32768 までの範囲) の最大距離をかけています。これは基本的なベクトル計算で、3D で何かをするにはこれをちゃんと理解しておく必要があります。

ClientMessage(...) 関数は、現在のプレーヤーに関する情報をコンソールに出力します。この関数は、プレーヤー間または特定のゲームイベント間の通信にも使われます。また、デバッグ情報を画面に表示するのにも適しています (ただしこの場合には、アプリケーションを出荷する前にデバッグコードを忘れずに除去してください)。

サンプルスクリプトの仕上げ

小さな UnrealScript サンプルはこれで終わりです。UDK を使って実際のアプリケーションを記述できるようになる前に習得しておくことがもっとたくさんあります。このドキュメントの末尾にある UnrealScript および UnrealEngine のゲームフレームワークに関連する情報を参照してください。

このサンプルのソースコードはこちら からダウンロードできます。

コンパイル

ソースコードのコンパイルにはいくつかの方法があります。UDK をサポートする IDE を使用する場合は、[Compile] (コンパイル) ボタンを押すだけでプロジェクトを簡単にコンパイルできます。

もう 1 つのコンパイル方法は UnrealFrontend の使用です。Frontend を起動してツールバーの [Make] ボタンを押すだけで、コンパイラが初期化されます。このボタンは何度でも押すことができ、ソースファイルが変更されたときにコードをコンパイルします。完全なリコンパイルを開始することも可能で、これには [Make] ボタンの横にある下向き矢印を押して、[Full Recompile] を選択します。

FrontendMake.png

Frontend に関するひとつの問題として、完全なリコンパイルの出力結果が表示されないことがあり、このような場合には手動でログファイルを開かなければなりません。

3 番目の方法は、上記 2 つの方法でコンパイラを開始する方法でもあるのですが、コマンドラインの実行です。通常のコンパイル命令は次のように出します

C:\UDK\UDK-2009-11\Binaries\Win32\udk.com make

完全なリコンパイルを実行するには、このコマンドラインに -full 引数を追加するだけです。

コンソールコマンドを実行するときは、=udk.exe= 実行ファイルではなく udk.com 実行ファイルを使用するようにしてください。いずれの機能も同じですが、=udk.com= コマンドは標準出力に出力結果を送りますが、=udk.exe= は特別なウィンドウに表示します。ビルド スクリプト (Makefile または Ant ビルドスクリプトなど) のコンパイラを使用したい場合は、標準出力に出力を送る必要があります。この場合にはコマンドラインスイッチ -unattended も追加するとよいでしょう。これによりコンパイル中に対話型プロンプトが表示されなくなります。

作成したパッケージがコンパイル処理中に見つけられない場合は、=UTGame\Config\UTEngine.ini= ファイルの [UnrealEd.EditorEngine] セクションにそれらを ModEditPackages として追加する必要があります。

テスティング

コードのコンパイルに成功したら、アプリケーションをテストして新しい機能が意図したとおりに動作するかどうかを確認します。

ほとんどの場合は、UDK をクライアント モードで開始し、起動 URL を指定してアプリケーションをテストします。=CluOne= アプリケーションを開始するには、次のように指定して UDK を開始します。

C:\UDK\UDK-2009-11\Binaries\Win32\udk ExampleMap?game=CluOne.CluOneGame

この場合の起動 URL は ExampleMap?game=CluOne.CluOneGame です。マップ名か (ここでは ExampleMap) または参加するサーバーのホスト名/IP を指定して URL を開始します。その後に一連の ?key=value 要素が続きます。これらはさまざまな設定を制御しますが、その中で最も重要な keygame で、これはゲーム開始時に作成される GameInfo サブクラスを定義します。値はクラスの完全修飾名です (例: PackageName.ClassName)。他の有効な ?key=value の要素は、普通は作成される GameInfo サブクラスによって決まります。

この例ではマップ ExampleMap が使われていますが、これは小さなマップなのでロード時間もわずかです。

デバッグ

このドキュメントを書いている時点では、UDK に特化したデバッガのサポートはありません。UT3 と同様に、UDK についても近い将来に nFringe で UnrealScript? のデバッグが適切に機能し、ブレークポイントの設定や、コードの段階的実行ができるようになるでしょうが、それが実現されるまでは古典的なデバッグ方法に頼るしかありません。

予想したとおりに事が運ばない場合、通常は 2 つの原因が考えられます。

  1. コードが呼び出されていない。
  2. 未設定のデータにアクセスしている (つまり、null ポインタ参照)。

後者の場合はログを調べることで簡単に検出できます。ログには貴重な情報が保存されるので、開発中には常にログから目を離さないようにしてください。ログを常に監視するには、コンソールログ機能を有効にしてクライアントを起動するのが一番よい方法です。これには以下のコマンドを使用します。

C:\UDK\UDK-2009-11\Binaries\Win32\udk.exe -log

これによりコンソールウィンドウが開き、ログ情報の同時出力を開始します。別の方法としては、クライアントを先に閉じてから、=UTGame\Logs= ディレクトリにあるログファイルを読むことができます。

ログの出力データを調べるときには、以下のような行に注意してください。

Log: Accessed None 'AccessControl'
        UTDeathmatch DM-Deck.TheWorld:PersistentLevel.UTDeathmatch_0
        Function Engine.GameInfo:Login:0358

"Accessed None" は、UnrealScript における null ポインタ例外を意味します。このログは読み込まれた変数の名前を示し、この AccessControl の場合にそれが none または null であったこと、およびそれが発生した関数 (この場合はクラス Engine.GameInfoLogin) を示しています。数字 0358 は行番号 ではなく バイトコードのオフセットなので 無視してください。これを簡単に行番号に変換する方法がないためですが、少なくともどこで問題が起こったかはこれで分かります。

何が発生し、何が発生していないかを追跡管理するには、ログ出力に書き込まれる項目を追加するのが良い方法で、以下のようなコードを書くだけで簡単に実行できます。

`log("This will add a line to the log output");

log の前にあるバックティック (` のこと、引用符 ' と混同しないでください) に注意してください。実際には、これは本当のログ関数呼び出しを作成する preprocessor directive (プリプロセッサディレクティブ) です。このマクロの完全なシグネチャは次のとおりです。

`log(logMessage,expression,prefix);

logMessage
ログに送られるメッセージ。
expression
これは式ですが、指定する場合は true の場合にメッセージがログに送られるようにする必要があります。
prefix
ログメッセージの接頭辞として使用する名前。ログメッセージを他と区別するのに非常に便利です。

この簡単なステートメントによって、特定のイベントがいつ発生するかを追跡できます。

function foo(Bar quux)
{
    if (quux == none)
    {
        `log("foo was called but quux was none");
    }
    else {
        `log("Performing foo on "$quux)
    }
}

その他の役に立つマクロディレクティブについては、=Development\src\CoreGlobals.uci= などのファイルを参照してください。

もう 1 つの非常に便利なデバッグ機能は、=Object= に定義されている関数 ScriptTrace() です。この関数を呼び出すと、スタックトレースをログ出力にダンプします。これを使って、現在の位置に至るまでの一連の関数呼び出しを調べることができます。

大切な注意が 1 つあります。コードは警告なしでコンパイルされます。コンパイル時には警告は問題にはなりませんが、コードを実行するときにエラーが発生することがよくあります。

関連ドキュメント