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!」とコンソールに表示します。
動作の流れ
- NPCがスポーンすると、
OnBegin
関数が呼び出されます。 - NPCは、近くのターゲットを検出し、そのターゲットに向かって移動します。
- ターゲットに十分接近したら、攻撃アニメーションを再生し、ターゲットにダメージを与えます。
- 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時間位長いけど、コードがコピーできる。
ディスコードからコードを持ってくる方法
ディスコードからコードを持ってくる方法
上記のどれかで実装できます。
スライム
下記にも似たような内容を貼り付けておきます。
下記のスライムを参考にして作れます。
アニメーション(アイドル、攻撃、移動)を自作すれば問題なし。
ブレンダーで似たようなものが作れます。
有料だが、このようなアセットもあります。
フィールドは超特大があったのでこちらを活用すれば誇大なフィールドを実現可能です。