これは、早期アクセス版の機能です。 この機能を使用して島を公開することはできますが、早期アクセス期間中は変更によって島が機能しなくなる可能性があります。その場合は、ご自身で対処する必要がありますので、ご注意ください。
NPC スポナーは、シーケンサーでバインディング存続期間トラックが必要です。31.00 以前に作成された既存のシーケンスにこのトラックを遡及的に追加することはできません。バインディング存続期間トラックを追加した後に、シーケンスで NPC スポナーを使用する島を再公開する必要があります。
バインディング存続期間トラックを追加するには、次の手順を実行します。
-
[Track (トラック)] リストで [NPC Spawner (NPC スポナー)] の横にある [+] アイコンをクリックします。
-
ドロップダウン メニューから [Binding Lifetime (バインディング存続期間)] を選択します。
シーケンサー を使用してカスタム キャラクター アニメーションを作成すると、NPC スポナー の仕掛け を含め、さまざまな方法や複数の仕掛けで再生できます。 イベント または ムービー シーケンス の仕掛けと組み合わせた シーケンサー を使用して、AI のパトロール経路 の選択ポイントに従って、パターン化された動作でアニメーションを設定および再生します。
MetaHuman を含め、インポート および Unreal Engine (UE) からカスタム アニメーションを移行) できます。これを行うために、フォートナイト キャラクターに独自のスケルタル構造があるので、スケルタルメッシュを リターゲティング して NPC キャラクターに合わせることが必要になる場合があります。
MetaHuman キャラクターはメモリの負荷がかかります。 使用する MetaHuman アセットの数を制限することを推奨します。
シーケンサーでの NPC をアニメートする
NPC スポナーの仕掛けを使用すると、インタラクティブなキャラクターから情報量の多いカットシーンまで、プロジェクトでさまざまなゲームプレイを制作できるようになります。コントロール リグ で NPC スポナーにカスタム アニメーションを作成します。あるいは、購入または他のソフトウェアで作成したアニメーションをインポートします。
FK コントロール リグ を使用して、リターゲティングされたアニメーション またはエモートで NPC をアニメートすることもできます。
詳細については、UE ドキュメントの「FK Control Rig」のアニメーション ワークフローを確認してください。
NPC キャラクターがあるアニメーションをキャプチャするには、以下の手順に従います。
-
コンテンツ ブラウザ 内を右クリックし、レベル シーケンス を作成します。
-
レベル シーケンス のサムネイルの名前を変更します。
-
レベル シーケンス のサムネイルをダブルクリックして、シーケンサー エディタ を開きます。
-
[+Track (+トラック)] をクリックし、[Actor to Sequencer (シーケンサーへのアクタ)] > [NPC Spawner (NPC スポナー)] を選択します。これにより、レベル シーケンス トラックに NPC スポナーの仕掛けが追加されます。
NPC スポナーの仕掛けを アウトライナー からトラック リストにドラッグして、レベル シーケンスに追加できます。
-
トラック リストの NPC スポナーの仕掛けの横にある [+] アイコンをクリックして、[Control Rig (コントロール リグ)] > [Control Rig Classes (Control Rig クラス)] > [FK Control Rig (FK コントロール リグ)] を選択します。これにより、NPC のスケルトンがトラックに追加され、操作および記録するスケルトンの個々のボーンにアクセスできるようになります。
-
ビューポート、アニメーション アウトライナー またはシーケンサーから移動したいボーンを選択して、アニメーションの開始位置に移動します。
-
移動したボーンの横にある [+] アイコンをクリックして、最初のキーフレームを設定します。
FBX アニメーション シーケンス ファイルとして作成または購入したアニメーションがある場合、NPC スポナーの横にある [+] アイコンをクリックして [Animation (アニメーション)] > [Animation file (アニメーション ファイル)] を選択することで、タイムラインの NPC スポナーの仕掛けのアニメーション トラックに、これらのファイルを追加できます。
アニメーションが完了するまで、引き続きボーンを移動してシーケンサーに新しいキーフレームを設定します。 アニメーションが完了したら、シーケンサーでアニメーションを再生して移動内容が環境に合っていることを確認します。
アニメーションを後ろから再生する簡単な方法は、タイムラインのアニメーション ファイルを右クリックして [Properties (プロパティ)] > [Reverse (反転)] を選択します。
満足できる結果であれば、アニメーションをスケルタルメッシュにベイクします。NPC スポナーを右クリックし、[Bake Animation Sequence (アニメーション シーケンスをベイク)] を選択します。
アニメーションを再生したときに、スケルタルメッシュのリムがスケルタルメッシュのボディの他の部分を突き抜けていないことを確認します。
動作の属性を記録する
動作の属性と NPC スポナーの仕掛けを使用することもできます。 動作オプションは、NPC がフォートナイト バトルロイヤルの NPC から継承する基本の特性を決定します。 これらの特性は、NPC がガードのように動作するか、野生生物のように動作するかを決定します。
動作の属性と NPC スポナーの仕掛けの設定方法の詳細については、「NPC キャラクター定義」のドキュメント を参照してください。
動作の属性を設定したら、レベル シーケンスのアニメーションをキーフレーム化して、ゲームプレイ中にムービー シーケンスの仕掛けで再生できます。 前述のステップとは異なり、動作が NPC スポナーの仕掛けのオプションで設定されているので、コントロール リグにパフォーマンスをベイクする必要がありません。
作成したアニメーションや、継承した動作と AI のパトロール経路節点の仕掛け を使用したり、Cine Camera アクタ で作成したパスに従って NPC を記録したりすることもできます。
スポーン可能な NPC バインディングと置き換え可能な NPC バインディング
2 通りの方法 (スポーン可能な NPC バインディングと置き換え可能な NPC バインディング) で、シーケンスに NPC を追加できるようになりました。これらのバインディングは、NPC キャラクター定義から作成されます。
スポーン可能な NPC バインディング
シネマティック シーケンスを使用すると、スポーン可能な NPC バインディング は、NPC キャラクター定義 に基づいてアクタをワールドにスポーンできます。この NPC は、他のスケルタルメッシュと同じようにシーケンサーでアニメートできます。
スポーン可能な NPC バインディングを作成するには、NPC キャラクター定義をシーケンサーにドラッグするだけです。
gif をクリックすると拡大表示されます。
スポーン可能なバインディングは、他のスケルタルメッシュ アクタと同様にアニメートすることができます。次に例を示します。
-
[+ Animation (+ アニメーション)] をクリックし、NPC アニメーション キャラクター定義のダンスのエモートを選択します。
gif をクリックすると拡大表示されます。
-
再生ヘッドをさらに前に移動し、NPC を新しい場所にドラッグして、新しいキーフレームを設定します。これで、NPC がポイント A からポイント B に移動します。
gif をクリックすると拡大表示されます。
置き換え可能な NPC バインディング
置き換え可能な NPC バインディング は、ワールドにスポーンされた NPC を制御し、シーケンスに配置します。その後、シーケンサーで作成されたアニメーションを実行できます。NPC がシーケンサーにバインドされている間、すべての動作、認識、および経路追従は一時停止されます。これらは、NPC がバインド解除されると再開されます。
NPC は、バインドが解除されると、元の場所に戻ります。
置き換え可能な NPC バインディングを作成するには、スポーン可能な NPC バインディングを作成し、バインディングを右クリックして、[Convert selecting binding to (選択したバインディングを変換)] > [Replaceable NPC Character (置き換え可能な NPC キャラクター)] を選択します。
gif をクリックすると拡大表示されます。
変換後、トラックはバインディング存続期間トラックに置き換えられます。スポーン可能なバインディングに加えられたすべての変更は保持されます。
ゲームプレイ時に NPC を見つけてバインドするには、NPC キャラクター定義にモディファイア (シーケンサー モディファイア) を追加する必要があります。他のモディファイアと同じ方法を使用して、これを NPC キャラクター定義に追加することができます。このモディファイアを追加しないと、検証が失敗します。
gif をクリックすると拡大表示されます。
シーケンサー モディファイアには、Unique Identifier プロパティがあります。このプロパティは、ゲーム内でスポーンされた NPC を見つけるために使用されます。デフォルト値は、NPC キャラクター定義の名前です。なお、2 つの異なる NPC キャラクター定義に同一の一意の識別子がある場合、ゲーム内でシーケンスを再生するときに両方がバインドされる場合があります。
ゲームでシーケンスを再生する
シーケンスを再生するには、通常どおりムービー シーケンスの仕掛けを使用します。
スポーン可能なバインディングを再生するために、その他の設定は必要ありません。
置き換え可能なバインディングでは、NPC キャラクター定義を使用する NPC スポナーをワールドに追加する必要があります。置き換え可能なバインディングがバインド先の NPC を見つけられない場合、クライアント ログに次の行が表示されます。
LogFortNPCMovieSceneBindings: Warning: Could not bind to a pawn using NPC Character Definition Guard.Please ensure there is at least one spawned. (LogFortNPCMovieSceneBindings:警告:NPC キャラクター定義ガードを使用してポーンにバインドできませんでした。1 つ以上の NPC がスポーンされていることを確認してください。)
シーケンスの再生と同時に NPC をスポーンする予定の場合は、スポーン可能なバインディングを使用することを検討するか、On Spawned イベント をムービー シーケンスの仕掛けの Play 関数に接続することを検討してください。
カスタム ブループリント NPC
カスタム ブループリントを使用する NPC キャラクター定義を除き、ほとんどの NPC タイプはスケルタルメッシュとしてバインドされます。
これにより、ブループリントがバインドされ、VFX などの追加コンポーネントが公開されます。これらは、その後シーケンサーで変更することができます。
以下は、NPC の頭が爆発するように、シーケンサーで Niagara パーティクル システムが変更されていることがわかります。
gif をクリックすると拡大表示されます。
既知の制限事項
- 置き換え可能な NPC バインディングは、ムービー シーケンスの仕掛けが [Visibility: Everyone (可視性:全員)] に設定されている場合にのみ使用できます。その他の [Visibility (可視性)] 設定を使用すると検証が失敗します。
- 置き換え可能な NPC バインディングを、乗ることができる、または飼いならせる野生動物 NPC と併用しようとすると、検証が失敗します。
- NPC キャラクター定義を使用する置き換え可能な NPC バインディングでは、[Finish Completion State Override (終了時の完了状態のオーバーライド)] ユーザー オプションの [Force Keep State (状態を強制維持)] オプションを使用できません。このオプションを使用すると検証が失敗します。
- NPC がシーケンサーによってバインドされると、所定の位置にスナップされます。さらに、遅延の問題により、NPC がバインドされたりバインド解除されたりするときに、非常に短い視覚的なバグが発生することがあります。このため、置き換え可能な NPC バインディングを使用する場合は、NPC をオフスクリーンでスポーンしたり、画面をフェードしたり、VFX や可視性トラックなどの手法を活用することを強くお勧めします。
アニメーションを Verse で呼び出す
アセット リフレクション を使用してアニメーションを Verse に公開することで、アニメーション モジュールを使用して NPC でカスタム アニメーションを再生できます。
アニメーション コントローラー インターフェース
play_animation_controller インターフェースを使用すると、キャラクター上のアニメーションを再生できます。これは GetPlayAnimationController() 関数で取り込むことができます。このインターフェースは、アニメーションを再生する次の 2 つの関数を公開します。同期 Play() 関数と非同期 PlayAndAwait() 関数です。
どちらの関数も次のパラメータを受け入れます。
| オプション | 値 | 説明 |
|---|---|---|
| Animation | アニメーションを選択します | 再生するアニメーション。「Assets.digest.verse」ファイルでアニメーションを指定する。 |
| PlayRate | 1.0、再生レートを選択します | アニメーションの再生速度。値 1.0 は、アニメーションのデフォルトの速度に対応します |
| BlendInTime | 0.0、BlendInTime を選択します | 前のアニメーションを現在のアニメーションにブレンドする時間の長さ。 |
| BlendOutTime | 0.0、BlendOutTime を選択します | 現在のアニメーションを次のアニメーションにブレンドする時間の長さ。 |
| StartPositionSeconds | 0.0、StartPositionSeconds を選択します | アニメーションの再生を開始する秒単位の位置。 |
Play And Await 関数
PlayAndAwait() 関数は非同期にアニメーションを再生し、play_animation_result の 列挙型 のインスタンスを返します。これには Completed、Interrupted、Error の 3 つの値が含まれています。これらは完了したアニメーション、中断されたアニメーション、発生しているエラーにそれぞれ対応しています。この列挙型のクエリを実行すると、アニメーションの結果に基づいてさまざまなコードを実行できます。
AnimationResult := PlayAnimController.PlayAndAwait(MyAnimation)
case(AnimationResult):
play_animation_result.Completed => Print("Animation Completed!")
play_animation_result.Interrupted => Print("Animation Interrupted.")
play_animation_result.Error => ("Error Occurred during animation.")
再生機能
Play() 関数は同期的に実行され、playing_animation_instance クラスのインスタンスを返します。playing_animation_instance クラスを使用すると、進行中のアニメーションのクエリと操作を実行できます。これには次の値が含まれています。
| 値 | 説明 |
|---|---|
| GetState() | この関数は、play_animation_state 列挙型でアニメーション再生の現在の状態を返します。 |
| Stop() | この関数は現在のアニメーションを停止します。 |
| CompletedEvent | アニメーションが完了すると、このイベントがトリガーされます。 |
| InterruptedEvent | アニメーションが中断すると、このイベントがトリガーされます。 |
| BlendedInEvent | アニメーションがブレンド アウトを終了すると、このイベントがトリガーされます。 |
| BlendingOutEvent | アニメーションがブレンド アウトを開始すると、このイベントがトリガーされます。 |
| Await() | この関数は、アニメーションが完了するか中断されるのを待機します。特に、play_animation_result 列挙型を返し、PlayAndAwait() を呼び出すことと機能的に同じです。 |
Play() 関数を使用して、進行中のアニメーションを操作したり、アニメーションの特定の条件を満たした場合にコードを実行したりできます。
# アニメーションを同期的に再生し、アニメーションのインスタンスを取得します
AnimationInstance := PlayAnimController.Play(MyAnimation, ?PlayRate := PlayRate, ?BlendInTime := BlendInTime, ?BlendOutTime := BlendInTime, ?StartPositionSeconds := StartPositionSeconds)
# アニメーションが完了したときに実行する関数をサブスクライブします
AnimationInstance.CompletedEvent.Subscribe(OnAnimationComplete)
Sleep(1.0)
AnimationState := AnimationInstance.GetState()
# 1 分経過後もアニメーションが再生している場合、アニメーションを停止します
if(AnimationState = play_animation_state.BlendingOut):
AnimationInstance.Stop()
アニメーションの再生の例
以下のコードに、アニメーション モジュールを使用してアニメーションを再生する NPC の動作の例を示します。キャラクターに再生したいカスタム アニメーションを アセット リフレクション で Verse に公開し、これを「Assets.digest.verse」ファイルに配置する必要があります。この例では、アニメーション MyAnimation は Assets.digest.verse のカスタム MyCharacter キャラクターのアニメーション モジュールにあるので、MyCharacter.Animations.MyCharacter を介して呼び出されます。
using { /Fortnite.com/AI}
using { /Fortnite.com/Animation/PlayAnimation}
using { /Verse.org/Simulation}
using { /Fortnite.com/Characters}
basic_play_anim_example := class(npc_behavior):
# アニメーションの再生速度。
@editable
PlayRate : float = 1.0
# 前のアニメーションを現在のアニメーションに
# ブレンドする時間。
@editable
BlendInTime : float = 0.25
# 現在のアニメーションを次のアニメーションに
# ブレンドする時間。
@editable
BlendOutTime : float = 0.25
# アニメーションの再生を開始する
# 秒単位の位置。
@editable
StartPositionSeconds : float = 0.0
# アニメーションを再開する前に待機する時間。
@editable
SleepDuration : float = 2.0
OnBegin<override>()<suspends>:void=
if:
# NPC キャラクターのアニメーション コントローラーを取得します
Agent := GetAgent[]
FortCharacter := Agent.GetFortCharacter[]
PlayAnimController := FortCharacter.GetPlayAnimationController[]
then:
AnimationResult := PlayAnimController.PlayAndAwait(MyCharacter.Animations.MyAnimation, ?PlayRate := PlayRate, ?BlendInTime := BlendInTime, ?BlendOutTime := BlendInTime, ?StartPositionSeconds := StartPositionSeconds)
# アニメーションの実行結果を出力します。
case(AnimationResult):
play_animation_result.Completed => Print("Animation Completed!")
play_animation_result.Interrupted => Print("Animation Interrupted.")
play_animation_result.Error => ("Error Occurred during animation.")
Sleep(SleepDuration)
# アニメーションを同期的に再生し、アニメーションのインスタンスを取得します。
AnimationInstance := PlayAnimController.Play(MyCharacter.Animations.MyAnimation, ?PlayRate := PlayRate, ?BlendInTime := BlendInTime, ?BlendOutTime := BlendInTime, ?StartPositionSeconds := StartPositionSeconds)
Sleep(SleepDuration)
AnimationState := AnimationInstance.GetState()
# アニメーションの現在の状態を出力します。
case(AnimationState):
play_animation_state.Playing => Print("Animation Playing!")
play_animation_state.BlendingIn => Print("Animation Blending In!")
play_animation_state.BlendingOut => Print("Animation Blending Out!")
play_animation_state.Completed => Print("Animation Completed!")
play_animation_state.Stopped => Print("Animation Stopped!")
play_animation_state.Interrupted => Print("Animation Interrupted!")
play_animation_state.Error => Print("Error Occurred During Animation")
else:
Print("Could not get animation controller")