【UEFN】 DiabloライクのTop-DownViewカメラを作る Part.1(Verseの学習③)

DiabloライクのTop-DownViewカメラを作る

Twitterでサンプルを公開したところ、反響が多かったため、Top-DownViewカメラの作り方を紹介します。 今回の完成映像はこちらになります。

DiabloLikeCamera

UEFNで俯瞰視点のゲームを作るためにトップダウンカメラを作ってみます。

実装方法

簡単な実装方法は以下の流れになります。

  1. 俯瞰カメラを作成し、LevelSequenceでゲーム開始時にそのカメラに切り替わるようにする

  2. Verseで現状動かせるオブジェクトはCreativePropになるので、俯瞰カメラをCreativePropの子供にする

  3. プレイヤーの位置をみて、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さんが非常に分かりやすく書いてくださっていたので、参考にされるといいと思います。

unrealengine.hatenablog.com

ここでプレイヤーと、プレイヤーの現在値を取得しています。

            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)にしたときに、どれくらいレートが出ているのか、計測するためのスクリプトを公開してくれている人がいました。 参考に貼っておきます。

dev.epicgames.com

最終シーンセットアップ

ビルドして出来上がったtrack_player_manager をシーン上に配置します。

  • _Targetにカメラの親となっているPropをセット
  • 適宜オフセットをセット
  • Visible in Gameをオフにセット

まとめ

これで実行すれば、サンプルのようなプレイヤーに追従する俯瞰カメラが出来上がります。 問題として、Fortniteはそもそも俯瞰カメラに対応した操作になっていないため、プレイヤーをカメラ前方向に向けておかないと、カメラの向きとプレイヤーの操作が一致せず、非常に操作がやりにくい形になります。この辺りは少しゲーム内で工夫する必要があります。

次の記事で、カメラの向きと操作を一致させるようスクリプトを改修します。

ringogames.hatenablog.com

今後もさまざまな情報を発信していきますので、Twitterフォローしていただけると嬉しいです。 twitter.com