UDN
Search public documentation:

CharactersTechnicalGuideJP
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 ホーム > ゲームプレイプログラミング > キャラクター技術ガイド

キャラクター技術ガイド


2011年7月に UDK に即して最終テスト実施済み

概要


Unreal においてキャラクターは 2 つの部分から成り立っています。それは、Pawn (ポーン) と Controller (コントローラー) の 2 つです。Pawn とは、ワールドにおける、プレーヤーおよび NPC (ノンプレイアブルキャラクター) の身体像のことです。Pawn は、プレーヤーによるコントロールと AI によるコントロールを区別しません。Pawn は、メッシュ、コリジョン、物理をもっていて、これによって、キャラクターとワールド間で起きる物理的インタラクションに関係する機能をすべて処理できるようになります。また、Pawn には、他のプレーヤーや環境からダメージを受ける機能があります。その場合、サウンドの発生やアニメーションの再生がともないます。また、Pawn には、武器を持ったり発砲したり (またはその両方を行う) といったような、あらゆるインベントリの機能も備わっています (ただし、武器の発砲プロセスは、技術的にはコントローラークラスから始動されます)。

各 Pawn は、どの時点においても単一の Controller を持つことができます。Controller は、その名前が示すとおり、何を行うか、どのように行動するかを Pawn に指示します。本質的には、Pawn の背後にある脳に相当します。Controller には数種類あります。たとえば、PlayerController や AIController などです。ただし、それらに共通する主な目的は、ワールドにおいてプレーヤーまたは他の刺激から入力を受け取り、その入力を処理し、それに応じて Pawn を行動させることにあります。たいていの場合、これによって、何らかのコマンドあるいは一連のコマンド群が Pawn に渡されることになります。

通常の状況では、ログイン時に全プレーヤーの Controller が作成されますが、それは GameInfo クラスによって処理されます。その後に、match (試合) が始まる場合は、GameInfo クラスによって各 Controller のために Pawn が作成され、その Controller に割り当てられます。この最後の処理は、 possession (所有) と呼ばれます。その理由は、Pawn が Controller に所有され、Controller の制御のもとに置かれるからです。プレーヤーを完成させるプロセスは、下図のようになります。

CreationProcess.jpg

もちろん、いつも上記のようなプロセスである必要はありません。ゲームを構成する世界が、手作業で配置され、動的には生成されないNPC がいる世界の場合もあるでしょう。これらの NPC は、ほとんどの場合、基本 Pawn クラスのサブクラスであるはずです。基本 Pawn クラスは、NPC 自身のための Controller 作成を処理し、NPC 自身をその Controller に割り当てるクラスです。

Controllers


Controller は、Pawn に付属させることによってその行動を制御する非物理的な Actor です。プレーヤーまたは環境から得られた情報を使用することによって、Pawn にその情報に応じた行動を取らせるのです。Controller は移動を管理します。移動が、プレーヤーによる入力に対して反応するものであっても、あるいは、ナビゲーションシステムによって生成されたパスを進んだり、各種イベントに基づいて行動を実行しているものであっても同様に管理されます。Pawn がゲーム内で移動するのは、Controller がそのように命じるためです。Controller が制御している Pawn には、イベントが発生します。たとえば、敵の姿や声を見たり聞いたりするようなイベントです。Controller は、これらのイベントについて多数の通知を受け取ります。Controller は、これらのイベントを利用し、そのイベントに応じた適切な行動を Pawn に実装します。

Controller の主要なサブクラスは 2 つあり、 PlayerControllerAIController がそれに当たります。新しいキャラクターを作成する場合は、これらのクラスのうち 1 つを派生させるか、あるいは、これらのクラスの更なるサブクラスから 1 つを派生させます。これは、どのような種類のキャラクターを作成するかによります。

また、Controller (特に AIController) は、State (状態) を大量に使用します。それによって、Controller が同一クラス内にある関数をオーバーライドすることが可能になるとともに、Controller の現在の状態に応じてさまざまな行動を関数に実行させることが可能になります。さらに、State によって、潜在的なコードおよび潜在的な関数が使用できるようにもなります。たとえば、AI のキャラクターがワールドをナビゲートするときに使用される移動の関数などが利用可能となります。

Controller

基本 Controller クラスには、一般的な関数とイベントが含まれています。これらは、Pawn 一般を制御するためのものであり、Pawn がプレーヤーに制御されているのか、あるいは AI に制御されているのかということに必ずしも対応しているわけではありません。

Pawn と所有

以下の関数は、Pawn の所有と所有解除にかかわるものです。

  • Possess [inPawn] [bVehicleTransition] 指定された Pawn を、Controller の Pawn に割り当てるとともに、PossessedBy() 関数を呼び出すことによって Pawn に対して通知します。
  • UnPossess Controller による Pawn への参照を解除するとともに、UnPossessedBy() 関数を呼び出すことによって、もはや Controller に制御されなくなったことをPawnに対して通知します。

インベントリ

以下の関数は、ピックアップ (収集されたアイテム) および武器、その他インベントリ固有の機能にかかわるものです。

  • RatePickup [PickupHolder] [PickupClass] ピックアップの望ましさを計算する PickupFactory からのコールバック関数です。
  • HandlePickup [InvetoryItem] この関数は、空のプレースホルダーです。オーバーライドすることによって、収集されたアイテムを扱う関数を追加実装できます。
  • FireWeaponAt [inActor] Controller が所有する Pawn が、指定されたアクタを標的にして現在アクティブな武器を発砲します。
  • StopFiring Controller が所有する Pawn が、現在アクティブな武器の発砲を中止します。
  • SwitchToBestWeapon [bForceNewWeapon] Controller が所有するPawnのインベントリにおいて、どの武器が最も有効であるかを計算し、それをアクティブな武器にします。オプションのブールパラメータによって、現在アクティブな武器とは異なる武器を選択できるようになります。これは、そのアクティブな武器が最も有効であるか否かにかかわりなく実行できます。
  • ClientSetWeapon [WeaponClass] Controller が所有する Pawn が、指定された武器に変更されます。ただし、Pawn のインベントリにその種の武器が存在することが前提となっています。

武器の詳細については、 武器システムのテクニカルガイド を参照してください。

移動とナビゲーション

次の関数は、所有された Pawn にワールドを潜在的に移動させる場合にかかわるものです。潜在的な移動とは、特定の目的地に行くようにコマンドが与えられることによって、ティックごとに更新されることなく移動が自動化されることを意味します。

  • MoveTo [NewDestination] [ViewFocus] [DestinationOffset] [bShouldWalk] Pawn が指定された目的地まで移動します。あるいは、目的地から指定された任意のオフセットまでの距離内を移動します。その場合、フォーカスは指定された任意のアクタ上に保たれます。この関数は、パスネットワークを使用することによって、Pawn が目的地までナビゲートできるようにします。
  • MoveToDirectNonPathPos [NewDestination] [ViewFocus] [DestinationOffset] [bShouldWalk] MoveTo() と同じ機能を持ちますが、パスを通らないで最終目的地に向かって移動する場合にのみ使用される点が異なります。
  • MoveToward [NewTarget] [ViewFocus] [DestinationOffset] [bUseStrafing] [bShouldWalk] NewTarget として指定された所定のアクタまで Pawn を移動させます。この関数は、他の Pawn あるいはインベントリアクタに向かって移動する場合、ナビゲーションネットワークを利用します。
  • FindPathTo [aPoint] [MaxPathLength] [bReturnPartial] 指定された目的地に最も近いナビゲーションノードへのパスを計算し、そのバス沿いにある次のノードを返します。
  • FindPathToward [anActor] [bWeightDetours] [MaxPathLength] [bReturnPartial] 指定されたアクタに最も近いナビゲーションノードへのパスを計算し、そのバス沿いにある次のノードを返します。
  • FindPathTowardNearest [GoalClass] [bWeightDetours] [MaxPathLength] [bReturnpartial] 指定されたクラスに最も近いノードへのパスを計算し、そのバス沿いにある次のノードを返します。
  • FindPathToIntercept [Pawn] [InRouteGoal] [bWeightDetours] [MaxPathLength] [bReturnpartial] 指定された Pawn がワールドを移動するときに、Pawn をインターセプトするパスを計算し、そのバス沿いにある次のノードを返します。
  • PointReachable [aPoint] Pawn の移動能力を考慮して、指定された場所に直接到達できるか否かを返します。この関数は、コストが高くなる可能性があるため、できれば使用を避けて ActorReachable() を使うようにしてください。
  • ActorReachable [anActor] Pawn の移動能力を考慮して、指定されたアクタに直接到達できるか否かを返します。この関数は、潜在的には PointReachable() よりも最適化されてはいるものの、やはりコストが高くなる可能性があるため、節約して使用してください。
  • FindRandomDest ナビゲーションネットワーク上にあるランダムなノードを返します。キャラクターがワールドをぶらつきながら歩くステートを作成する場合に役立ちます。

AI およびナビゲーションに関する詳細については、 AI システムの概要 を参照してください。

カメラ / 照準

このセクションの関数は、Controller とその Pawn の視点および視線の照準にかかわるものです。

  • GetPlayerViewPoint [out_Location] [out_Rotation] Controller が所有する Pawn の視点を返します。人プレーヤーにとっては、カメラの視点になります。AI に制御されるプレーヤーにとっては、Pawn の目から見た視点になります。基本的な実装では、単に、Controller 自体の位置と回転に相当します。
  • GetActorEyesViewPoint [out_Location] [out_Rotation] Controller またはその Pawn が存在している場合、その視点を返します。基本的には、プレーヤーがどの方向をどこから見ているかという情報を返します。
  • IsAimingAt [Target] [Epsilon] Controller が現在指定されたターゲットに照準を合わせているか否かを返します。ただし、その場合、指定された誤差の範囲内に照準が位置しているかどうかが考慮されます。Epsilon (イプシロン) の値が 1.0 である場合は、ターゲットに直接照準を合わせています。この値が低くなれば、その分だけ誤差が考慮されることになります。

プレーヤー Controller

人プレーヤーから入力を受け取り、ゲーム内で取られる行動に加工する機能は、PlayerController とそのサブクラスで実装されます。たいていの場合、プレーヤーが押したボタンやキーに基づいて、PlayerController が処理する行動には、次のようなものがあります。すなわち、Pawn を移動させたり、カメラを制御したり (Pawn 経由で)、武器を変更または発砲したりといった行動です。以下では、PlayerController クラスの主な関数についていくつか個々に解説していきます。

概説

次の関数は、実質上一般的なものであり、特定のカテゴリーには分類されません。

  • Playertick [DeltaTime] プレーヤーのための主要な更新用関数です。サイクルごとに実行されます。
  • ConsoleCommand [Command] プレーヤーから入力されたコンソールコマンドであるかのように、指定されたコマンドを実行します。

プレーヤー 入力 / 移動

この関数は、プレーヤーの入力と移動にかかわるものです。

  • InitInputSystem PlayerController の PlayerInput クラスの新たなインスタンスを生成することによって、入力システムを初期設定します。
  • PlayerMove [DeltaTime] 現在の移動のために新たな加速値と回転値を計算します。その後、ProcessMove() (プレーヤーが一人の場合またはリッスンサーバーの場合)、または、ReplicateMove() (ネットワーククライアントの場合) のいずれかを呼び出します。基本PlayerController クラスにおいては、この関数はスタブにすぎませんが、PlayerWalking ステートなどのような移動に関係する何らかのステート内においては、オーバーライドされます。この関数は、PlayerTick() 関数によって毎サイクルごとに呼び出されます。
  • ProcessMove [DeltaTime] [newAccel] [DoubleClickMove] [DeltaRot] クライアント上で現在の移動を処理します。この関数は、移動のために特別な機能が必要となるある種のステート内で、オーバーライドされます。
  • ReplicateMove [DeltaTime] [newAccel] [DoubleClickMove] [DeltaRot] 移動に関する処理を開始します。現在の移動をPendingMove リストに保存し、その後、ProcessMove() および ServerMove() (サーバー上で実行される) を呼び出します。
  • ServerMove [TimeStamp] [inAccel] [ClientLoc] [MoveFlags] [ClientRoll] [View] この関数は、サーバー上でしか実行されません。MoveAutonomous() を呼び出すことによって、現在の移動を実行します。また、この関数は、更新が必要かどうかについても判断します。判断の根拠となるのは、最後の更新から時間が十分経過したかどうか、あるいは、クライアント上の位置とサーバー上の位置の間に誤差が十分にあるかどうかということです。
  • Move Autonomous [DeltaTime] [MoveFlags] [newAccel] [DeltaRot] ProcessMove() を呼び出し、実行に必要な、あらゆる自立的な物理に関する計算を更新します。
  • ClientUpdatePosition クライアント上の位置を更新して、サーバ上の位置に一致させます。この関数は、PlayerTick() 関数から呼び出されますが、ServerMove() 関数が必要と認めた場合に限ります。
  • UpdateRotation [DeltaTime] プレーヤーの入力に基づいて、Controller の回転および Controller が所有する Pawn の回転を更新します。
  • ProcessViewRotation [DeltaTime] [out_ViewRotation] [DeltaRot] プレーヤーの入力に基づいて、プレーヤーの視野の回転を処理するとともに、その結果得られる回転を出力します。この関数は、UpdateRotation() によって呼び出されます。

AI Controller

Pawn の環境を観察し、そこから得られる情報に基づいて知的な判断を行う機能は、AIController とそのサブクラスによって実装されます。AIController は、基本的に、自身の自己完結型決定ループを使用することによって、意思決定プロセスを継続的に繰り返し、その決定に基づいて適切な行動を実行します。以下で、AIController クラスの主な関数について解説していきます。

意思決定

AI によって制御されるエンティティ (存在物) を扱う場合、意思決定プロセスは極めて重要なものになります。情報を処理するとともに、それに基づいて何を行いどのように振舞うか決定する主体がなければ、NPC キャラクターは単なる立像にすぎません。確かに、すぐれたAI を作成する方法について論じるのは、本ドキュメントが扱うべき範囲からは逸脱します。しかし、AIController クラス構造のどこにどのようにして AI のコードを付け加えるのかということについては、知っておかなければなりません。以下にあげる関数が、意思決定プロセスにおいて主な担い手となります。

注意: 以下の関数は、AIController クラスではなく、UDKBot クラスで実装されます。以下の関数を利用するには、UDKBot クラスまたは UTBot クラスを拡張する必要があります。

  • ExecuteWhatToDoNext 意思決定プロセスにおいて中心となるエントリーポイントです。決定ロジックの大多数を含むべきです。ただし、この関数が実行されるのは物理ティックの間なので、物理ステートを変更するものは一切含んではいけません。
  • WhatToDoNext ExecuteWhatToDoNext() が次のティックで呼び出されるようにします。また、物理ティックの間に実行するのが危険なコードも含めることができます。この関数は、LatentWhatToDonext() を使用するため、ステートコード内部から呼び出されることはありません。
  • LatentWhatToDoNext WhatToDoNext() の呼び出しをカプセル化するとともに、ティック遅れの意思決定プロセスが開始するのを待機する状態をカプセル化します。この関数がステートコードから呼び出されることによって、次の意思決定ループを待つ間、ステートが中断されます。

Pawn

Pawn クラスは、Unreal 内のすべてのプレーヤー、キャラクター、クリーチャー、その他のタイプのエンティティの基本クラスです。すでに述べたように、Pawn クラスは、プレーヤーまたは AI とワールドの間で生じる物理的インタラクションを管轄します。カスタム Pawn クラスを作成する場合は、どのような機能がすでに存在しているかを最初に確認しておきたいものです。それによって、既存の機能をどのようにオーバーライドするかについて適切な判断を下すことができます。ひいては、新しいキャラクターに望ましい振る舞いをすることができるだけではなく、まったく新しい機能を追加することになった場合に、必要となる時間を配分できるようにもなります。その一助となるように、下記で、Pawn クラスの重要な関数について、機能カテゴリー別に解説していきます。

Controller と所有

次の関数には、Controller と Pawn のインタラクション、および、所有と所有解除にかかわる機能が含まれています。

  • PossessedBy [controller] [bVehicleTransition] この関数は、引数となる Controller を、Pawn の新しい Controller にするとともに、他の必要な動作または初期化を実行します。この関数は、Controller が Pawn を所有する際に、Controller によって呼び出されます。
  • Unpossessed Pawn の Controller を解除するとともに、これに関連する他のプロパティをすべてリセットします。この関数がController から呼び出されるのは、Pawn が死亡した場合、または、Controller が Pawn の所有をこれ以上望まなくなった場合です。後者の例としては、Controller が他の Pawn の所有を望む場合があげられます。
  • SpawnDefaultController 現在Pawnに Controller がない場合、Pawn のために ControllerClass のインスタンスを生成するとともに、Controller が Pawn を所有するようにさせます。この関数は、Pawn の PostBeginPlay() 関数の中で呼び出され、レベルに配置された Pawn またはゲームプレー中にスポーンされた Pawn が。確実に Controller によって所有されるようにします。
  • DetatchFromController [bDestroyController] Controller が Pawn を所有しなくなるようにさせます。また、任意で、所有解除後に Controller を破壊させます。この関数が呼び出されるのは、Pawn が死亡した場合、あるいは、リセットされた場合、破壊されている場合、他の Controller に割り当てられている場合です。

インベントリと武器

インベントリの機能の大多数は、PostBeginPlay() のイベントで生成される Pawn の InventoryManager によって処理されます。ただし、Pawn もその機能のいくつかを処理したり、コマンドを InventoryManager に送ります。これは、インベントリ固有の関数をいくつか使用することによって行われます。また、Pawn クラスには、武器とその発砲にかかわる関数がいくつか含まれています。これらの関数を以下に列挙します。

  • AddDefaultInventory デフォルトのインベントリにリストされているインベントリアイテムを、Pawn のインベントリに追加します。この関数は、GameInfo クラスの AddDefaultInventory() 関数から呼び出されます。
  • CreateInventory [inventoryClass] [bDoNotActivate] 指定されたインベントリクラスのインスタンスを生成し、Pawn のインベントリに追加するとともに、新しいインベントリアイテムを返します。この関数は、実際に実行する InventoryManager に呼び出しを送るにすぎません。
  • FindInventoryType [inventoryClass] [bAllowSubclass] Pawn のインベントリから指定されたクラスのインスタンスを検索し、見つかった場合は、そのインスタンスを返します。
  • TossInventory [invenetoryItem] [forceVelocity] Pawn に、指定されたインベントリアイテムを任意の速度で投げさせるとともに、それを Pawn のインベントリから除外します。
  • ThrowActiveWeapon Pawn に、現在のアクティブな武器を地面に向かって投げさせるとともに、それを Pawn のインベントリから除外します。この関数は、実際に実行する TossInventory() 関数にコマンドを送るにすぎません。
  • SetActiveWeapon [newWeapon] 指定された武器を Pawn のアクティブな武器に設定します。この関数は、実際に実行する InventoryManager にコマンドを送るにすぎません。
  • PlayWeaponSwitch [oldWeapon] [newWeapon] 古い武器から新しい武器に交換する際のアニメーションを Pawn に再生させるために使用される関数です。この関数は、InventoryManager の ChangeWeapon() 関数によって呼び出されます。
  • StartFire [fireModeNum] Pawn に、アクティブな武器を指定された発砲モードで発砲開始させます。この関数は、実際に実行する InventoryManager にコマンドを送ります。
  • StopFire [fireModeNum] Pawn に、アクティブな武器の発砲および発砲モードを停止させます。この関数は、実際に実行する InventoryManager にコマンドを送ります。
  • WeaponFired [weapon] [bViaReplication] [hitLocation] アクティブな武器の発砲にかかわるエフェクトの生成をデリゲートするために使用される関数です。この関数は、アクティブな武器の PlayFireEffects() 関数を呼び出します。
  • WeaponStoppedFiring [weapon] [bViaReplication] アクティブな武器の発砲にかかわるエフェクトをすべて破壊する際、それをデリゲートするために使用される関数です。この関数は、アクティブな武器の StopFireEffects() 関数を呼び出します。

ダメージの受け取り

Pawnクラスには、ヒーリング機能の他に、武器や他の環境からダメージを受け取る機能が含まれています。以下に、ダメージとヘルスにかかわる関数を列挙します。

  • TakeDamage [damage] [instigatedBy] [hitLocation] [momentum] [damageType] [hitInfo] [damageCauser] 指定された量だけ、Pawnのヘルスを減らします。
    • Damage ヘルスを減らす量。
    • InstigatedBy 受け取ったダメージに関わっている Pawn の Controller。
    • HitLocation 適用されるダメージが由来する位置。
    • Momentum ダメージの結果として、Pawn に適用される速度。
    • DamageType 実行されているダメージの種類を記述するダメージタイプのクラス。
    • HitInfo ダメージに関する情報を持つ、任意の TraceHitInfo 構造体。
    • DamageCauser 実行されているダメージに関わる任意のアクタ。
  • HealDamage [amount] [healer] [damageType] 指定された量だけ、Pawn のヘルスを増やします。それによってもたらされるヘルスの上限は、Pawn が持つ最大ヘルス値です。ただし、Pawn が死亡していないことと、すでにヘルスが満たされていないことがこの関数が発動する条件となります。
  • TakeFallingDamage Pawn が落下する速度に基づいて、Pawn にダメージを適用します。この関数は、適切なダメージ量をTakeDamage() 関数に渡します。
  • CrushedBy [otherPawn] 他の Pawn が当該 Pawn に依拠するようになった場合に、当該 Pawn にダメージを受け取らせます。ダメージの量は、当該 Pawn に依拠するようになった Pawn の速度に基づきます。この関数は、Pawn の BaseChange() 関数から呼び出され、ダメージ量を TakeDamage() 関数に渡します。
  • TakeRadiusDamageOnBones [instigatedBy] [baseDamage] [damageRadius] [damageType] [momentum] [hurtOrigin] [bFullDamage] [damageCauser] [bones] 半径依存で減じられるダメージを、Pawn のスケルトンメッシュ上のボーンに関するリストに対して適用します。
  • NotifyTakeHit [instigatedBy] [hitLocation] [damage] [damageType] [momentum] Pawn がダメージを受けたことを知らされる必要がある、あらゆるものに対して通知を送ります。この関数は、Controller の NotifyTakeHit() 関数を呼び出します。
  • TakeDrowningDamage Pawn が水中にいたり、長時間潜水してきたことに基づいて、ダメージを適用します。

アニメーション

Pawn は、主要なビジュアルコンポーネントとして、スケルトンメッシュを使用します。移動など行動のために再生される大量のアニメーションは、Pawn に割り当てられた AnimTree によって処理されますが、ビルトインされているアニメーションを再生する機能については、制限があるのも事実です。機能の多くは、コマンドを Pawn のスケルトンメッシュコンポーネントに渡すヘルパー関数という形態をとります。これらの関数について以下で解説します。

注意: Pawn の SkeletalMeshComponent には、Mesh 変数によって参照されますが、個々のアニメーションシーケンスを再生するための、アニメーション関連の機能が含まれています。これを使用するには、Pawn の AnimTree における唯一のアニメーションノードが、AnimNodeSequence ノードとなっていなければならないということを忘れないでください。これによって、ブレンディングなど AnimTree システムの高度な機能をすべて失ってしまうことになるでしょうが、上記機能は必要に応じて動作します。

  • SetMorphWeight [MorphNodeName] [MorphWieght] Pawn に割り当てられた AnimTree 内部において、特定のモーフノードの重みを設定します。
  • SetSkelControlScale [SkelControlName] [Scale] Pawn に割り当てられた AnimTree 内部において、特定の SkelControl ノードのスケールを設定します。
  • PlayActorFaceFXAnim [AnimSet] [GroupName] [SeqName] [SoundCueToPlay] Pawn に、指定された FaceFX 顔アニメーションシーケンスを再生させます。
  • StopActorFaceFXAnim 現在再生している FaceFX 顔アニメーションシーケンスを停止します。
  • IsActorPlayingFaceFXAnim ブーリアン値を返すことによって、Pawn が現在 FaceFX 顔アニメーションを再生しているか否かを知らせます。

カメラパースペクティブ / 照準

以下の関数には、次の 2 つの機能が含まれています。すなわち、Pawn が現在の視野ターゲットになっている場合に、プレーヤーのカメラの位置と志向性を制御する機能、および、プレーヤーまたは NPC に向けて、現在の照準を設定する機能です。

  • CalcCamera [DeltaTime] [out_CamLoc] [out_CamRot] [out_FOV] Pawn から眺めた時のカメラの視点を計算します。これがプレーヤーのための主となるカメラ計算となります。
  • GetDefaultCameraMode [controller] このPawnのために使用されるべきデフォルトのカメラモードを名前として返します。この関数は、Pawn を所有する時に、Controller によって呼び出されます。
  • ProcessViewRotation [deltaTime] [out_ViewRotation] [out_DeltaRot] プレーヤーの視野の回転を処理するとともに、最終的な視野の回転を out_ViewRotation パラメータとして返します。この関数は、PlayerController の UpdateRotation() 関数から呼び出されます。
  • SetViewRotation [NewRotation] Controller が存在する場合、その回転を設定します。Controller が存在しない場合は、Pawn 自体の回転を設定します。
  • GetActorEyesViewPoint [out_Location] [out_Rotation] Pawn の目、あるいは、プレーヤーの視点の位置と志向性を返します。第1の人のパースペクティブについては、カメラの位置と志向性と同一です。これは、大多数のトレースが実行される際の起点となる視点ともなります。
  • GetBaseAimRotation 照準誤差やオートロック、付着といった調整を一切もたない Pawn の照準回転を、Rotator として返します。
  • GetAdjustedAimFor [Weapon] [StartFireLoc] 中間点によって、照準誤差や自動照準といったあらゆる調整が、基本の照準回転に対して適応されるようになります。デフォルトでは、Controller の GetAdjustedaimFor() 関数にコマンドが渡されます。Pawn のために Controller が存在しない場合は、基本の照準回転を返します。

プレーヤーの例


カスタムメッシュを使用してプレーヤー制御のキャラクターを追加する場合について説明します。これには、3 つの新しいクラスが使用されます。Pawn および PlayerController、GameInfo の 3 つのクラスです。この例の目的は、プレーヤーによって制御される新しいキャラクターを作成する際の基本事項を示すことにあります。基本的な実装を終えると、後は単に、利用可能なものを活用するか、独自のカスタム機能を追加してゲームに適する新たなキャラクターを実装していくということになります。

Player.jpg

プレーヤー Pawn クラス

この例では、新たな Pawn クラスに機能を少し追加します。ビルトインヘルス再生機能を Pawn クラスに与えてみることにします。Tick() 関数の内部で、指定された量のヘルスが、Pawn の現在の Health に頻繁に追加されるものとします。これを完成するために、クラス変数をいくつか追加しました。さらに、Tick() 関数をオーバーライドして、再生を追加しました。

UDNPawn.uc
class UDNPawn extends UTPawn;

var float ElapsedRegenTime;
var float RegenAmount;
var float RegenTime;

event Tick(float DeltaTime)
{
  //calculate elapsed time
  ElapsedRegenTime += DeltaTime;

  //has enough time elapsed?
  if(ElapsedRegenTime >= RegenTime)
  {
    //heal the Pawn and reset elapsed time
    HealDamage(RegenAmount, Controller, class'DamageType');
    ElapsedRegenTime = 0.0f;
  }
}

defaultproperties
{
  //set defaults for regeneration properties
  RegenAmount=2
  RegenTime=1
}

プレーヤー Controller クラス

次の新たな PlayerController クラスは、UTPlayerController をごく基本的に拡張したものです。プレーヤーとして使用するキャラクターのクラスを保持する新しいクラス変数を単に追加しています。またその後、ServerSetCharacterClass() 関数を使用して、そのクラス変数を、プレーヤーのキャラクターに設定しています。

UDNPlayerController.uc
class UDNPlayerController extends UTPlayerController;

var class<UTFamilyInfo> CharacterClass;

simulated event PostBeginPlay()
{
   super.PostBeginPlay();

   SetupPlayerCharacter();
}

/** Set player's character info class & perform any other initialization */
function SetupPlayerCharacter()
{
   //Set character to our custom character
   ServerSetCharacterClass(CharacterClass);
}

defaultproperties
{
   //Points to the UTFamilyInfo class for your custom character
   CharacterClass=class'UDNExamples.UDNFamilyInfo_SpaceMarine'
}

GameInfo クラス

この場合、新しいゲームタイプが必要となります。新たな Pawn クラスおよび PlayerController クラスの使用を明確化するためです。いずれにしても、ゲーム作成においては、ほぼ、UDK を利用しながらカスタムゲームタイプを使うことになるでしょう。それによって、新規に作成するかわりに、適当なデフォルトのプロパティをクラスに追加するだけで済むようになります。この例では、新たなゲームタイプが作成され、単に、DefaultPawnClass プロパティと PlayerControllerClass プロパティが、それぞれ新しい Pawn と PlayerController を指すように設定されているに過ぎません。

UDNGame.uc
class UDNGame extends UTDeathMatch;

defaultproperties
{
   //Points to your custom Pawn class
   DefaultPawnClass=class'UDNExamples.UDNPawn'

   //Points to your custom PlayerController class
   PlayerControllerClass=class'UDNExamples.UDNPlayerController'
}

さてこれで、この新しいゲームタイプを使用してマップを実行する場合、プレーヤーは、ダメージを受けた場合再生し、カスタムキャラクターを使用することになります。

NPC の例


簡単な AI 制御の Pawn について説明するために、新たな Pawn クラスと Controller クラスを作成します。Pawn クラスが、Unreal Editor 内に配置可能になり、メッシュおよびアニメーション、物理プロパティを設定するとともに、使用すべき Controller のクラスを設定するようになります。Controller は、NPC にワールドを歩き回らせます。その際、現在の目的地に NPC が到着するたびに、ランダムな目的地が選択されます。

NPC.jpg

NPC Pawn クラス

この Pawn クラスは、かなり単純です。プロパティが少し追加されていますが、これらは、設計者のために使いやすく作られている既存のプロパティを複製したものにすぎません。SkeletalMeshComponent を使用して、メッシュや AnimTree、AnimSets、PhysicsAsset といったあらゆるビジュアルプロパティを設定します。これに使用されるデフォルト値のいくつかは、デフォルトのプロパティが置かれているブロック内で設定されます。クラスを利用して、使用すべき Controller クラスが、NPC を制御するように設定します。PostBeginPlay() 関数を使用して、既存の ControllerClass 変数を NPCController 変数に設定します。最後に、SetCharacterClassFromInfo() がオーバーライドされていますが、これは何も実行しません。NPC の実装には必要ないからです。

このクラスの完全なソースを以下に示します。

UDNPawn_NPC.uc
class UDNPawn_NPC extends UTPawn
   placeable;

var(NPC) SkeletalMeshComponent NPCMesh;
var(NPC) class<AIController> NPCController;

simulated event PostBeginPlay()
{
   if(NPCController != none)
   {
      //set the existing ControllerClass to our new NPCController class
      ControllerClass = NPCController;
   }

   Super.PostBeginPlay();
}

//override to do nothing
simulated function SetCharacterClassFromInfo(class<UTFamilyInfo> Info)
{
}

defaultproperties
{
   //Setup default NPC mesh
   Begin Object Class=SkeletalMeshComponent Name=NPCMesh0
      SkeletalMesh=SkeletalMesh'CH_LIAM_Cathode.Mesh.SK_CH_LIAM_Cathode'
      PhysicsAsset=PhysicsAsset'CH_AnimCorrupt.Mesh.SK_CH_Corrupt_Male_Physics'
      AnimSets(0)=AnimSet'CH_AnimHuman.Anims.K_AnimHuman_BaseMale'
      AnimtreeTemplate=AnimTree'CH_AnimHuman_Tree.AT_CH_Human'
   End Object
   NPCMesh=NPCMesh0
   Mesh=NPCMesh0
   Components.Add(NPCMesh0)

   //Points to your custom AIController class - as the default value
   NPCController=class'Engine.AIController'
}

NPC Controller クラス

Controller クラスは、考えられうる限り最も基本的なナビゲーションの実装にかかわるクラスです。ExecuteWhatToDoNext() 関数は、主要な意思決定関数ですが、これをオーバーライドして、Controller が絶えず Roaming ステートに送られるようにします。このステートは、単に、目的地が存在するか確認したり、現在の目的地に Pawn がすでに到着しているか確認するとともに、必要に応じて新たな目的地を設定し、Controller に対してそれに向かって移動するように命じます。最後に、LatentWhatToDoNext() 関数を呼び出すことによって、次のティックで ExecuteWhatToDoNext() 関数が再度呼び出されるようになります。その際、意思決定ループが最初からもう一度実行されます。

この Controller クラスのソースは以下に示します。

UDNBot.uc
class UDNBot extends UTBot;

var Actor Destination;

protected event ExecuteWhatToDoNext()
{
   //Go to the roaming state
   GotoState('Roaming');
}

state Roaming
{
Begin:
   //If we just began or we have reached the Destination
   //pick a new destination - at random
   if(Destination == none || Pawn.ReachedDestination(Destination))
   {
      Destination = FindRandomDest();
   }

   //Find a path to the destination and move to the next node in the path
   MoveToward(FindPathToward(Destination), FindPathToward(Destination));

   //fire off next decision loop
   LatentWhatToDoNext();
}

defaultproperties
{
}

新たなカスタム NPC をテストする


新たな NPC クラスは、Actor クラスの中に置かれています。search (検索) ウィジェットを使用するほうが簡単な場合があります。

UDNCTG_ActorClasses.jpg

コンテンツブラウザ内の [Actor Classes] (Actor クラス) タブにおいてアクタが選択されると、ゲームのビューポート内で右クリックすることによって、コンテクストメニューを表示することができるようになります。コンテクストメニュー内で、 Add UDN_PawnNPC Here (ここに UDN_PawnNPC を追加する) というメニュー項目を選択します。

UDNCTG_AddActor.jpg

これによって、NPC がワールド内に置かれます。これで、PIE を使用してゲームをテストできるようになりました。

UDNCTG_PlacedNPC.jpg