【UEFN】 撃破した/されたプレイヤーのagentをVerseで取得してみる

## 背景
`fort_character`インターフェースにある``EliminatedEvent``を利用すればこれは必要なさそうですが複数人のプレイヤーやクリーチャーの撃破イベントを一括にとるとなると少しコード量が増えてしまいそうだと考えていました。そこで出会ったのが``撃破マネージャー``になります。

## やること
プレイヤーが撃破する、されたイベントを購読してみる。

### 動画
<iframe width="560" height="315" src="https://www.youtube.com/embed/nBJktOJE-3w?si=QFeqWcer18URPaWk" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

## 実装

### 利用するDevice
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692976/119b2a38-d398-93d7-66fd-4696ee13fbd9.png)
配置するだけで設定を変えることはしませんでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692976/d4be748c-9650-e191-59df-5868b32fe83c.png)

撃破したときに好きなアイテムをドロップできるように設定しそのアイテムについての設定ができるような感じでした。


### 全体コード
```
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }

elimination_manager_controller_device := class(creative_device):

    @editable
    EliminationManager:elimination_manager_device = elimination_manager_device{}

    OnBegin<override>()<suspends>:void=
        # 撃破されたプレイヤーのagentを取得できる
        EliminationManager.EliminatedEvent.Subscribe(OnEliminated)
        # 撃破したプレイヤーのagentを取得できる
        EliminationManager.EliminationEvent.Subscribe(OnElimination)

    OnEliminated(Agent : agent):void=
        Print("Eliminated")

    OnElimination(QAgent : ?agent):void=
        if (Agent := QAgent?):
            Print("Elimination")
        else:
            Print("Elimination by environment")
```

elimination_manager_device自体が
- EliminatedEvent
- EliminationEvent
の二つの``listenable``だけしか(※語弊あり)用意していないのでそれらを使ってみました。

これらのイベントはプレイヤー以外にもクリーチャーの撃破関連も取得できるようになっています。

### ``elimination_manager_device``の中身を見てみる

```
# Used to spawn items when an `agent` or specified target is eliminated.
    elimination_manager_device<public> := class<concrete><final>(base_item_spawner_device):
        # Signaled when a qualifying elimination occurs.
        # Sends the eliminated `agent`.
        EliminatedEvent<public>:listenable(agent) = external {}

        # Signaled when a qualifying elimination occurs.
        # Sends the eliminator `agent`. If the eliminator is a non-agent then `false` is returned.
        EliminationEvent<public>:listenable(?agent) = external {}
```
撃破マネージャーは``base_item_spawner_device``を継承していたのでアイテムのスポーンイベントも購読できるようになっています。
```
# Base class for devices that spawn items.
    base_item_spawner_device<public> := class<abstract><epic_internal>(creative_device_base):
        # Signaled when an `agent` picks up the spawned item.
        # Sends the `agent` that picked up the item.
        ItemPickedUpEvent<public>:listenable(agent) = external {}

        # Enables this device.
        Enable<public>():void = external {}

        # Disables this device.
        Disable<public>():void = external {}
```
これは撃破マネージャーの設定で撃破した後にアイテムをスポーンさせる設定ができるのでそのイベントの操作ができるようになっているから継承されているみたいです。

## まとめ
``fort_character``から一回一回確認してイベント購読の開始はなかなか実装の難易度やコードの複雑性が増しそうだったのでとても良いものだと思いました。

## 余談
この度UEFN/Verseに関するオープンコミュニティサーバーを建ち上げました。ちょっとでも興味があれば奮ってご参加くださいませ。

https://discord.gg/MehcNhyxdq