UE4の勉強記録

UE4の勉強の記録です。個人用です。

「Unreal Engine4.xを使用してRPGを作成する」の足りない部分を作成する。モンスターの追加 part 2

<前文>

f:id:kazuhironagai77:20191208123606p:plain

前回、前々回と続き、データサイエンスの話ですが、先週から更に調査した結果ある結論に達しました。私がデータサイエンスに対してかなりネガティブなイメージを持っている事を分かった上で話半分で聞いてほしいのですが、データ科学者って実際は占い師と同じ事をしているじゃないの?という結論です。

勿論、新薬の研究室とかに配置されたデータ科学者は違うでしょうが、一般的な会社に就職したデータ科学者は、経営者から会社の方針に対する相談を受けてそれに対してGoかStopの判断を下す所謂軍師ポジションを担ってるように見えます。

ここではっきり言っておきたいのは、この場合、データサイエンス的に結論が出るために必要な数と質のデータは決して揃わないのにGoかstopの決断を下す所です。のでやっている事は占い師と同じです。(勿論、機械学習とか深層学習のような高尚な技術はほとんど使用しないみたいです。)

世の中には、決して科学では割り切れない部分が存在してます。社運を賭けた決断を下す社長にどうしたらいいと聞かれたら、絶対成功する方法なんていくらデータを見ても見つけられないでしょう。そんな時どうやって決断するのか。

知り合いの会社経営者が教えてくれたのですが、そういう決断を下す時に、その人はある占い師に内緒で相談するそうです。孫子の時代から、占いを参考にしてはいけない。と言われていますが、そこは経営者といえ人間ですから弱い者。聞いてしまうんでしょうね。

流石に上場企業の社長になったら占い師に聞くわけにはいかないでしょう。会議で、占い師に聞いたら失敗すると言われたので止めます。なんて言えませんからね。そこでデータ科学者の出番ですよ。

となると、データ科学者に必要なのは、機械学習や深層学習などの知識よりも、カリスマ性やプレゼン力なのかもしれませんね。

勿論、そうじゃない分野も出てくるかもしれません。例えば、陸上や水泳の部活なんかは、練習期間は2年間しかないです。である生徒は、フォームを正しくする練習に特化するのが最も成績を向上させるとか、その他の生徒はウェイトトレーニングで筋肉を強化した方がいいみたいな結論は、出来るようになるかもしれません。それだって生徒がケガをしなければ、みたいな条件付きですが。

それで、私の結論なんですが、占い師ポジションでもいいんじゃない。と思いました。

データサイエンスの応用箇所がガチガチの科学、工学分野しかなければ、独学でデータサイエンスを勉強した人がデータ科学者として就職出来るチャンスは0でしょう。学歴とか、紹介状とかで絶対にはじかれてしまうはずです。仮に入れたとしても、資料作成的なポジションで、データエンジニアとしての仕事をやらされる訳でしょう。これは修行だと割り切っても、後から来た所謂高学歴の新卒が、データ科学者としてデータエンジニアの作成した成果を取っててしまう訳です。やる価値は多分ないでしょうね。

でも占い師的な軍師ポジションで、データから拾いきれない部分を明らかにした上で、その拾いきれない部分に対してある結論を下す場合なら、経営者だって色々な人の意見を聞いてみたいはずですし。ガチガチのデータサイエンスを勉強した人が、結論は分かりません。とかになったら経営者は、お前は間違えなければこの会社が倒産しても、大学に戻って先生やれるけど、俺はこのプロジェクト失敗したら責任とって首つらなきゃならないだぞ。みたいに考えるかもしれません。そうなったらプレゼン力とカリスマでその経営者に取り入る事だって出来そうです。

カリスマが無ければ出来ないので、社員になるのは駄目でしょうね。となるとコンサルとして独立するのが良いかもしれません。書籍かYouTubeで宣伝を兼ねつつカリスマ性とプレゼン力を見せつけて悩んいる経営者の相談役に収まっていく。

結構いけそうな気がしますね。

それでは今週の勉強を始めます。

<本文>

今週は、先週行ったモンスターの追加、出現、AI、そしてアニメーションの追加をCh2に行います。余った時間はAIの勉強をします。

<モンスターの追加>

1.モンスターの追加

f:id:kazuhironagai77:20191208123721p:plain

Skeleton Crew BundleをCh2に追加します。

f:id:kazuhironagai77:20191208123740p:plain

しました。

2.モンスターの出現

先週のBlogで確認すると、最初にCharacterクラスからMonsterCharacterクラスを作成しています。

一応、作成する前にCh2のC++のコードに類似のクラスを作成していないか確認します。

f:id:kazuhironagai77:20191208123808p:plain

Ch2のC++でCharacterクラスから作成したクラスは上記のRPGChracterクラスだけでした。このクラスはプレイヤーがコントロールするキャラクターのためのクラスなのでモンスターを表すC++のクラスはないようです。

f:id:kazuhironagai77:20191208123829p:plain

次にGameModeクラスに先週書いたコードをそのまま追加します。

f:id:kazuhironagai77:20191208123912p:plain

f:id:kazuhironagai77:20191208124040p:plain

唯一、先週と違う部分は、元々作成したあったBeginPlay()関数内にSuper::BeginPlay()がなかったので、そこだけは省きました。

ビルドします。

f:id:kazuhironagai77:20191208124116p:plain

成功しました。

テストします。

まず、MonsterCharacterクラスからMonsterCharacterBPを作成します。

DefaultRPGGameModeブループリントクラスを開いて、MonsterToSpawnにMonsterCharacterBPをセットします。

f:id:kazuhironagai77:20191208124138p:plain

MonsterCharacterBPを開きMeshをセットします。

f:id:kazuhironagai77:20191208124210p:plain

前回と同じようにサイズや向き、位置などを調整します。

f:id:kazuhironagai77:20191208124230p:plain

Playを押してゲームを始めます。

f:id:kazuhironagai77:20191208124401p:plain

モンスターは出現しました。

流石に、お店内にモンスターが出現しては困るので出現する場所を変更します。

f:id:kazuhironagai77:20191208124430p:plain

f:id:kazuhironagai77:20191208124440p:plain

マップの端っこに上記に示したような一角を作成しました。ここにモンスターを出現させます。

f:id:kazuhironagai77:20191208124503p:plain

出来ました。

3.AIの作成

NavMeshBoundsVolumeを追加します。

f:id:kazuhironagai77:20191208124530p:plain

f:id:kazuhironagai77:20191208124538p:plain

MyAIControllerをAIControllerクラスから作成します。

f:id:kazuhironagai77:20191208124557p:plain

MonsterCharacterBPを開き、AIController ClassにMyAIControllerをセットします。更に、Auto Possess AIにPlaced in World or Spawnedを選択します。

f:id:kazuhironagai77:20191208124658p:plain

BehaviorTreeとBlackboardを作成します。

f:id:kazuhironagai77:20191208124716p:plain

BehaviorTreeのBlackboard AssetにmyBlackboardDataを選択します。

f:id:kazuhironagai77:20191208124735p:plain

MyBlackboardDataを開き、Keyの名前をCharacterKeyに変更します。

f:id:kazuhironagai77:20191208124755p:plain

先週の説明では、この後でBase ClassをActorに変更すると書かれていますが、既にActorが選択されていました。

f:id:kazuhironagai77:20191208124817p:plain

今度は、MyBehaviorTreeを開いて、Behavior Treeを作成します。

f:id:kazuhironagai77:20191208124835p:plain

SequenceにMoveToとWaitを追加しようとしましたが、これらをCompositeから作成するのか、Taskから作成するのかが分かりません。

先週作成したプロジェクトを開いて確認します。

f:id:kazuhironagai77:20191208124854p:plain

Taskでした。

f:id:kazuhironagai77:20191208124928p:plain

出来ました。

MyAIControllerを開いて、RunBehaviorTreeをセットします。RunBehaviorTreeのノードのBTAssetにMyBehaviorTreeをセットします。

f:id:kazuhironagai77:20191208124953p:plain

BehaviorTreeに戻ってMoveToにdecorator, Blackboardを追加します。Decoratorの名前をIsPlayerValid?に変更します。

f:id:kazuhironagai77:20191208125040p:plain

次はCharacterKeyに値をセットします。

まず、NewTaskをクリックしてBTTask_BlueprintBaseNewを作成します。名前をFindPlayerServiceとします。

f:id:kazuhironagai77:20191208125328p:plain

f:id:kazuhironagai77:20191208125337p:plain

FindPlayerServiceを開きevent内でブループリントを組みます。

f:id:kazuhironagai77:20191208125407p:plain

Event Receive Activationがありません。うーん。どこかで間違えたのでしょうか?

HTF do I? Basic AI From Scratch #1 in Unreal Engine 4を見たらすぐ分かりました。

FindPlayerServiceはNewTaskから作成するのではなく、

f:id:kazuhironagai77:20191208125430p:plain

から作成する必要がありました。

作り直します。

f:id:kazuhironagai77:20191208125448p:plain

f:id:kazuhironagai77:20191208125455p:plain

今度は出来ました。

更に、Sequenceの所にFindPlayerServiceを追加します。これも先週のブログでは書いてませんでした。

f:id:kazuhironagai77:20191208125759p:plain

FindPlayerServiceを開きevent graph内で、Event Receive Activationを選択します。

f:id:kazuhironagai77:20191208125824p:plain

今度はしっかりありました。

うーん。やっぱり先週作成したブログからだけではAIの部分は作成出来ないですね。チュートリアルを見ながら確認して作成していきます。

もういきなりですが、Event Receive Activationの選択方法まで全然違ってます。FunctionのOverrideから選択してますね。

f:id:kazuhironagai77:20191208125850p:plain

今度は、簡単に出来ました。やはりまだAIの部分は理解していないので、チュートリアルを見ながらじゃないと正しく作成するのは無理ですね。

f:id:kazuhironagai77:20191208125917p:plain

PlayerObjectをPublicにする理由もしっかり説明されていました。

f:id:kazuhironagai77:20191208125937p:plain

これが、PlayerObjectがprivateの場合にMyBehaviorTree内でFindPlayerServiceを選択した時にdetail内に表示される内容です。

f:id:kazuhironagai77:20191208130019p:plain

MyBehaviorTree内からPlayerObjectの値を選択する事が出来ません。PlayerObjectをpublicにするとPlayerObjectの値は選択出来るようになります。

f:id:kazuhironagai77:20191208130104p:plain

これでAIは完成のはずです。テストしてみます。

プレイヤーのキャラクターがNavMeshBoundsVolume内に侵入すると凄い勢いで追いかけて来ます。

f:id:kazuhironagai77:20191208130129p:plain

出来ましたね。

ただし新たな問題も見つかりました。

f:id:kazuhironagai77:20191208130207p:plain

モンスターがプレイヤーのキャラクターを勢いよく追いかけすぎて、NavMeshBoundsVolume外に飛び出してしまう時があります。そうなるとモンスターは全く動かなくなります。

これは問題ですが、来週以降に直す事にします。

4.アニメーションの追加

何か今週は凄い疲れてます。やっている事は先週の繰り返しなのに何でこんな疲れるんですかね。

兎に角、モンスターのアニメーションを作成します。

animation からBlend Space 1Dを選択し、Skeleton_Swordman_Skelを選択します。名前はSkelSword1Dとします。

f:id:kazuhironagai77:20191208130246p:plain

SkelSword1Dを開いて、軸の設定をします。全く先週と同じです。

f:id:kazuhironagai77:20191208130308p:plain

アイドル、歩く、走るのアニメーションをそれぞれの箇所にセットします。

f:id:kazuhironagai77:20191208130329p:plain

今度は、Animation Blueprintを作成します。AnimInstance、Skeleton_Swordman_Skelをそれぞれ選択します。名前はSkelSwordAniにします。

f:id:kazuhironagai77:20191208130349p:plain

AnimGraphを開き、State Machineを追加します。State Machineの名前はdefaultです。

f:id:kazuhironagai77:20191208130406p:plain

Defaultの中身を作成します。

f:id:kazuhironagai77:20191208130424p:plain

Idle/Runの中身を作成します。

f:id:kazuhironagai77:20191208130442p:plain

Speed変数に値をセットするために、イベントグラフにコードを追加します。

f:id:kazuhironagai77:20191208130505p:plain

これで完成です。

テストします。

MonsterCharacterBPのAnimationにSkelSwordAniをセットします。

f:id:kazuhironagai77:20191208130615p:plain

何から何まで、全部先週と同じで方法で作成しましたが、これでアニメーションも動くはずです。

f:id:kazuhironagai77:20191208130639p:plain

大迫力で追いかけてくれました。成功です。

UE4におけるAIについての勉強>

どうもまだUE4のAIの作成方法を理解していません。ので今週はAIの勉強をします。

HTF do I? Basic AI From Scratch #1 in Unreal Engine 4をもう一度復習して、Unreal Engine 4 Tutorial – AIを今度こそ勉強します。

私が大学にいた時は、AIと機械学習は別のクラスでした。今、機械学習以外のAIはどこで習えるのでしょうか?AIのクラスは選択しなかったので、今となってはどんな内容を教えていたのか全く分かりません。唯一知っている事は、そのクラスを取った友達が見せてくれた教科書の最初のページにパックマンが載っていた事です。UE4のAIを見ても、まだ勉強していませんが、機械学習とは全然違うように思えます。やはりパックマンの事と言いゲーム専用のAI分野があるような気がします。

あ、そうだ!ゲームとAIで調べればいいんですね。

以下に示す本が出て来ました。

f:id:kazuhironagai77:20191208130712p:plain

まず、三番目の本、Artificial Intelligence: A Modern Approach (3rd Edition) 3rd EditionがAI全般の定番の教科書みたいですね。

f:id:kazuhironagai77:20191208130735p:plain

アマゾンで211人もreviewしてます。しかも高評価です。Stanford大学のAIのクラスの教科書にも使用されているみたいです。ただしゲームのAIについではないです。コメント欄をざっくばらんに読んでみると、本の内容よりも製本やキンドルの場合は図の配置などに関する文句が多いみたいです。最新の版では直っているんでしょうか?その他のコメントで面白かったのは、版が新しくなったから買い直したら内容がほとんど同じだったけど、良く考えたらAIそのものが前の版からそんなに進歩してないね。というのと、他のAIの本みたく、大袈裟に書かれてない所がいい。と言うコメントでした。

これってAIそのものは学問としては順調に進んでいるけど、世間が期待しているような革新的な発明は起きてないよ!と言う事でしょう。

ほら!やっぱり今の世間の言うほどは凄くない。まあ止めときます。この話題は。

兎に角、この本は手元に一冊は置いとかないといけない本ですね。

後、スタンフォード大学って全ての講義をYouTubeに挙げるとか宣言してませんでしたっけ。もしかしたらこの本を使用した講義もどこかで無料で見れるかもしれませんね。

探したら、ここバークレー校のAIの講義が挙げられていました。

f:id:kazuhironagai77:20191208130819p:plain

2012年となっているので少し古ですね。ただ最初の講義を見たらこの教科書を紹介しているので参考にはなるでしょうね。

Artificial Intelligence for GameとArtificial Intelligence and Gameは両方ともゲームのためのAIの本ですね。どっちがいいんでしょうか?両方とも2年以内に新しい版になっているので、内容的に古すぎる事はなさそうですね。両方買っといてもいいかもしれませんね。ぱらっとアマゾンで見た感じではArtificial Intelligence for Gameの方が良いように思えますね。こっちにしておきますか。

これだけ分かれば十分ですね。

それでは、UE4におけるAIの勉強を始めます。

HTF do I? Basic AI From Scratch #1 in Unreal Engine 4

新しくプロジェクトを作成してやります。後、#2もあるみたいですのでそれもやります。

一応、先週、そして今週の2回ほど、ほぼこのチュートリアル通りにAIを作成したので、このチュートリアルの勉強は今回で3回目になります。今度こそ完全に理解したいです。

今回は。4.24で作成してみます。

f:id:kazuhironagai77:20191208130844p:plain

何これ?

Gameでいいのは分かるんですが、Filmとか、EngineeringそしてProduct Designなんてあります。中身も違うんでしょうか?

取りあえず今回はGameを選択します。

後はそのままで、一応、BlueprintかC++かの所だけC++に変更しました。

f:id:kazuhironagai77:20191208130908p:plain

後、勿論ThirdPersonを選択しました。

1.Navigation Volumeをセットする。

Nav Mesh Bounds Volume を選択してレベル内にセットします。

f:id:kazuhironagai77:20191208130933p:plain

こんな感じにセットしました。

f:id:kazuhironagai77:20191208130951p:plain

そう言えば、Navigation Volumeをセットすると表示されるこの緑色の箇所はなにを表しているでしたっけ。調べて見ます。

公式のサイトによると、

f:id:kazuhironagai77:20191208131010p:plain

Nav Mesh Bounds Volumeはレベル内に建てられたNav Meshsをコントロールするために使用されます。

Nav Meshsはレベル内のエリアのあらゆる場所でNavigation pathを計算します。

Volume内では歩けるような適切な角度で全ての表面にNav Meshは作成されます。

...

と書かれていました。

ここから以下の事が推測出来ます。

  • 緑の箇所がNav Mesh
  • Nav Mesh上でNavigation pathが計算される。
  • Nav Mesh上のみでAIは行動はする。

なるほど、Navigation Volumeは、ワンピースに出て来たオペオペの実のルームみたいな概念を実装しているんですね。

f:id:kazuhironagai77:20191208131105p:plain

こんな感じ。

ただし、AIが影響を受けるのは、地面に接している緑の部分だけ。そこが違う所ですね。

(後で考えたんですけど、SphereじゃなくてCircleって言ってますね。ひょっとしてオペオペの実もNavigation Volumeと同じように地面に接している部分しか影響ないの?ジャンプしたらオペオペの実の攻撃は躱せるんですかね。)

2.AIを作成する。

Nav Meshだけでは何の役にも立ちません。使用するためには更にAIを作成する必要があります。AIを作成するためにはAIControllerとAIControllerによってコントロールされるキャラクターが必要になります。

AIControllerから作成していきます。

BlueprintからAIControllerを選択して作成しました。

f:id:kazuhironagai77:20191208131227p:plain

所で、UE4C++ではAIControllerは作成出来ないのでしょうか?

試してみましょう。

f:id:kazuhironagai77:20191208131247p:plain

ありますね。

一個だけUE4C++でAIを作成するチュートリアルも見つかりました。Unreal Engine 4.11.2 C++: Artificial Intelligence Essentials Part 1 - The Base

ただこのチュートリアル、作者が途中で制作するのを中止してしまったみたいですね。

今回は基本をまず理解しないといけないので、UE4C++については後回しにします。

今度はAIがコントロールするキャラクターを作成します。

キャラクターはUE4C++から作成してもいいんですが、(実際、RPGのプロジェクトの方ではUE4C++から作成した。)今回はチュートリアルに忠実にと言う事でブループリントから作成します。

f:id:kazuhironagai77:20191208131308p:plain

このチュートリアルではStatic Mesh Componentであるcubeとsphereを追加する事でH-AICharacterの形状を作成してます。

f:id:kazuhironagai77:20191208131333p:plain

f:id:kazuhironagai77:20191208131341p:plain

Mesh内のskeletal meshに指定する場合とどう違うんですかね。

f:id:kazuhironagai77:20191208131358p:plain

勿論、こっちはSkeletal meshでチュートリアルはStatic Mesh Componentであるのが違いと言うのは分かっていますが。

次に、AI Controller ClassにH-AIControllerをセットします。

f:id:kazuhironagai77:20191208131417p:plain

H-AICharacterをレベル内に配置しました。

f:id:kazuhironagai77:20191208131437p:plain

思ったより小さいですね。まあいいでしょう。

3.Behavior Treeを作成する。

前節で、キャラクターにAIControllerをセットしたのにキャラクターが全く動かないのは何故でしょうか?理由は二つあります。

  1. Behavior Treeがセットされていない。
  2. Behavior Treeを使用するように言っていない。

では、まずBehavior Treeを作成します。

f:id:kazuhironagai77:20191208131533p:plain

作りました。

開きます。

開くと、Blackboard Assetをセットする個所があります。

f:id:kazuhironagai77:20191208131552p:plain

のでBlackboard Assetを作成してセットします。

ちょっと待って!!

このBehavior TreeとBlackboard Assetについて目的と役割が良く分からないので先に調べます。

公式サイトのBehavior Treesの説明です。

f:id:kazuhironagai77:20191208131618p:plain

UE4のBehavior Treesは貴方のプロジェクト内のNPCのためのAIを作成するために使用されます。

Behavior Treeが、ブランチに保持されているロジックを実行するために使用されている間、どのブランチを実行するか決定するために、Behavior Treeのブレインとして働くBlackboardと呼ばれる別のアセットを頼ります。

これだけで結構Behavior TreeとBlackboard Assetの役割が分かりますね。

でもこれって単なるif statementではないでしょうか?

AIと言うからにはcomputerが自分で学習して行動を決定するんじゃないの?

うーん。この辺はAIの教科書らを読んだ方が理解しやすそうですね。

Blackboardを作成します。

f:id:kazuhironagai77:20191208131722p:plain

AI-BTのBlackboard AssetにAI-BBをセットします。

f:id:kazuhironagai77:20191208131745p:plain

次にAI-BB内にkeyを作成します。

このAIはプレイヤーのコントロールするキャラクターを見つけたら追いかけるAIなので、プレイヤーのキャラクターを保持するためのkeyが必要になります。ので

KeyのタイプにObjectを選択し、

f:id:kazuhironagai77:20191208131804p:plain

ベースタイプにActorを選択します。

f:id:kazuhironagai77:20191208131822p:plain

うーん。なるほど。KeyTypeはObjectしかないからBase ClassでActorを選択するんですね。でもCharacterクラスは選択出来ないでしょうか?

f:id:kazuhironagai77:20191208131840p:plain

出来ますね。まあ、今回はActorクラスで代用出来るのであえてCharacterクラスを選ばなかったと理解します。

因みにこのKeyの名前は、

f:id:kazuhironagai77:20191208131900p:plain

PlayerKeyとしました。

AI-BT内にBehavior Treeを作成します。

f:id:kazuhironagai77:20191208131923p:plain

これでテストします。

f:id:kazuhironagai77:20191208131940p:plain

動きません。何故でしょうか?

理由は二つあります。

  1. AI-BTのBehavior Treeはどこからも呼ばれていないので何もしない。
  2. PlayerKeyに値が入っていない。

ではこれらの問題を解決しましょう。

H-AIControllerを開きEvent Graphに行きます。

以下のコードを書きます。

f:id:kazuhironagai77:20191208132015p:plain

これで、AI-BTを呼ぶ事が出来る様になりました。

Playを押してみると、NPCは全く動きませんが、AI-BTのBehavior Treeは以下に示すように確かに実行されています。

f:id:kazuhironagai77:20191208132034p:plain

でも、良く見ると、ずっとMoveToの方を実行していてWaitは全く実行されていません。

これは、PlayerKeyの値がNoneになっているためです。

f:id:kazuhironagai77:20191208132055p:plain

これを直します。

直しますが、その前に、このような有効でない値をもったPlayerKeyに対してMoveToを使用しないようにさせます。そうしないとコードの安全性が保てませんから。

その為には、以下に示すようにDecoratorを使用します。

f:id:kazuhironagai77:20191208132115p:plain

これでPlayerKeyがnoneでない事を確認します。

これでPlayを押してみると、MoveToも実行されません。以下に示すように、IsPlayerValid内に赤いバーが表示されています。PlayerKeyに有効な値が入ってないからです。

f:id:kazuhironagai77:20191208132134p:plain

オブジェクトを使用する前にそのオブジェクトが有効なアドレスを保持しているかを確認する事はC++でコード書いている人は当たり前の事で、ここで重要な事はBehavior Treeにおけるオブジェクトのチェックの仕方はこうするのかと言う事ですな。

うん。分かりました。

では、PlayerKeyに適切な値をセットします。

そのためには、まずNew Serviceをクリックして

f:id:kazuhironagai77:20191208132158p:plain

BTService_BlueprintBaseを作成します。

f:id:kazuhironagai77:20191208132217p:plain

名前をFindPlayerServiceに変更しました。更に、Behavior TreeのSequenceにFindPlayerServiceをセットします。

f:id:kazuhironagai77:20191208132241p:plain

Sequence内でFindPlayerServiceを呼ぶ訳ですね。となるとFindPlayerService内でKeyPlayerに有効なオブジェクトを指定すれば良い訳ですね。

FindPlayerServiceを開いてEventGraphを表示します。

まず、Event Receive ActivationをFunction Overrideから選択します。

f:id:kazuhironagai77:20191208132307p:plain

なるほど、流石に3回目だとよく分かりますね。前回はこの辺は何でやっているのか全く理解しないでやってました。Sequenceを実行する時にこのEventが発動する訳ですね。

f:id:kazuhironagai77:20191208132339p:plain

これで、PlayerObjectにKeyPlayerの有効な値であるプレイヤーがコントロールするキャラクターのデータを保持するアドレスが入るはずです。

これをBehavior Treeに戻ってFindPlayerServiceを選択してPlayerObjectとKeyPlayerを繋げれば完成です。

しかし、Behavior Treeに戻ってFindPlayerServiceを選択してみるとPlayerObjectは表示されていません。何故でしょうか?

f:id:kazuhironagai77:20191208132406p:plain

そうです。PlayerObjectがprivateだからです。

PlayerObjectをPublicにして

f:id:kazuhironagai77:20191208132429p:plain

もう一度Behavior Treeに戻ってFindPlayerServiceを選択してみると

f:id:kazuhironagai77:20191208132451p:plain

今度はPlayerObjectの値を選択出来るようになりました。今回は既にPlayerKeyが選択されています。

プレイを押して確認します。

f:id:kazuhironagai77:20191208132513p:plain

完成しました。

もう疲れました。今週はこれでお終にします。

<まとめと感想>

AIの勉強は来週します。