UEFN では、小道具を動かす方法がいくつかあります。 TeleportTo[] や MoveTo() などの関数を使用して、トランスフォームを直接変更することや、小道具移動装置などの別の仕掛けを使用して小道具をプリセット パス上で動かすことができます。 ただし、アニメーションの形で別の便利なオプションもあります。
クリエイティブの各小道具には、そのアニメーションを再生するために使用できる play_animation_controller があります。 アニメーションには、小道具のトランスフォームを動かすことに関していくつかのメリットがあります。 アニメーションによる移動は通常、MoveTo() や TeleportTo() によるオブジェクトの移動よりも滑らかです。それは、ゲーム ティックごとに関数を呼び出すことによるネットワーク レイテンシーを回避できるためです。 また、アニメーションでは、プレイヤーや他のオブジェクトとのコリジョンがより一貫したものになり、小道具移動装置の仕掛けを使用する場合と比べて、オブジェクトがどこでどのように動くかをより細かく制御できます。 アニメーションを、ループして再生したり、ピンポン モードで順方向と逆方向に再生したりすることができます。
また、アニメーションでは補間タイプを選択することもできます。 補間タイプによって、アニメーションのイージングのタイプや、アニメーションが追従するアニメーション カーブが決まります。 たとえば、線形補間タイプでは、アニメーションが一定の速度で再生されますが、イーズイン タイプでは、低速で始まり、終点に近づくにつれて加速します。 使用するアニメーションに適切な補間タイプを選択することで、小道具がさまざまなポイントで、減速するか、加速するか、線形に動くかを指定できます。
障害物に応じてさまざまなアニメーションを切り替えることで、同じ小道具を使用して、プレイヤーに対する異なるさまざまな課題を作成することができます。 このセクションでは、この強力なツールを使用して、独自のアニメーションを作成し、小道具を動かす方法について説明します。
アニメーション コントロールを設定する
以下の手順に従って、小道具に対するアニメーション コントロールを設定します。
Verse Explorer を使用して、「
movement_behaviors」という新規 Verse ファイルを作成します。 このファイルには、小道具をアニメートするために必要なユーティリティ関数が格納されます。using { /Fortnite.com/Devices }、using { /Fortnite.com/Devices/CreativeAnimation }文およびusing { /UnrealEngine.com/Temporary/SpatialMath }文をファイルの先頭に追加して、これらのモジュールがインポートされるようにします。 これらは、小道具をアニメートするために必要になります。「
movement_behaviors」内で、move_to_ease_typeという新しいenumを作成します。 この列挙型内の値は、さまざまなアニメーション イージング タイプに対応します。 各イージング タイプは、InterpolationTypesモジュールで確認できます。Verse# This file stores functions common to animating creative props using keyframes. # It also defines the move_to_ease_type enum to help in building animations. using { /Fortnite.com/Devices } using { /UnrealEngine.com/Temporary/SpatialMath } using { /Fortnite.com/Devices/CreativeAnimation } # Represents the different movement easing types. move_to_ease_type<public> := enum {Linear, Ease, EaseIn, EaseOut, EaseInOut}VectorOnesという新しいvector3型エイリアスを追加します。これは、<code>X、Y、Zがすべて1.0に設定されているvector3</code> を作成します。 後でこのベクターを使用すると一部の数学演算が容易になるように、その型エイリアスを定義することで、vector3{X:=1.0, Y:=1.0, Z:=1.0}を繰り返し記述する必要がなくなります。Verse# Initializes a vector3 with all values set to 1.0. VectorOnes<public>:vector3 = vector3{X:=1.0, Y:=1.0, Z:=1.0}move_to_ease_typeを受け取ってcubic_bezier_parametersを返す新しいメソッドGetCubicBezierForEaseType()を追加します。Verse# Return the cubic_bezier_parameters based on the given move_to_ease_type. GetCubicBezierForEaseType(EaseType:move_to_ease_type):cubic_bezier_parameters=キュービック ベジェは、アニメーションで使用されるイージング関数のタイプを定義する 4 つの数値で構成されています。 たとえば、イーズイン カーブのパラメータでは、開始時にアニメーションを低速にし、その後に加速できます。 線形カーブのパラメータでは、アニメーション再生を一定速度にできます。 これらの値を定義して独自のカスタム アニメーション カーブを作成できますが、この例では
InterpolationTypesモジュールで定義されている値を使用するため、独自に定義する必要はありません。GetCubicBezierForEaseType()内のcase()式で、move_to_ease_typeに基づいて、InterpolationTypesモジュールからcubic_bezier_parametersを取得します。 たとえば、EaseOutであればInterpolationTypes.EaseOutを返し、LinearであればInterpolationTypes.Linearを返します。 完成したGetCubicBezierForEaseType()関数は次のようになります。Verse# Return the cubic_bezier_parameters based on the given move_to_ease_type. GetCubicBezierForEaseType(EaseType:move_to_ease_type):cubic_bezier_parameters= case (EaseType): move_to_ease_type.Linear => InterpolationTypes.Linear move_to_ease_type.Ease => InterpolationTypes.Ease move_to_ease_type.EaseIn => InterpolationTypes.EaseIn move_to_ease_type.EaseOut => InterpolationTypes.EaseOut move_to_ease_type.EaseInOut => InterpolationTypes.EaseInOutmovable_propクラスに戻り、MoveEaseTypeという新しい編集可能なmove_to_ease_typeを追加します。 これは、小道具のアニメーションに適用されるイージング タイプです。Verse# The type of animation easing to apply to the RootProp's movement. The easing type # changes the speed of the animation based on its animation curve. @editable {ToolTip := MoveEaseTypeTip} MoveEaseType:move_to_ease_type = move_to_ease_type.EaseInOut
キーフレームを使用してアニメーションを作成する
コードでアニメーションを作成するには、キーフレームを使用します。 アニメーションは 1 つまたは複数のキーフレームから作成され、各キーフレームでは、アニメーションの特定のポイントでのオブジェクトの値が指定されます。 キーフレームを使用してアニメーションを作成することで、小道具を移動、回転、またはスケールするポイントを複数指定できます。
キーフレームには 5 つの値があります。 DeltaLocation、DeltaRotation、および DeltaScale では、キーフレームの開始から終了までに小道具が行う各値の変化を指定します。 また、アニメーションの持続時間 (秒) である Time と、キーフレームの補間モードである Interpolation があります。 キーフレームの例は次のようになります。
# An example keyframe.
KeyFrame := keyframe_delta:
# The target position of the `creative_prop`. This is the difference between the starting and ending translation of the prop.
DeltaLocation := EndTransform.Translation - StartTransform.Translation,
# The target rotation for the `creative_prop` to rotate to.
DeltaRotation := EndTransform.Rotation,
# The target scale for the `creative_prop`. Scale is multiplicative to the starting Scale of the `creative_prop`
以下の手順に従って、キーフレームを使用してアニメーションを作成します。
MoveToEase()という新しいcreative_prop拡張メソッドを「movement_behaviors」ファイルに追加します。 この関数は、動かす小道具の位置/回転/スケール、アニメーションの持続時間、移動のイージング タイプ、およびアニメーション モードを受け取ります。Verse# Animate a creative_prop by constructing an animation from a single keyframe, and then playing that animation on the prop. # This method takes a Position, Rotation, and Scale for the prop to end at, the duration of the animation, # the type of easing to apply to the movement, and the animation mode of the animation. (CreativeProp:creative_prop).MoveToEase<public>(Position:vector3, Rotation:rotation, Scale:vector3, Duration:float, EaseType:move_to_ease_type, AnimationMode:animation_mode)<suspends>:void=MoveToEase()内で、GetAnimationController[]を使用して、クリエイティブの小道具のアニメーション コントローラーを取得します。 このアニメーション コントローラーによって、アニメーションが小道具上で再生され、後で待機するイベントが公開されます。Verse(CreativeProp:creative_prop).MoveToEase<public>(Position:vector3, Rotation:rotation, Scale:vector3, Duration:float, EaseType:move_to_ease_type, AnimationMode:animation_mode)<suspends>:void= # Get the animation controller for the CreativeProp to move. if (AnimController := CreativeProp.GetAnimationController[]):ScaleMultiplicativeを呼び出して、小道具のスケールの変化を計算します。 この状況では、Scaleは少し複雑です。 スケールは乗算されるため、終了トランスフォームのスケールは、スケール後に必要とされる量ではなく、元のトランスフォームに乗算するために必要とされる量である必要があります。 たとえば、元のトランスフォームのスケールが1.2であり、1.5にスケールする場合は、実際には1.25でスケールする必要があります (1.2 * 1.25 = 1.5であるため)。 最終的な値は、VectorOnesに、新しいスケールと以前のスケールの差分を以前のスケールで除算した値を加算した値です。 アニメーションの再生中にアニメーションのサイズを変更した場合に、アニメーションが適切にアニメートされ続けるには、この値が必要です。Verse# Calculate the multiplicative scale for the keyframe to scale to. ScaleMultiplicative:vector3 = VectorOnes + ((Scale - CreativeProp.GetTransform().Scale) / CreativeProp.GetTransform().Scale)各アニメーションでは、実行するキーフレームの配列が必要です。 この関数では、単一のキーフレームのみを使用し、それを配列にキャストします。 この配列にあるのは単一のキーフレームのみであるため、小道具は 1 回の移動で新しい位置まで滑らかにアニメートされます。 そして、ループ内で
MoveToEase()を呼び出すため、連続した複数のアニメーションを指定することなく、小道具をアニメートし続けることができます。Keyframesというkeyframe_deltaの配列を定義します。 この配列を新しい配列と同じ値に設定し、その配列内で、新しいkeyfram_deltaを作成します。Verse# Build the keyframe array from a single keyframe_delta of the given values. Keyframes:[]keyframe_delta = array: keyframe_delta:keyframe_deltaの定義内で、キーフレームの作成に必要となる各値を初期化します。DeltaLocationを、新しいPositionとクリエイティブの小道具の平行移動との差分に設定します。DeltaRotationをRotationに設定し、DeltaScaleを、以前計算したScaleMultiplicativeに設定します。TimeをDurationに設定し、GetCubicBezierForEaseType()を呼び出して適切なInterpolationを設定します。Verse# Build the keyframe array from a single keyframe_delta of the given values. Keyframes:[]keyframe_delta = array: keyframe_delta: DeltaLocation := Position - CreativeProp.GetTransform().Translation, DeltaRotation := Rotation, DeltaScale := ScaleMultiplicative, Time := Duration, Interpolation := GetCubicBezierForEaseType(EaseType)Keyframes配列を作成したので、SetAnimation()にAnimationModeを渡し、その配列をアニメーション コントローラーのアニメーションとして設定します。Play()を使用してアニメーションを再生した後に、Await()でMovementCompletedEventを待機します。 完成したMoveToEase()拡張メソッドは次のようになります。Verse# Animate a creative_prop by constructing an animation from a single keyframe, and then playing that animation on the prop. # This method takes a Position, Rotation, and Scale for the prop to end at, the duration of the animation, # the type of easing to apply to the movement, and the animation mode of the animation. (CreativeProp:creative_prop).MoveToEase<public>(Position:vector3, Rotation:rotation, Scale:vector3, Duration:float, EaseType:move_to_ease_type, AnimationMode:animation_mode)<suspends>:void= # Get the animation controller for the CreativeProp to move. if (AnimController := CreativeProp.GetAnimationController[]): # Calculate the multiplicative scale for the keyframe to scale to. ScaleMultiplicative:vector3 = VectorOnes + ((Scale - CreativeProp.GetTransform().Scale) / CreativeProp.GetTransform().Scale)
関数をオーバーロードする
記述済みの MoveToEase() 関数は有用ですが、呼び出すたびにこれだけ多くの変数を関数に渡すのは面倒です。 小道具のトランスフォームのいずれかだけ (平行移動や回転など) を変更する場合も考えられるため、その場合にもっとシンプルに呼び出すことができる関数があると便利です。
これを解決するために、関数のオーバーロードを利用できます。 MoveToEase() 関数をオーバーロードすることによって、型が異なる入力を処理するための同じ名前の複数のメソッドをセットアップできます。 以下の手順に従って、オーバーロード関数をセットアップします。
「
movement_behaviors」ファイル内で、名前が同じで入力が異なる別の拡張メソッドを作成することで、MoveToEase()関数をオーバーロードします。 このMoveToEase()は小道具の平行移動のみを更新し、回転とスケールは変更しません。 そのため、必要な引数はPosition、Duration、EaseType、AnimationModeだけです。Verse# An overload of MoveToEase() that changes the position of the prop while keeping the rotation and scale the same. (CreativeProp:creative_prop).MoveToEase<public>(Position:vector3, Duration:float, EaseType:move_to_ease_type, AnimationMode:animation_mode)<suspends>:void=新しい
MoveToEase()内で、元のMoveToEase()関数を呼び出し、すべての入力に加えてIdentityRotation()を渡して、ScaleとしてVectorOnesを渡します。IdentityRotation()は、すべての値が0(つまり、(0,0,0)) である回転を返します。 アニメーションに回転を加えたくないため、ここではIdentityRotation()が必要です。 オーバーロードされたMoveToEase()関数は次のようになります。Verse# An overload of MoveToEase() that changes the position of the prop while keeping the rotation and scale the same. (CreativeProp:creative_prop).MoveToEase<public>(Position:vector3, Duration:float, EaseType:move_to_ease_type, AnimationMode:animation_mode)<suspends>:void= CreativeProp.MoveToEase(Position, IdentityRotation(), VectorOnes, Duration, EaseType, AnimationMode)同様の処理を繰り返して、回転のみを変更するが平行移動とスケールは変更しない、もう一つのオーバーロードされたメソッドを作成します。 オーバーロードされた新しいメソッドは次のようになります。
Verse# An overload of MoveToEase() that changes the rotation of the prop while keeping the position and scale the same. (CreativeProp:creative_prop).MoveToEase<public>(Rotation:rotation, Duration:float, EaseType:move_to_ease_type, AnimationMode:animation_mode)<suspends>:void= CreativeProp.MoveToEase(CreativeProp.GetTransform().Translation, Rotation, VectorOnes, Duration, EaseType, AnimationMode)同様の処理をもう一度繰り返して、スケールのみを変更するが平行移動と回転は変更しないメソッドを作成します。 ただし、
translationとscaleはどちらもvector3であり、生成される関数は、平行移動用に作成したオーバーロードと同じシグネチャになるため、エラーになります。 これを解決するために、関数パラメータを並べ替えます。DurationとScaleの位置を入れ替えて、オーバーロードされた関数を取得します。 オーバーロードされたメソッドは次のようになります。Verse# An overload of MoveToEase() that changes the position and scale of the prop while keeping the rotation the same. (CreativeProp:creative_prop).MoveToEase<public>(Duration:float, Scale:vector3, EaseType:move_to_ease_type, AnimationMode:animation_mode)<suspends>:void= CreativeProp.MoveToEase(CreativeProp.GetTransform().Translation, IdentityRotation(), Scale, Duration, EaseType, AnimationMode)複数のキーフレームを処理できるバージョンの
MoveToEase()があると便利です。 事前に複数のキーフレームを設定し、それらすべてをMoveToEase()に渡すことで、複数のキーフレームを処理できます。 そうすることで、この関数はクリエイティブの小道具にアニメーションを設定して再生するだけで済みます。 キーフレームの配列とアニメーション モードを入力として受け取る、MoveToEase()のオーバーロードを追加します。Verse# An overload of MoveToEase() that takes a pre-built array of keyframes and plays an animation. (CreativeProp:creative_prop).MoveToEase<public>(Keyframes:[]keyframe_delta, AnimationMode:animation_mode)<suspends>:void= if (AnimController := CreativeProp.GetAnimationController[]): AnimController.SetAnimation(Keyframes, ?Mode:=AnimationMode) AnimController.Play() AnimController.MovementCompleteEvent.Await()コードを保存してコンパイルします。
メソッドをセットアップできたので、動かしましょう。 次のセクションでは、小道具を平行移動して、プラットフォームを動かします。
完全なコード
このセクションで作成した完全なコードを以下に示します。
movement_behaviors.verse
# This file stores functions common to animating creative props using keyframes.
# It also defines the move_to_ease_type enum to help in building animations.
using { /Fortnite.com/Devices }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Fortnite.com/Characters}
using { /Fortnite.com/Devices/CreativeAnimation }
# Represents the different movement easing types.
move_to_ease_type<public> := enum {Linear, Ease, EaseIn, EaseOut, EaseInOut}