はじめに
NPCのコンポーネント検証シリーズ、今回は npc_awareness_component について調べました。
このコンポーネントは、NPCの「知覚(視覚・聴覚・触覚)」を司る中枢です。ターゲットを検知した瞬間や、見失った瞬間のイベントをフックにすることで、NPCのAI挙動をVerseから細かく制御できるようになります。
今回は、主要なプロパティと5つのイベントについて検証しました。
✅ DetectedTargets(検知済みターゲットのリスト)
✅ DetectTargetEvent(ターゲット検知イベント)
✅ ForgetTargetEvent(ターゲットを忘れるイベント)
✅ SeeTargetEvent(視覚検知イベント)
✅ HearTargetEvent(聴覚検知イベント)
✅ TouchTargetEvent(触覚検知イベント)
※本記事の内容は筆者の実験結果に基づく推測を含みます。今後のアップデートで挙動が変わる可能性がありますのでご注意ください。
環境:
UEFN: v39.10(UE 5.8)
npc_awareness_component とは
v39.00 のリリース ノート で追加された、NPCの知覚(Perception)を一括管理するためのコンポーネントです。
ターゲットを「見つけた」「聞いた」「触れた」といった情報をイベントとして受け取れます。
API定義(npc_awareness_component)
@available {MinUploadedAtFNVersion := 3900}
# Fortnite NPC perception management
npc_awareness_component<native><public> := class<final_super><epic_internal>(component):
# Information about all detected targets.
var<private> DetectedTargets<native><public>:[]npc_target_info = external {}
# Event when a target was detected.
DetectTargetEvent<native><public>:listenable(npc_target_info) = external {}
# Event when a target was forgotten.
ForgetTargetEvent<native><public>:listenable(entity) = external {}
# Event when a target is seen. Sight sense must be active.
SeeTargetEvent<native><public>:listenable(npc_target_info) = external {}
# Event when a target is heard. Hearing sense must be active.
HearTargetEvent<native><public>:listenable(npc_target_info) = external {}
# Event when a target is touched. Touch sense must be active.
TouchTargetEvent<native><public>:listenable(npc_target_info) = external {}
1. DetectedTargets
# Information about all detected targets.
var<private> DetectedTargets<native><public>:[]npc_target_info = external {}
# 検知されたすべてのターゲットに関する情報。
-
検証結果:
- DetectTargetEvent 発生後、DetectedTargets に追加されます
- ForgetEvent 発生後、DetectedTargets から取り除かれます
- 挙動の注意点: ゲーム開始時、DetectTargetEvent 発生前であってもすでにターゲットが含まれているケースがあり、初期状態のハンドリングに注意が必要です
2. DetectTargetEvent
# Event when a target was detected.
DetectTargetEvent<native><public>:listenable(npc_target_info) = external {}
# ターゲットが検知されたときのイベント。
動画は、DetectTargetEvent と ForgetTargetEvent を確認しています
- 始めは、NPCとプレイヤーは同じチームです
検知対象が Enemies のため、プレイヤーは攻撃されません - プレイヤーがボリュームに入ったとき、NPCを別チームに変更しています
DetectTargetEvent が発生し、NPCはプレイヤーへの攻撃を開始します - プレイヤーが再度ボリュームに入ったとき、NPCをプレイヤーと同じチームに戻しています
ForgetTargetEvent が発生します
-
検証結果:
- 視覚、聴覚、触覚 のいずれかでターゲットを検知し、それが DetectedTargets に存在しない場合、発生します
- 検知対象は、NPCキャラクター定義の
Perception ModifierまたはGuard Perception Modifier内のDetection by Affiliation設定に依存すると考えられます-
Detect Enemies(デフォルト)
-
Detect Neutrals
-
Detect Friendlies
既知の不具合 (2025年12月時点)
現在、Enemies 以外を検知対象に設定すると DetectTargetEvent が発生しない不具合が報告されています。 (公式フォーラム参照)
-
検証用コード
# プレイヤーが Volume に入ったときに、
# NPCの所属チームを変更する。味方なら敵に、敵なら味方チームに。
OnVolumeEnters(Agent:agent):void=
Print("OnVolumeEnters: ")
if(SimE := GetSimulationEntity[]):
NPCAwarenessComps := for(Comp : SimE.FindDescendantComponents(npc_awareness_component)){Comp}
if(NPCAwarenessComp := NPCAwarenessComps[0]):
if:
NPCAgent := GetAgentFromEntity[NPCAwarenessComp.Entity]
TC := GetPlayspace().GetTeamCollection()
TeamAttitude := TC.ToggleTeamAttitude[NPCAgent, Agent]
then:
Print(" - Toggled TeamAttitude: " + ToDiagnostic(TeamAttitude))
else:
Print(" - Error: Could not toggle team attitude.")
# ターゲットを検知したときの処理。検知したターゲット情報を出力。
OnDetectTarget(TargetInfo:npc_target_info):void=
Print("OnDetectTarget: " + ToDiagnostic(TargetInfo))
Print(" - TargetInfo.Target: " + ToDiagnostic(TargetInfo.Target))
Print(" - TargetInfo.HasLineOfSight: " + ToDiagnostic(TargetInfo.HasLineOfSight))
Print(" - TargetInfo.Attitude: " + ToDiagnostic(TargetInfo.Attitude))
Print(" - TargetInfo.LastKnownPosition: " + ToDiagnostic(TargetInfo.LastKnownPosition))
# NPCに検知されている、すべてのターゲット情報を出力
DetectedTargets_Test():void=
Print("========== DetectedTargets_Test ==========")
if(SimE := GetSimulationEntity[]):
NPCAwarenessComps := for(Comp : SimE.FindDescendantComponents(npc_awareness_component)){Comp}
if(NPCAwarenessComp := NPCAwarenessComps[0]):
DetectedTargets:[]npc_target_info = NPCAwarenessComp.DetectedTargets
Print(" - DetectedTargets.Length: {DetectedTargets.Length}")
for(I -> TargetInfo : DetectedTargets):
Print(" - DetectedTargets[{I}]: Target: " + ToDiagnostic(TargetInfo.Target))
Print(" - DetectedTargets[{I}]: HasLineOfSight: " + ToDiagnostic(TargetInfo.HasLineOfSight))
Print(" - DetectedTargets[{I}]: Attitude: " + ToDiagnostic(TargetInfo.Attitude))
Print(" - DetectedTargets[{I}]: LastKnownPosition: " + ToDiagnostic(TargetInfo.LastKnownPosition))
Print("===============================================")
========== DetectedTargets_Test ==========
- DetectedTargets.Length: 0
===============================================
OnVolumeEnters:
- Toggled TeamAttitude: (/Fortnite.com/Teams:)team_attitude.Hostile
OnDetectTarget: AI_npc_target_info /VKEdit/Maps/VKEdit_EmptyOcean_VolumeSupport.VKEdit_EmptyOcean_VolumeSupport:PersistentLevel.VKEdit_EmptyOcean_VolumeSupport_SimulationEntityActor.SimulationEntity.RoundLifetimeSimulationEntity.Henchman_Prefab_Entity_C_2147482640.AI_fort_guard_perception_component_0.AI_npc_target_info_2147482638
- TargetInfo.Target: Entity /VKEdit/Maps/VKEdit_EmptyOcean_VolumeSupport.VKEdit_EmptyOcean_VolumeSupport:PersistentLevel.VKEdit_EmptyOcean_VolumeSupport_SimulationEntityActor.SimulationEntity.RoundLifetimeSimulationEntity.PlayerPawn_Athena_C_2147482637
- TargetInfo.HasLineOfSight: true
- TargetInfo.Attitude: (/Fortnite.com/Teams:)team_attitude.Hostile
- TargetInfo.LastKnownPosition: (/Verse.org/SpatialMath:)vector3{Forward := -370.63969596999425, Left := 8802.510502376554, Up := 77.15099384415615}
OnVolumeEnters:
- Toggled TeamAttitude: (/Fortnite.com/Teams:)team_attitude.Friendly
OnForgetTarget: TargetEntity: Entity /VKEdit/Maps/VKEdit_EmptyOcean_VolumeSupport.VKEdit_EmptyOcean_VolumeSupport:PersistentLevel.VKEdit_EmptyOcean_VolumeSupport_SimulationEntityActor.SimulationEntity.RoundLifetimeSimulationEntity.PlayerPawn_Athena_C_2147482637
OnDetectTarget: AI_npc_target_info /VKEdit/Maps/VKEdit_EmptyOcean_VolumeSupport.VKEdit_EmptyOcean_VolumeSupport:PersistentLevel.VKEdit_EmptyOcean_VolumeSupport_SimulationEntityActor.SimulationEntity.RoundLifetimeSimulationEntity.Henchman_Prefab_Entity_C_2147482640.AI_fort_guard_perception_component_0.AI_npc_target_info_2147482637
- TargetInfo.Target: Entity /VKEdit/Maps/VKEdit_EmptyOcean_VolumeSupport.VKEdit_EmptyOcean_VolumeSupport:PersistentLevel.VKEdit_EmptyOcean_VolumeSupport_SimulationEntityActor.SimulationEntity.RoundLifetimeSimulationEntity.PlayerPawn_Athena_C_2147482637
- TargetInfo.HasLineOfSight: true
- TargetInfo.Attitude: (/Fortnite.com/Teams:)team_attitude.Friendly
- TargetInfo.LastKnownPosition: (/Verse.org/SpatialMath:)vector3{Forward := -242.2152475088556, Left := 8769.469720987045, Up := 77.14999645587599}
OnForgetTarget: TargetEntity: Entity /VKEdit/Maps/VKEdit_EmptyOcean_VolumeSupport.VKEdit_EmptyOcean_VolumeSupport:PersistentLevel.VKEdit_EmptyOcean_VolumeSupport_SimulationEntityActor.SimulationEntity.RoundLifetimeSimulationEntity.PlayerPawn_Athena_C_2147482637
3. ForgetTargetEvent
# Event when a target was forgotten.
ForgetTargetEvent<native><public>:listenable(entity) = external {}
# ターゲットが忘れられたときのイベント。
-
検証結果:
- ターゲットが忘れられたときに発生します
DetectTargetEvent 発生以降に、以下のケースなどで発生します- NPCがターゲットを撃破した
- 障害物などでターゲットを見失った
- チーム変更により検知対象外(敵から味方へなど)になった
- ターゲットが忘れられたときに発生します
4. SeeTargetEvent
# Event when a target is seen. Sight sense must be active.
SeeTargetEvent<native><public>:listenable(npc_target_info) = external {}
# ターゲットが視認されたときのイベント。視覚センスがアクティブである必要があります。
-
検証結果:
- NPCキャラクター定義で設定の検知対象が見えたときに発生します
検証用コード・設定
NPCを敵チームにしてから検証開始
OnSeeTarget(TargetInfo:npc_target_info):void=
Print("OnSeeTarget: TargetInfo: " + ToDiagnostic(TargetInfo))
Print(" - TargetInfo.Target: " + ToDiagnostic(TargetInfo.Target))
Print(" - TargetInfo.HasLineOfSight: " + ToDiagnostic(TargetInfo.HasLineOfSight))
Print(" - TargetInfo.Attitude: " + ToDiagnostic(TargetInfo.Attitude))
Print(" - TargetInfo.LastKnownPosition: " + ToDiagnostic(TargetInfo.LastKnownPosition))
5. HearTargetEvent
# Event when a target is heard. Hearing sense must be active.
HearTargetEvent<native><public>:listenable(npc_target_info) = external {}
# ターゲットが聞こえたときのイベント。聴覚センスがアクティブである必要があります。
-
検証結果:
- NPCキャラクター定義で設定の検知対象が聞こえたときに発生します。1度発生するときは、立て続けに発生します
- イベント発生後、必ずしもプレイヤーへの攻撃を開始しません。立っている位置から動かないことのほうが多いです
検証用コード・設定
NPCを敵チームにしてから検証開始
# 頻繁に発生するのでログ出力は少量
OnHearTarget(TargetInfo:npc_target_info):void=
Print("OnHearTarget: " )
6. TouchTargetEvent
# Event when a target is touched. Touch sense must be active.
TouchTargetEvent<native><public>:listenable(npc_target_info) = external {}
# ターゲットに触れたときのイベント。触覚センスがアクティブである必要があります。
-
検証結果:
- NPCキャラクター定義で設定の検知対象に触れたとき、発生します
-
設定の注意点: デフォルトでは検知しませんでした。NPCキャラクター定義の
Override Touch Settingsをオンにし、Enable Touchを明示的に有効にすることで動作するようになります
検証用コード・設定
OnTouchTarget(TargetInfo:npc_target_info):void=
Print("OnTouchTarget: called. TargetInfo: " + ToDiagnostic(TargetInfo))
Print(" - TargetInfo.Target: " + ToDiagnostic(TargetInfo.Target))
Print(" - TargetInfo.HasLineOfSight: " + ToDiagnostic(TargetInfo.HasLineOfSight))
Print(" - TargetInfo.Attitude: " + ToDiagnostic(TargetInfo.Attitude))
Print(" - TargetInfo.LastKnownPosition: " + ToDiagnostic(TargetInfo.LastKnownPosition))
おわりに
今回の検証で、NPCが「世界をどう認識しているか」をVerseで取れるようになりました。
これら知覚のイベントは、前回検証した guard_actions_component によるアクションと組み合わせることで、NPCを自在に動かすための手がかりになります。
関連記事




