UEFN:Verseで敵を作る方法「Dungeonを作るための思考メモ」

UEFN:Verseで敵を作る方法「Dungeonを作るための思考メモ」

UEFN:Verseで敵を作る方法「Dungeonを作るための思考メモ」

ダンジョンモンスターは下記のような無料モンスターで再現可能。

プログラムは下記の動画が参考になる。

しかし、Verseが必要です。

コメント欄からコードを取得できる。これが一番簡単かもしれません。なので、ある程度理解して、導入するこちらの動画で試してみます。

上記の動画で解説しているコードがこちら。

--FIRST SCRIPT PASTED LIKE IN THE VIDEO--
using { /Fortnite.com/AI }
using { /Verse.org/Simulation }
using { /Fortnite.com/Characters }
using { /Fortnite.com/Animation/PlayAnimation }
using { /Verse.org/Assets }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Fortnite.com/Game }
using { /UnrealEngine.com/Temporary/UI }
using { /Verse.org/Colors/NamedColors }
 
# Getting started: https://www.epicgames.com/fortnite/en-US/creative/docs/uefn/Verse/onboarding-guide-to-programming-with-verse-in-unreal-editor-for-fortnite

# A Verse-authored NPC Behavior that can be used within an NPC Character Definition or an NPC Spawner device's NPC Behavior Script Override.



skeleton_npc_behavior := class(npc_behavior):
    BehaviorHelp : BehaviorHelper = BehaviorHelper{}

    var Attack1 : animation_sequence = SkeletonNPC.SkeletonAttackAnimation
    
    NPCDamage : float = 10.0

    # This function runs when the NPC is spawned in the world and ready to follow a behavior.
    OnBegin< override>()< suspends>:void=
        # TODO: Replace this with your code
        if { 
            NPCAgent := GetAgent[]
            NPCChar := NPCAgent.GetFortCharacter[]
            
            #Allows us to tell npcs to go to different place like the pathfinding service in roblox
            NPCNav := NPCChar.GetNavigatable[]

            #Control where npc is looking
            NPCFocus := NPCChar.GetFocusInterface[]

            #Control the npc's animations
            NPCAnim := NPCChar.GetPlayAnimationController[]
        } then {
            NPCSpawnLocation := NPCChar.GetTransform().Translation

            loop {
                Sleep(0.1)
                #Checks if npc is alive
                if (not NPCChar.IsActive[]) {
                    break
                }
                if (NewTarget := BehaviorHelp.FindNearestTargetFromPos[NPCChar], NewAgent := NewTarget.GetAgent[]) {
                    spawn{NPCFocus.MaintainFocus(NewAgent)}
                    NavTarget := MakeNavigationTarget(NewAgent)
                    NPCNav.NavigateTo(NavTarget, ?MovementType := movement_types.Running, ?ReachRadius := 150.0)
                    NPCAnim.Play(Attack1)
                    Sleep(0.58)

                    DistanceDifference := Distance(NPCChar.GetTransform().Translation, NewTarget.GetTransform().Translation)

                    if (DistanceDifference < 200.0) {
                        NewTarget.Damage(NPCDamage)
                    }
                } 
            }
        }

    # This function runs when the NPC is despawned or eliminated from the world.
    OnEnd< override>():void=
        # TODO: Replace this with your code
        Print("Goodbye, NPC!")
------------------------------------------------

--SECOND SCRIPT PASTED IN VIDEO--

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /Fortnite.com/Characters }
using { /UnrealEngine.com/Temporary/SpatialMath }

# See https://dev.epicgames.com/documentation/en-us/uefn/create-your-own-device-in-verse for how to create a verse device.

# A Verse-authored creative device that can be placed in a level
BehaviorHelper := class(creative_device):
    
    FindNearestTargetFromPos(FortChar : fort_character)< decides>< transacts> : fort_character = {
        var MaybeTarget : ?fort_character = false

        #Change this range how you would like
        #This will be the range that the device will search for the nearest target
        var CheckRange : float = 5000.0

        for (Player : GetPlayspace().GetPlayers(), PlayerFortChar := Player.GetFortCharacter[]) {
            DistanceDifference := Distance(FortChar.GetTransform().Translation, PlayerFortChar.GetTransform().Translation)

            if (DistanceDifference < CheckRange and not PlayerFortChar = FortChar) {
                set MaybeTarget = option{PlayerFortChar}
                set CheckRange = DistanceDifference 
            }
        }

        return MaybeTarget?
    }

    # Runs when the device is started in a running game
    OnBegin< override>()< suspends>:void=
        # TODO: Replace this with your code
        Print("Hello, world!")

上記のコードの解説は下記。

この2つのVerseスクリプトは、Unreal Editor for Fortnite (UEFN)を使って、FortniteのクリエイティブモードでAI(敵キャラクター)を制御するためのものです。1つ目のスクリプトはNPCの行動を定義し、2つ目のスクリプトはそのNPCがターゲット(プレイヤー)を見つけるためのヘルパー関数を定義しています。

1つ目のスクリプトの解説

1つ目のスクリプトでは、敵キャラクター(NPC)の動作を制御しています。

主なポイント

  • skeleton_npc_behavior クラス: このクラスは、npc_behavior クラスを継承しており、NPCの行動ロジックを定義しています。
  • BehaviorHelp: BehaviorHelperクラスのインスタンスを持っており、このヘルパークラスを使って、ターゲットの検出などの機能を提供します(2つ目のスクリプトで定義)。
  • Attack1: NPCが再生するアニメーション(攻撃モーション)を定義しています。ここでは、SkeletonNPC.SkeletonAttackAnimationというアニメーションが使用されています。
  • NPCDamage: NPCがプレイヤーに与えるダメージを定義しています(10.0)。

主な機能

  • OnBegin関数:
  • NPCがスポーンされたときに呼び出される初期化関数です。NPCキャラクターの位置を取得し、プレイヤーをターゲットにします。
  • NPCのナビゲーション(移動)やフォーカス(ターゲットの追尾)、アニメーションを管理するためのインターフェースを取得しています。
  • 無限ループ(loop)内で、NPCがまだ生存しているかを確認し、最も近いターゲット(プレイヤー)に向かって移動します。
  • ターゲットに接近すると、攻撃アニメーションを再生し、プレイヤーにダメージを与えます。
  • OnEnd関数:
  • NPCが削除される(デスポーンや倒される)ときに呼び出され、シンプルに「Goodbye, NPC!」とコンソールに表示します。

動作の流れ

  1. NPCがスポーンすると、OnBegin関数が呼び出されます。
  2. NPCは、近くのターゲットを検出し、そのターゲットに向かって移動します。
  3. ターゲットに十分接近したら、攻撃アニメーションを再生し、ターゲットにダメージを与えます。
  4. NPCが倒されると、OnEnd関数が実行されて終了します。

2つ目のスクリプトの解説

2つ目のスクリプトは、BehaviorHelper クラスを定義し、NPCがターゲットを探す際のヘルパー関数を提供しています。

主なポイント

  • BehaviorHelper クラス: クリエイティブモードのデバイスとして動作し、ゲーム内で使うことができます。NPCの行動を補助するためのクラスです。
  • FindNearestTargetFromPos 関数:
  • NPCの周囲にいるプレイヤーを検出し、その中で最も近いターゲットを選択します。
  • NPCの位置とプレイヤーの位置を比較し、指定された範囲内(この場合5000.0の範囲)の最も近いプレイヤーを見つけます。
  • 見つかったプレイヤーの位置をNPCに返します。
  • OnBegin 関数:
  • デバイスがゲームでスタートすると呼ばれます。
  • Print("Hello, world!")とコンソールに表示して、動作確認をしています。

結論

この2つのスクリプトは連携して動作します。skeleton_npc_behavior スクリプトはNPCの基本的な行動(移動や攻撃)を定義し、BehaviorHelper スクリプトはターゲットを探すロジックを提供します。この仕組みにより、Fortniteのクリエイティブモードで動くシンプルなAI敵キャラクターを作成できます。

このコードを使えば、プレイヤーに向かって移動し、攻撃する敵を簡単に生成できるようになります。

以下は、1つ目のスクリプトに対する詳細な解説をコード内に追加したものです。各ステップで何をしているのか理解できるように、詳細なコメントを挿入しています。

1つ目のスクリプト(敵NPCの行動)

# 必要なライブラリをインポート
using { /Fortnite.com/AI }
using { /Verse.org/Simulation }
using { /Fortnite.com/Characters }
using { /Fortnite.com/Animation/PlayAnimation }
using { /Verse.org/Assets }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Fortnite.com/Game }
using { /UnrealEngine.com/Temporary/UI }
using { /Verse.org/Colors/NamedColors }

# NPCのカスタム行動クラスを定義。`npc_behavior`をベースにしています。
skeleton_npc_behavior := class(npc_behavior):
    # NPCの行動をサポートするためのヘルパーを定義
    BehaviorHelp : BehaviorHelper = BehaviorHelper{}

    # 攻撃時に再生するアニメーションシーケンスを定義。ここでは、スケルトンの攻撃アニメーションを指定。
    var Attack1 : animation_sequence = SkeletonNPC.SkeletonAttackAnimation

    # NPCがプレイヤーに与えるダメージ量を定義
    NPCDamage : float = 10.0

    # NPCがスポーンして行動を開始するときに呼ばれる関数(開始時のセットアップ)
    OnBegin< override>()< suspends>:void= 
        # NPCが正しくセットアップできたかどうかを確認
        if { 
            # NPCエージェントのインスタンスを取得(ゲーム内のNPCキャラクター)
            NPCAgent := GetAgent[]

            # エージェントからフォートナイトキャラクターのインスタンスを取得(実際のキャラクターを管理)
            NPCChar := NPCAgent.GetFortCharacter[]

            # NPCのナビゲーションシステム(移動制御)を取得。これでNPCがどこに移動するかを指示できる
            NPCNav := NPCChar.GetNavigatable[]

            # NPCのフォーカスシステム(視線・ターゲット)を取得。NPCが誰に向かっているかを制御
            NPCFocus := NPCChar.GetFocusInterface[]

            # NPCのアニメーションコントローラーを取得。これでNPCのアニメーションを再生できる
            NPCAnim := NPCChar.GetPlayAnimationController[]
        } then {
            # NPCがスポーンしたときの位置を取得
            NPCSpawnLocation := NPCChar.GetTransform().Translation

            # 行動ループを開始(無限ループ)。NPCの動作を継続的にチェック。
            loop {
                # 0.1秒の待機。これで毎フレームではなく少し間隔を置いて処理を実行する
                Sleep(0.1)

                # NPCが生きているか確認(アクティブかどうか)。死んでいる場合はループを終了
                if (not NPCChar.IsActive[]) {
                    break
                }

                # NPCがターゲットを見つけたか確認。最も近いターゲット(プレイヤー)を取得
                if (NewTarget := BehaviorHelp.FindNearestTargetFromPos[NPCChar], NewAgent := NewTarget.GetAgent[]) {
                    # ターゲットが見つかった場合、そのターゲットをフォーカス
                    spawn{NPCFocus.MaintainFocus(NewAgent)}

                    # ターゲットへのナビゲーションを設定し、NPCがターゲットに向かって移動するようにする
                    NavTarget := MakeNavigationTarget(NewAgent)

                    # NPCをターゲットに向かって走らせる。到達範囲は150.0ユニット
                    NPCNav.NavigateTo(NavTarget, ?MovementType := movement_types.Running, ?ReachRadius := 150.0)

                    # 攻撃アニメーションを再生(`Attack1`で定義されたアニメーション)
                    NPCAnim.Play(Attack1)

                    # アニメーションの再生が終わるまで少し待機(0.58秒)
                    Sleep(0.58)

                    # NPCとターゲットの距離を計算。これでNPCがターゲットにどれだけ近いかを判断
                    DistanceDifference := Distance(NPCChar.GetTransform().Translation, NewTarget.GetTransform().Translation)

                    # 距離が200.0未満(NPCがターゲットに十分近づいた場合)、ターゲットにダメージを与える
                    if (DistanceDifference < 200.0) {
                        NewTarget.Damage(NPCDamage)
                    }
                } 
            }
        }

    # NPCがデスポーンまたは倒されたときに呼ばれる関数(終了時の処理)
    OnEnd< override>():void=
        # NPCが消えたことを知らせるメッセージを表示
        Print("Goodbye, NPC!")

詳細な説明

  • BehaviorHelper: BehaviorHelpは、ターゲット(プレイヤー)を探すために2つ目のスクリプトで定義されるヘルパー関数を使用します。
  • Attack1: NPCが攻撃するときに再生するアニメーション。SkeletonAttackAnimationという名前のアニメーションシーケンスを指定。
  • NPCDamage: NPCが攻撃する際に与えるダメージ量。このスクリプトでは10ダメージが設定されています。
  • OnBegin関数:
  • NPCがスポーンしたときに呼び出され、キャラクターやナビゲーション、フォーカス、アニメーションのコントローラーを設定します。
  • 無限ループ内でNPCがターゲットを探し、ターゲットに向かって移動し、近づいたら攻撃を仕掛けるという流れ。
  • NPCがターゲット(プレイヤー)に接近すると、攻撃アニメーションを再生し、一定距離(200.0未満)に達したらプレイヤーにダメージを与えます。
  • OnEnd関数:
  • NPCが削除される(デスポーンまたは倒された)ときに呼ばれ、「Goodbye, NPC!」というメッセージがコンソールに表示されます。

2つ目のスクリプト(ターゲット探しのヘルパー)

# 必要なライブラリをインポート
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /Fortnite.com/Characters }
using { /UnrealEngine.com/Temporary/SpatialMath }

# ターゲット探索用のヘルパークラスを定義。`creative_device`から継承されています。
BehaviorHelper := class(creative_device):

    # NPCの周囲で最も近いプレイヤーキャラクターを探す関数
    FindNearestTargetFromPos(FortChar : fort_character)< decides>< transacts> : fort_character = {
        var MaybeTarget : ?fort_character = false  # 最も近いターゲット候補を保持

        # 探索する範囲(5000.0ユニット)。この範囲内のプレイヤーをチェックします。
        var CheckRange : float = 5000.0

        # 現在のプレイスペース内のすべてのプレイヤーを取得し、ループ処理
        for (Player : GetPlayspace().GetPlayers(), PlayerFortChar := Player.GetFortCharacter[]) {
            # NPCとプレイヤーの距離を計算
            DistanceDifference := Distance(FortChar.GetTransform().Translation, PlayerFortChar.GetTransform().Translation)

            # 計算された距離がチェック範囲内であり、かつNPC自身ではない場合、ターゲットとして設定
            if (DistanceDifference < CheckRange and not PlayerFortChar = FortChar) {
                set MaybeTarget = option{PlayerFortChar}  # 最も近いターゲットを更新
                set CheckRange = DistanceDifference  # 範囲を更新(次にもっと近いターゲットを見つけるため)
            }
        }

        # 最も近いターゲットを返す
        return MaybeTarget?
    }

    # デバイスがゲーム内で開始されるときに呼ばれる関数
    OnBegin< override>()< suspends>:void=
        # 起動メッセージをコンソールに表示
        Print("Hello, world!")

詳細な説明

  • BehaviorHelper: このクラスは、NPCが近くのターゲット(プレイヤー)を探すためのヘルパークラスです。
  • FindNearestTargetFromPos関数: NPCの位置

から最も近いプレイヤーキャラクターを探し、そのプレイヤーのキャラクターを返します。

  • CheckRange(5000.0ユニット)内にいるプレイヤーを全員チェックし、最も近いプレイヤーを選びます。
  • OnBegin関数: ゲーム開始時に呼ばれ、「Hello, world!」というメッセージを表示してデバイスが動作していることを確認できます。

これらのスクリプトにより、Fortniteのクリエイティブモード内で、NPCが自動的にプレイヤーを検出し、攻撃する行動を実現することができます。

上記の方法でわからない場合には下記の方法を試しましょう

1時間位長いけど、コードがコピーできる。

ディスコードからコードを持ってくる方法

ディスコードからコードを持ってくる方法

上記のどれかで実装できます。

スライム

下記にも似たような内容を貼り付けておきます。

下記のスライムを参考にして作れます。

アニメーション(アイドル、攻撃、移動)を自作すれば問題なし。

https://sketchfab.com/3d-models/slime-variant-2-f7f9baaefe494705a3d59d3a27937dbe

ブレンダーで似たようなものが作れます。

有料だが、このようなアセットもあります。

https://www.unrealengine.com/marketplace/en-US/product/lilblob-the-slime
てんすらが作れそう

フィールドは超特大があったのでこちらを活用すれば誇大なフィールドを実現可能です。