LoginSignup
5
3

More than 5 years have passed since last update.

【UE4】AIPerceptionをAIControllerとCharacterにアタッチした時の違い

Last updated at Posted at 2018-02-24

はじめに

過去に書いたAIPerceptionの紹介記事(【UE4】AI Perception の紹介と使い方【UE4】AI Perception の紹介と使い方 その2)では

AI Perceptionコンポーネントでは「コントローラー側にコンポーネントを追加する」という形になります。

と説明しました。
記憶が朧気なのですが、最初の紹介記事を書いた時点でAIPerceptionはAIControllerでアタッチされた時にしか動作しなかったと思います。ですので、紹介記事ではコントローラー側にコンポーネントを追加するようにと書きました。

最近AIPerceptionをCharacter側にアタッチして問題なく動作する場面(その時はAISense_Sightでした)を見てしまったので「Character側に付けても問題ないのならば、AIControllerに付ける意味とは一体...?」と考え、自分なりに検証してみたのでその結果を書いていきます。

検証処理

検証に使用したバージョンは4.18.3です。

Characterを継承したBlueprintにAIPerceptionを付けたもの。AIControllerを継承したBlueprintにAIPerceptionを付け、Characterを継承しただけのBlueprintにそのAIControllerをセットしたものの2種類用意しました。
AIPerceptionが付いている方にはそれぞれ以下のような処理を追加しました。

2018-02-25_00h03_34.png

2018-02-25_00h04_40.png

AISense_TeamとAISense_Touchについては検証していません。

検証結果

AISense_DamageとAISense_Predictionは動作しない

【UE4】AI Perception の紹介と使い方 その2で紹介したAISense_DamageとAISense_PredictionはCharacter側にAIPerceptionを付けた場合、動作しませんでした。

AISense_Damage.cppで定義されている関数Updateは以下のように書かれています。

float UAISense_Damage::Update()
{
    //~~ 省略 ~~
            UAIPerceptionComponent* PerceptionComponent = PerceptionListener->GetPerceptionComponent();
            if (PerceptionComponent != nullptr && PerceptionComponent->GetListenerId().IsValid())
            {
                // this has to succeed, will assert a failure
                FPerceptionListener& Listener = ListenersMap[PerceptionComponent->GetListenerId()];

                if (Listener.HasSense(GetSenseID()))
                {
                    Listener.RegisterStimulus(Event.Instigator, FAIStimulus(*this, Event.Amount, Event.Location, Event.HitLocation));
                }
            }
        }
    }

    RegisteredEvents.Reset();

    //~~ 省略 ~~
}

PerceptionListener->GetPerceptionComponent()を呼び出しAIPerceptionComponentを取得しています。(この関数はAIControllerで定義されています)
Character側にAIPerceptionを付けた場合、関数GetPerceptionComponentはNULLが返り、刺激が登録されず、Blueprint側で書いたOnPerceptionUpdateが呼び出されません。

AISense_Predictionも関数Updateの形はほぼ同じなので同様の理由で受けた刺激が登録されず、OnPerceptionUpdateで定義したDamageとPredictionの刺激を受けた際の処理を通ることはありません。

じゃあAISense_SightとAISense_Hearingは?

この2つの検証は上記で示した検証コードのブランチ部分をそれぞれAISense_SightAISense_Hearingに変更し、PrintStringの内容を変えただけです。
AISense_SightやAISense_HearingはAIPerceptionを付けた時に必ずと言って良い程追加される刺激ですが、この2つの刺激についてはCharacter側に付けようがAIController側に付けようが問題なく動作します

エンジンコードを見てみると2つのクラスの関数Updateでは関数GetPerceptionComponentを呼び出し条件分岐させるような部分が無いため、Characterに付けてもAIControllerに付けても影響は受けないものと思われます。

結論

簡単な検証ではありますが得られた結果として

Character側にAIPerceptionを付けた場合AISense_SightとAISense_Hearingは動作するAISense_DamageとAISense_Predictionは動作しない
AIController側の場合は4つのAISenseは問題なく動作する

ということがわかりました。

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3