【UEFN】 DiabloライクのTop-DownViewカメラを作る Part.1(Verseの学習③)
DiabloライクのTop-DownViewカメラを作る
Twitterでサンプルを公開したところ、反響が多かったため、Top-DownViewカメラの作り方を紹介します。 今回の完成映像はこちらになります。
UEFNで俯瞰視点のゲームを作るためにトップダウンカメラを作ってみます。
実装方法
簡単な実装方法は以下の流れになります。
俯瞰カメラを作成し、LevelSequenceでゲーム開始時にそのカメラに切り替わるようにする
Verseで現状動かせるオブジェクトはCreativePropになるので、俯瞰カメラをCreativePropの子供にする
プレイヤーの位置をみて、CreativePropを移動させる
シーン準備
カメラの親となるCreativePropを一つシーン上に配置します。FortniteのPropsの下のものを配置してもいいですが、今回は独自にPropを準備しました。
このページに従い、破壊されない小道具(Indestructible Prop)を作成します。 この際、メッシュは特に使用する必要はないため、空にしておきます。
次に、カメラをシーン上に作成します。
先ほど作成したPropもシーン上に配置し、カメラをPropの子供にします。
カメラの座標値はすべて0に、角度は下向きにしておきます。
次に、LevelSequenceを作成し、先ほど作成したカメラをこのトラックに追加します。
シーン上にCinematic Sequence Deviceを配置します。
- Sequecneに先ほど作成したレベルシーケンスをセット
- LoopPlayback,AutoPlayをONにします。
これで基本準備は完了です。
Verse コード
using { /Fortnite.com/Devices } using { /Verse.org/Simulation } using { /UnrealEngine.com/Temporary/Diagnostics } using { /Fortnite.com/Characters } using { /UnrealEngine.com/Temporary/SpatialMath } # A Verse-authored creative device that can be placed in a level track_player_manager := class(creative_device): @editable _Target : creative_prop = creative_prop{} @editable _OffsetX : float = -3000.0 @editable _OffsetY : float = 0.0 @editable _OffsetZ : float = 3000.0 OnBegin<override>()<suspends>:void= Offset:vector3 = vector3{X:=_OffsetX, Y:=_OffsetY, Z:=_OffsetZ} ## start update loop spawn{UpdateTargetPosition(Offset)} UpdateTargetPosition(Offset:vector3)<suspends>:void= loop: ## get player and player position Players : []player = GetPlayspace().GetPlayers() if(Player : player = Players[0]): if(FortniteCharacter : fort_character = Player.GetFortCharacter[]): PlayerPosition : vector3 = FortniteCharacter.GetTransform().Translation TargetPositionX : float = PlayerPosition.X TargetPositionY : float = PlayerPosition.Y TargetPositionZ : float = PlayerPosition.Z TargetPosition:vector3 = vector3{X:=TargetPositionX, Y:=TargetPositionY, Z:=TargetPositionZ} + Offset ## move target to player position _Target.MoveTo(TargetPosition, IdentityRotation(), 0.5) # Not Good # if(_Target.TeleportTo[TargetPosition, IdentityRotation()]): # void Sleep(0.5) # Not Good # Sleep(0.0)
コード解説していきます。
OnBegin時に位置を更新するための非同期処理を開始しています。 このあたりの処理に関しては、alweiさんが非常に分かりやすく書いてくださっていたので、参考にされるといいと思います。
ここでプレイヤーと、プレイヤーの現在値を取得しています。
Players : []player = GetPlayspace().GetPlayers() if(Player : player = Players[0]): if(FortniteCharacter : fort_character = Player.GetFortCharacter[]): PlayerPosition : vector3 = FortniteCharacter.GetTransform().Translation
その位置にオフセットをつけてpropのMoveTo関数で移動しています。
## move target to player position _Target.MoveTo(TargetPosition, IdentityRotation(), 0.5) # Not Good # if(_Target.TeleportTo[TargetPosition, IdentityRotation()]): # void Sleep(0.5) # Not Good # Sleep(0.0)
TeleportとSleep(0.0)の部分はコメントアウトしていますが、あえて残しています。 当初、これで実装してみたのですが、かなりガタガタしてしまい、あまりいい動きとなりませんでした。 0.5秒間隔でMoveToするくらがちょうどいい塩梅かなと感じています。
ちなみにSleep(0.0)にしたときに、どれくらいレートが出ているのか、計測するためのスクリプトを公開してくれている人がいました。 参考に貼っておきます。
最終シーンセットアップ
ビルドして出来上がったtrack_player_manager をシーン上に配置します。
- _Targetにカメラの親となっているPropをセット
- 適宜オフセットをセット
- Visible in Gameをオフにセット
まとめ
これで実行すれば、サンプルのようなプレイヤーに追従する俯瞰カメラが出来上がります。 問題として、Fortniteはそもそも俯瞰カメラに対応した操作になっていないため、プレイヤーをカメラ前方向に向けておかないと、カメラの向きとプレイヤーの操作が一致せず、非常に操作がやりにくい形になります。この辺りは少しゲーム内で工夫する必要があります。
次の記事で、カメラの向きと操作を一致させるようスクリプトを改修します。
今後もさまざまな情報を発信していきますので、Twitterフォローしていただけると嬉しいです。 twitter.com