【UEFN】フォートナイトで攻撃魔法を作る (Verseの学習⑤)

フォートナイトにNiagaraで独自の攻撃魔法を作る

フォートナイトで俯瞰視点のクリエイティブマップを作っています。ただ、俯瞰視点では通常のエイムが必要な銃器による攻撃がまともにできません。 剣だけで戦うのはゲーム性が低いため、なんらか別の攻撃手段を実装する必要があります。

そこで、俯瞰視点でも使用できる攻撃魔法を作ることにしました。

今回の完成映像はこちらになります。

実装方法

以下の方法で実装していきます。

  • 視覚効果にはNiagaraの機能を使用
  • NiagaraとDamageVolumeDeviceを連動させることで、Creatureにダメージを与える

Niagaraを動作させる方法は、現状のUEFNだと以下の2つの選択かと思います。

  1. VFXSpawnerで自作したNiagaraのエフェクトを制御する
  2. LevelSequenceで自作したNiagaraのエフェクトを制御する

今回は、Niagaraによるエフェクト効果、発動した時の効果音、DamageVolumeの大きさ、照り返しの光の照明、などをまとめて制御する必要があるため、2のLevelSequenceの方式を使用することにしました。

Niagaraでエフェクトを作る

NiagaraはUnrealEngine4.20からベータテストが始まり、4.26で正式版となった、UnrealEngineとしては比較的新しいエフェクト機能になります。

そもそも、UEFNにはUnrealEngineと違い、Blueprintのノード機能が現状ないため、(おそらく将来的にはVerseがそこを担っていく?)、Niagaraの制御方法が乏しいのですが、Niagara単品での機能は、UnrealEngineと同様に使用することができます。

Niagaraを使ったShockWaveの作り方は、以下の動画が一例として非常に参考になります。

youtu.be

上記の動画に従って作成していただければ、UEFNでも同じエフェクトを作成することができます。

注意点として、UEFNでは、UnrealEngineでサンプル的に入っている素材が入っていません。

上記の動画で使用している、M_smoke_sub_uvというマテリアルはUEFNには存在せず、UnrealEngineにのみ存在しています。

UnrealEngine 5.1.1をダウンロードしていき、UnrealEngine 5.1.1からコピーしていただくのがいいかと思います。

やり方は、まず、UnrealEngineでプロジェクトを作成します。この際、スターターコンテンツをオンにしてください。

スターターコンテンツをオンにしてプロジェクトを作成してください

作成したプロジェクトのなかで、StarterContentの中にあるM_smoke_sub_UVを探して、移行(migrate)します。

このマテリアルを移行(migrate)してやります

マテリアルの作り方、Niagaraの作り方などは、UnrealEngineを基準にしたものが非常に多く情報があり、UEFNでもほぼ同様の手法が使えるため、UnrealEngineをインストールしておくのはUEFNで開発を行う上でも有益かと思います。

Material Functionというマテリアル周りの機能もUEFNでは標準で入っていないので、それらもUnrealEngineから持ってくることも可能です。

素材の移行(migrate)の仕方の詳細は、以下のドキュメントを参考にしてください。

docs.unrealengine.com

Migrate先の指定は、UEFNでは必ず以下の場所になります。

  • (プロジェクトディレクトリへのパス)\Plugins\(プロジェクト名)\Content

シーンへの配置

出来上がったNiagaraエフェクトと必要な素材をシーン上に配置していきます。

(※自分は上記の動画とは別に準備したNiagaraエフェクトを使用しています)

Outlinerの構成

  • ROOT_SHOCK_WAVE
    • Creative_propです。全体を移動させるために使用しします。
  • CSD_ShockWave
    • Cinematic Sequencer Device です。シーケンスを再生させるために使用(移動させる必要は特にないが、管理のためここに配置)
  • DVD_ShockWave
    • Damage Volume Device
  • NS Shockwave
  • PointLight
    • 照り返し用にライトを追加

シーケンサーの追加

エフェクト制御のためのシーケンサーを一つ作成して、タイムラインを以下のように構築します。

シーケンサー構成

Niagaraシーケンサーで同期させるためには、ComponentにNiagara System Life Cycle Trackを追加する必要があります。

やり方はShiotaniさんのブログで詳細に書かれているため以下を参考にしてください。

saltcanyon.hatenablog.com

DamageVolumeDeviceの大きさ、PointLightの強さに対してキーフレームをうち、音声を追加して、以下のようにしました。

タイムラインの動作

出来上がったシーケンサーを、Cinematic Sequence Device で動作するように設定します。

CSD_ShockWaveの設定

Verseでの作業

今回はコードの抜粋です。

基本的に実施するのは、

  • なんらかのトリガー(自分の場合はしゃがみ動作)で、 ROOT_SHOCK_WAVEをプレイヤーの位置に移動
  • 必要なデバイスをEnableに
  • シーケンサーの再生
  • 終了処理

ということになります。

しゃがみ動作にたいする登録作業はこのような感じです。

        # add skill event 
        Players : []player = GetPlayspace().GetPlayers()
        if(Player : player = Players[0]):
            if(FortniteCharacter : fort_character = Player.GetFortCharacter[]):
                FortniteCharacter.CrouchedEvent().Subscribe(OnPlayerCrouched)
    OnPlayerCrouched(the_player:fort_character, IsCrounch: logic):true= 
        if(IsCrounch?):
            Players : []player = GetPlayspace().GetPlayers()
            if(Player : player = Players[0]):
                if(FortniteCharacter : fort_character = Player.GetFortCharacter[]):
                    PlayerPosition : vector3 = FortniteCharacter.GetTransform().Translation

                    ## taqrget position
                    TargetPositionX : float = PlayerPosition.X
                    TargetPositionY : float = PlayerPosition.Y
                    TargetPositionZ : float = PlayerPosition.Z

                    TargetPosition:vector3 = vector3{X:=TargetPositionX, Y:=TargetPositionY, Z:=TargetPositionZ}
                    _SkillController.CastSkill(TargetPosition, _BaseCameraSequence)

今まで書いてきたコードとほぼ同じ形なので、特に難しい部分はありません。

スキル発動部分はこのような感じにしました。

    ### process for crouched
    CastSkill<public>(TargetPosition : vector3, BaseCameraSequence : cinematic_sequence_device) : void=
        ### teleport and cast skill
        if(_SkillRoot.TeleportTo[TargetPosition, IdentityRotation()]):
            spawn{CastSkill(BaseCameraSequence)}
    
    CastSkill(BaseCameraSequence : cinematic_sequence_device)<suspends> : void = 
        BaseCameraSequence.Stop()
        _SkillSequence.Play()
        ## start scale
        Sleep(0.0)
        _SkillDamageVolume.Enable()

        ## wait for anim end
        Sleep(_SkillTimeOffset)
        
        ## disable volume
        _SkillDamageVolume.Disable()
        
        ## stop camera and recover
        _SkillSequence.Stop()
        BaseCameraSequence.Play()
  • _SkillRootには、ROOT_SHOCK_WAVEをセットしています。
  • _SkillSequenceには、CSD_ShockWaveをセットしています。

スキル用のDeviceとプレイヤー制御のDeviceは分けて作っています。

スキル発動時はカメラなども別にする可能性があるため、カメラ制御用のシーケンスを別途、関数に渡しており、スキル発動後にもとに戻しています。

今回のサンプルはシンプルにするために、Sleepで処理を終わらせていますが、CinematicSequencerDeviceは終了時のEventがあるため、これで終了してやる方がいいかもしれません。

まとめ

完成したものはこのような形です。

このままでは強すぎるので、使用回数など制限を与えることで、ゲームとしておもしろくなりそうです。

今回は、Verseで作成したDeviceの使い方の詳細までは載せていません。

前回までの記事をみていただければ、この辺りは同じですのでわかるのではないかと思います。

少し無理やり作っている部分もありますが、現状のUEFNで出来る形はこのようなものではないかなぁと考えています。

もし、もっといいやり方を考案された方がいらっしゃれば、ぜひ教えていただけるとうれしいです。

この記事が参考になれば幸いです。

UEFN、超楽しい:)

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