NPC キャラクターの動作は、動作スクリプトによって定義されます。 動作スクリプトは、移動先、戦闘の対象、他のキャラクターとインタラクションする方法など、キャラクターがワールド内で行うべきアクションを指示するためのものです。 ガードや野生動物などのキャラクターには、認知や警戒のほか、雇用や手なずけに対応する機能など、追加の動作が存在する場合があります。
NPC 動作は、NPC キャラクターの既存の動作にさらなる機能を追加するユーザー定義の Verse スクリプトです。 npc_behavior API を使用すると、NPC キャラクターのスポーン時またはデスポーン時に実行されるコードを定義することができます。また、このコードは、衛生兵、店員、ボスなどのカスタム キャラクターを作成するのに利用できます。 NPC 動作は npc_behavior 抽象クラスから継承され、使用するには /Fortnite.com/AI モジュールをインポートする必要があります。
NPC 動作スクリプトを実行するには、NPC キャラクター定義にそのスクリプトをアタッチする必要があります。 NPC 動作スクリプトによるキャラクター定義とのインタラクションの方法は、NPC キャラクターのタイプによって異なります。 カスタムタイプの NPC には、アクションを行うための動作スクリプトが必要です。一方、ガードおよび野生動物タイプの NPC は、動作スクリプトが提供されないとデフォルトの動作を実行します。 NPC キャラクター定義およびさまざまなキャラクター タイプの作成に関する詳細については、「キャラクター定義」のページを参照してください。
このチュートリアルでは、NPC 動作スクリプトの作成の基本を説明し、NPC をスポーンして目標に対してナビゲートする方法を解説します。
新規 NPC 動作スクリプトを作成する
以下の手順に従って、ガードをスポーンして 2 つのポイントをパトロールさせる NPC 動作スクリプトを UEFN で作成します。
UEFN でプロジェクトを開き、メニュー バーから [Verse] > [Verse Explorer] を選択します。
Verse Explorer 内で目的のプロジェクト名を右クリックし、[Add new Verse file to project (新規 Verse ファイルをプロジェクトに追加)] を選択して [Create Verse Script (Verse スクリプトを作成)] ウィンドウを開きます。
[Create Verse Script] ウィンドウで、テンプレートとして選択するために [NPC Behavior (NPC 動作)] をクリックします。
[NPC Behavior Name (NPC 動作の名前)] フィールドのテキストを仕掛けの名前に変更し、NPC 動作に名前を付けます。 この例では、仕掛けの名前は「my_first_npc_behavior」です。
[Create (作成)] をクリックし、Verse ファイルを作成します。
Verse Explorer 内で Verse ファイルの名前をダブルクリックして Visual Studio Code で開きます。
コードを保存し、コンパイルし、新規 NPC キャラクター定義を作成します。 NPC キャラクターの作成の詳細については、「キャラクター定義」のページを参照してください。
my_first_behaviorスクリプトを新規キャラクター定義の Verse 動作として割り当てます。UEFN ツールバーの [Launch Session (セッションを開始)] をクリックしてレベルをプレイテストします。 レベルのプレイテスト時には、NPC スポナーからスポーンしたキャラクターは近くのランダムなポイントを選択し、そのポイントに移動する必要があります。 ポイントに到達したら、一定時間待機してから最初のポイントに戻る必要があります。 島設定の仕掛けから Verse のデバッグ描画を有効にしている場合は、キャラクターがフォーカスしている場所に矢印が表示され、キャラクターが移動しようとしているポイントにボックスが表示されます。
Navigatable
Navigatable API を使用すると、キャラクターを特定の目標に向かわせたり、パトロールや一定のポイントの警備をさせたり、別のキャラクターを追従させたりすることができます。 ガードタイプの NPC は AI のパトロール経路節点を使用してこれを行うことができますが、ここでは Verse コードを使用してこの機能をあらゆるタイプのキャラクターに拡張し、レベル内に追加の仕掛けを配置しなくて済むようにします。 キャラクターの navigatable インターフェースを使用すると、キャラクターを navigation_target に移動させることができます。これは、agent または position から作成できます。 カスタム、ガード、野性生物タイプの NPC は、すべてこの Navigatable によるインターフェースを使用できます。 キャラクターの navigatable インターフェースを取得するには、その fort_character への参照をまず取得する必要がありますが、これは、GetFortCharacter[] を呼び出すことで実行できます。
# Get the Navigatable Interface, this allows you to tell it to move.
Navigatable := Character.GetNavigatable[]
テンプレートの例では、コードによってランダムなオフセットから位置が選択され、その位置からキャラクターがスポーンし、変数 GoToPoint 内に保存されます。 続いて、GotToPoint とキャラクターのスポーン ポイントの両方から navigatoin_target が作成されます。
# Create a random offset from the spawn point to walk toward.
GoToPoint := NPCSpawnPoint + vector3{X := GetRandomFloat(-DistanceFromSpawnPtToMove,DistanceFromSpawnPtToMove),
Y := GetRandomFloat(-DistanceFromSpawnPtToMove,DistanceFromSpawnPtToMove),
Z := 0.0 }
if(ShowAIDebug?):
Print(my_first_npc_behavior_message_module.OnNavigateBeginMessage(Agent,GoToPoint.X,GoToPoint.Y,GoToPoint.Z), ?Duration := AIDebugDrawTime)
# Create a navigation target from these two positions that the navigation interface can use.
NavTargetStart := MakeNavigationTarget(GoToPoint)
NavigateTo() 関数は、navigation_result 列挙型を返します。これには、キャラクターが navigation_target に到達したかどうかを示す情報が含まれています。 navigation_result の値をチェックし、ターゲットに到達したかどうかに基づき、キャラクターに動作を与えることができます。
# Check to see if something has interfered with the NPC reaching the intended location and print a
# message to the output log.
if (NavResultGoTo <> navigation_result.Reached):
if(ShowAIDebug?):
Print(my_first_npc_behavior_message_module.OnNavigateErrorMessage(Agent,GoToPoint.X,GoToPoint.Y,GoToPoint.Z), ?Duration := AIDebugDrawTime)
else:
# Once it arrives at its location, wait for this duration in seconds
Navigatable.Wait(?Duration := MoveToWaitDuration)キャラクターがワールドを移動する方法、およびキャラクターが移動できるさまざまな領域を視覚化する方法については、「ナビゲーション メッシュ」ページを参照してください。
フォーカス
キャラクターがアクションを行う場合、そのキャラクターは特定のターゲットを注視します。 キャラクターが注視している特定のターゲットは、そのキャラクターのフォーカスとなります。 キャラクターのフォーカスの対象は、話している相手のキャラクター、攻撃しているターゲット、移動先となる位置などがあります。 focus_interface を使用すると、キャラクターがフォーカスする特定のターゲットを指定することができます。 カスタム、ガード、野性生物タイプの NPC は、すべてこのフォーカス インターフェースを使用できます。 MaintainFocus() 関数は、キャラクターのフォーカスをターゲットに合わせます。これは vector3 の位置か agent にすることができます。 focus_interface は fort_character インターフェースの一部であり、GetFocusInterface[] を使用して取得できます。
# Get the Focus Interface, this allows you to tell it to look at something or somewhere.
Focus := Character.GetFocusInterface[]
テンプレートの例では、キャラクターが最初の位置に移動を開始した後で、コードによって MaintainFocus() が使用され、前の navigation_target にフォーカスを合わせることが強制されています。 これによって、キャラクターは逆方向に歩くようになり、最初のポイントに戻りながら背後を監視します。
# Leveraging concurrency to wait until the NPC reaches its destination, while the calls to look back at its origin point
# and drawing a debug arrow never completes, continuing, ensures only the NavigateTo can win the race.
NavResultGoToNext := race:
# Move back to its starting position.
Navigatable.NavigateTo(NavTargetEnd)
# Sets NPC to look at its previous position which will make it walk backwards.
# This is meant to show the utility of the focus interface.
block:
Focus.MaintainFocus(GoToPoint)
Leashable
ガードが特定の目標をガードする場合は、ガードがその目標周辺の領域にとどまり、他の場所に離れていかないようにする必要があります。 fort_leashable インターフェースは、ガードタイプの NPC に固有のインターフェースです。これを使用すると、ガードがターゲットを中心としてパトロールを行う範囲の半径を指定できます。 ガードには特定の位置か、他の NPC に対してリードを設定できます。また、リードのターゲットが移動した場合、ガードはその位置を更新し、リードの近くにとどまれるようにします。 なお、現在、カスタムおよび野生動物タイプの NPC キャラクターは fort_leashable インターフェースを使用できません。 fort_leashable インターフェースは、GetFortLeashable[] を使用して取得できます。
# Get the Leash Interface, which lets you confine a guard to a certain area.
Leashable := Character.GetFortLeashable[]
キャプチャー ポイントをガードする場合や重要な NPC を守る場合など、ガードには特定の位置か、他のエージェントに対してリードを設定できます。 各リードには InnerRadius と OuterRadius があります。これは、リードのターゲットに対してそれぞれ、センチメートル単位で近づける距離と離れられる距離を指定します。 テンプレートの例では leashable インターフェースを使用していませんが、独自のガード NPC を作成する場合に便利な場合があるでしょう。
# Leash the guard to a position so they stay between 500 and 1000
# cm of the position they're leashed to
Leashable.SetLeashPosition(NPCSpawnPoint, InnerRadius := 500.0, OuterRadius := 1000.0)
# Leash the guard to an agent so they stay between 500 and 1000
# cm of the agent they're leashed to
Leashable.SetLeashAgent(AgentToFollow, InnerRadius := 500.0, OuterRadius := 1000.0)
# Clear all leashes on the guard
Leashable.ClearLeash()
デバッグ描画
このファイルの先頭で、このテンプレートにはデバッグ描画のための専用のチャンネルが定義されています。 デバッグ描画を使用し、テスト目的で特定のゲーム データを視覚化することができます。 たとえば、キャラクターの表示領域を視覚化したり、キャラクターの移動先の場所を中心として形状を描画したりすることができます。 [Island Settings] の [Debug (デバッグ)] タブで、[Verse Debug Draw (Verse デバッグ描画)] を有効にしてこれらのデバッグ形状を視覚化します。なお、公開された体験ではこれらは表示されません。 ファイルの先頭のチャンネルを使用すると、チャンネル内のデバッグ形状を 1 つの方法で非表示にしたり、表示したり、クリアしたりすることができます。
# Create a dedicated debug channel to draw to for this behavior
npc_debug_draw := class(debug_draw_channel) {}
new_npc_behavior テンプレート クラスは、ビジュアライゼーションや移動に使用される複数の値を定義します。
MoveToWaitDurationは、キャラクターがポイントから移動する前に待機する時間の長さ (秒単位) を定義します。Verse# How long to wait in seconds after the NPC navigates to a point before moving on. @editable_number(float): Categories:=array{my_first_npc_behavior_message_module.SettingsCategory}, MinValue:=option{0.5}, MaxValue:=option{10.0} MoveToWaitDuration:float = 5.0DistanceFromSpawnPtToMoveは、キャラクターが移動するスポーンポイントからのランダムなオフセットの範囲を定義します。Verse# The negative min and absolute max x & y coordinate offset in centimeters to tell the NPC to move to @editable_number(float): Categories:=array{my_first_npc_behavior_message_module.SettingsCategory}, MinValue:=option{0.0} DistanceFromSpawnPtToMove:float = 1500.0ShowAIDebugロジック値を使用すると、エディタのデバッグ形状の描画を切り替えることができます。Verse# Whether to draw debug to the NPC channel when Verse Debug Draw is enabled in Island Settings. @editable: Categories:=array{my_first_npc_behavior_message_module.SettingsCategory} ShowAIDebug:logic = trueAIDebugDrawTimeの浮動小数点数を使用すると、デバッグ描画の場所をレンダリングするための時間を指定できます。Verse# How long in seconds to render the debug draw location and print text. # It is recommended to keep this in sync with MoveToWaitDuration otherwise the print will not be shown if a previous message is displayed. @editable_number(float): Categories:=array{my_first_npc_behavior_message_module.SettingsCategory}, MinValue:=option{0.5} AIDebugDrawTime:float = 5.0LookAtDebugDrawDurationの浮動小数点数を使用すると、矢印のデバッグ描画の表示をレンダリングするための時間を指定できます。Verse# How long in seconds to render the look at arrow's debug draw. LookAtDebugDrawDuration:float = 0.5DebugDrawNPCチャンネルは、デバッグ描画インスタンスを定義し、ファイルの先頭で定義されたチャンネルを使用します。Verse# How long in seconds to render the look at arrow's debug draw. @editable_number(float): Categories:=array{my_first_npc_behavior_message_module.SettingsCategory}, MinValue:=option{0.5} LookAtDebugDrawDuration:float = 0.5最後に、
VerticalOffsetToNPCHeadは、デバッグの視線の矢印を描画するために、NPC の骨盤から頭までのこのオフセットを定義します。 このオフセットがない場合、デバッグの視線の矢印は、NPC の中心から描画されます。Verse# Used for specifying a point offset from the NPC pelvis to the head to draw the look at arrow from. VerticalOffsetToNPCHead<private>:float = 55.0
new_npc_behavior テンプレート クラスの 2 つの関数は、デバッグ形状を描画します。 DrawDebugLocation() 関数は、指定された位置の大きなポイントを、LookAtDebugDrawDuration の時間数だけ描画します。
# This function draws a box around a specified position for a finite amount of time.
# NOTE: To see this in game, Verse Debug Draw must be enabled in Island Settings.
DrawDebugLocation(Location:vector3):void =
DebugDrawNPC.DrawPoint( Location,
?Color := NamedColors.SteelBlue,
?Thickness := 100.0,
?DrawDurationPolicy := debug_draw_duration_policy.FiniteDuration,
?Duration := AIDebugDrawTime )
DrawDebugLookAt() 関数を使用すると、エージェントの頭部から注視ポイントまでの矢印を描画することで、キャラクターが見ている場所を視覚化できます。
# This function draws an arrow from the Agent's head to its look at point every half a second.
# NOTE: To see this in game, Verse Debug Draw must be enabled in Island Settings.
DrawDebugLookAt(Character:fort_character, LookAtPoint:vector3)<suspends>:void=
loop:
DebugDrawNPC.DrawArrow( Character.GetTransform().Translation + vector3{ Z := VerticalOffsetToNPCHead},
LookAtPoint,
?ArrowSize := 50.0,
?Color := NamedColors.Yellow,
?Thickness := 5.0,
?DrawDurationPolicy := debug_draw_duration_policy.FiniteDuration,
キャラクターをレベルに追加する
NPC 動作スクリプトの概要が学習できたら、次はキャラクターを作成して島でスクリプトを使用しましょう。 次のワークフローは、ガードタイプのキャラクター向けにデザインされたものですが、NPC 動作スクリプトは、カスタムおよび野生動物タイプのキャラクターでも機能します。
MyFirstCharacterDefinition という名前の新しい NPC キャラクター定義を作成します。 新しいキャラクター定義をクリックし、[Character Definition (キャラクター定義)] 画面を開きます。
[Character Definition] 画面で、次のプロパティを変更します。
[NPC Character Type (NPC キャラクターのタイプ)] で、[Type (タイプ)] を [Guard (ガード)] に設定します。 [Guard] インターフェースを使用すると、ガードがアラートや不審の状態になっているときのイベントや、ガードを雇用して味方として活用するなど、ガードに固有のキャラクターの機能にアクセスできます。 また、ガードは武器を装備できます。一方、カスタムおよび野生動物タイプのキャラクターは、現時点では装備できません。 さらに、キャラクターの名前は [Name (名前)] タブで変更できます。
[NPC Character Behavior (NPC キャラクター動作)] で、[Behavior (動作)] を [Verse Behavior (Verse 動作)] に設定します。 続いて、[NPC Behavior Script (NPC 動作スクリプト)] を
my_first_npc_behaviorに設定します。 キャラクターは、引き続き [Guard] インターフェースから機能にアクセスできますが、OnBeginとOnEndの間で Verse スクリプトを使用して実行すべきアクションを決定します。[Modifiers (モディファイア)] タブの [Guard Spawn Modifier (ガード スポーン モディファイア)] で、[Cosmetic (ビジュアル)] タブをクリックし、キャラクターのビジュアル面のアピアランスを変更します。 既存のビジュアルから選択することも、[Character Cosmetic Retargeting (キャラクターのビジュアル リターゲティング)] を有効にしてカスタム モデルを使用することもできます。 なお、ガードおよびカスタム タイプのキャラクターのみがキャラクターのビジュアル リターゲティングを利用できますが、野生動物は利用できません。 キャラクターのモディファイアや、さまざまなキャラクター タイプに適用するモディファイアの詳細については、「NPC キャラクター定義」のページを参照してください。
[Modifiers] タブで、[Add Element (要素を追加)] をクリックし、新しいモディファイアをキャラクターに追加します。 新しいモディファイアのタイプを [Inventory Modifier (インベントリ モディファイア)] に変更します。 なお、インベントリ モディファイアは、ガードのみが使用できます。
[Inventory Modifier] で、[Add Element] をクリックし、キャラクターのインベントリに新しいアイテムを追加します。 [Item Definition (アイテム定義)] を、キャラクターが装備する必要がある武器、アイテム、またはその他のいずれかに設定します。 キャラクターのインベントリには複数のアイテムを追加できます。また、キャラクターは武器を戦闘に使用したり、消耗品を回復に使用したりします。
[Modifiers] タブで、[Add Element (要素を追加)] をクリックし、新しいモディファイアをキャラクターに追加します。 新しいモディファイアのタイプを [UI Modifier (UI モディファイア)] に変更します。
[UI Modifier] で、[Name (名前)] タブをクリックし、キャラクターの名前を変更すると、 キャラクターの名前が頭上に表示されます。
NPC キャラクター定義を保存します。 コンテンツ ブラウザで、NPC キャラクター定義をレベルにドラッグします。 これにより、新しい NPC スポナーが自動的に作成され、そのスポナーにキャラクター定義が割り当てられます。
NPC スポナーを選択します。 アウトライナーで、次の手順に従って [User Options (ユーザー オプション)] を選択します。
[Spawn Count (スポーン数)] を「20」に設定します。 複数のガードのサポートが必要になると思われるため、最大数にして楽しんでみましょう。
UEFN ツールバーの [Launch Session (セッションを開始)] をクリックしてレベルをプレイテストします。 プレイテスト時には、キャラクターが最初のポイントと、その近くのランダムなポイントの間でキャラクターがスポーンしてパトロールし、途中で敵が出現すれば戦う必要があります。
応用編
このガイドを完了したことで、NPC 動作スクリプトを作成し、最初のカスタム キャラクターを作成する方法を習得できました。 詳細について、および特定のタイプのキャラクターやシナリオを作成する方法については、以下に記載されているいくつかの NPC 動作のチュートリアルを参照してください。