GetHorizontalDotProductToとは??

今回「GetHorizontalDotProductTo」という
気になるノードを見つけたので

どういうノードなのかを解説します。

f:id:Free_Gamer:20190911104133p:plain

このノードは

 

OtherActorが、ターゲットの前面・後面のどちら側にいるのかを
「1」~「-1」の値で返してくれます。

 

・・・よくわかんないですよね。すいません。

 

とりあえず実際に使ってみましょう!

 

 

~OtherActorの作成~

「ThirdpersonCharacter」をコピーし

「OtherActor」という名前を付けます。

f:id:Free_Gamer:20190911110607p:plain


「OtherActor」を以下のようにレベルに配置します。

「ThirdpersonCharacter」と平行な位置に配置します。

f:id:Free_Gamer:20190911110717p:plain



~レベルBPの編集~

レベルBPを開き

イベントグラフに以下の処理を作成します。

f:id:Free_Gamer:20190911111328p:plain

「Qキー」を押した時

GetHorizontalDotProductToの返す値を表示します。

 

実際にプレイしてみましょう。

f:id:Free_Gamer:20190911111734p:plain

f:id:Free_Gamer:20190911111802p:plain

ほぼ「0」に近い数字が返されましたね。

 

今度は「ThirdpersonCharacter」の向きを

「OtherActor」の方向に向けます。

f:id:Free_Gamer:20190911112448p:plain

 

これでプレイしてみましょう。

f:id:Free_Gamer:20190911112829p:plain

f:id:Free_Gamer:20190911113236p:plain

今度は「1」が返ってきました。

 

どういう条件で値が返されるかというと・・・

f:id:Free_Gamer:20190911114748p:plain

上から見た図です。

 

ターゲット(ThirdpersonCharacter)の前面に

OtherActorがいる場合「1」を返す。

ターゲット(ThirdpersonCharacter)の後面に

OtherActorがいる場合「-1」を返す。

 

というノードなのです!

 

なので、ターゲット(ThirdpersonCharacter)の真横に

OtherActorがいた場合は

「0」に近い値を返す

といった感じになります。

f:id:Free_Gamer:20190911115620p:plain

 

 

この「GetHorizontalDotProductTo」ノードを使えば

OtherActorがプレイヤーの前面・後面どちらにいるのかを

簡単に判定できます。

f:id:Free_Gamer:20190911120215p:plain

 

youtu.be

 

お役に立てれば幸いです。

 

 

それではまた!^^ノシ

ポーズ画面の実装!

今回は

 

ポーズ画面の実装!

 

方法を紹介します。

 

今回紹介する方法は

普段自分がやっている方法とは違うのですが

 

UE4初心者もこの記事を見るかもしれないので

あえて自分が普段やっている方法とは違う

(個人的に)至ってシンプルな方法を紹介します。

 

UE4初心者の方を混乱させないためです。

(とはいえ自分もUMGは初心者みたいなものですがw)

 

あと、UMGの作成の解説がクソみたいに長く

ごちゃごちゃしてるかもしれませんが

とりあえず画像の通りやれば出来るはずなので

落ち着いてやりましょう!w

 

 

実装したい事

・「Pキー」を押した時、ポーズ画面を出す。

・ポーズ中、「Pキー」を押した時、あるいは「Return(ゲームに戻る)」ボタンを

クリックした時、ポーズを解除する。

 

 

 

~インターフェースの作成~

「UI_Interface」という名の

BPインターフェースを作成

f:id:Free_Gamer:20190831181321p:plain

 

「UI_Interface」を開き

新規関数「OnPauseBPI」を作成

f:id:Free_Gamer:20190831181520p:plain

引数(インプット)

f:id:Free_Gamer:20190831181535p:plain

 

 

~ポーズUMGの作成~

「Pause」という名の

UMGを作成

f:id:Free_Gamer:20190831181120p:plain

以下の通りに

UMGを作成します。

f:id:Free_Gamer:20190831183636p:plain

階層は以下の通りです。

f:id:Free_Gamer:20190831183757p:plain

各パネルについて

上から順に説明していきます。

 

「Overlay」

パレットの「パネル」項目内にあります。

f:id:Free_Gamer:20190831183948p:plain

「Overlay」を

階層の親である

「CanvasPanel」の子として追加します。

f:id:Free_Gamer:20190831184246p:plain

「CanvasPanel」から少し右にズレて

追加されるはずです。

 

「Overlay」が

親である「CanvasPanel」の子として

追加された証拠です。

 

 追加した「Overlay」のアンカーを

「画面全体」にします。

f:id:Free_Gamer:20190831184447p:plain

 

「Overlay」の

「左オフセット」

「上オフセット」

「右オフセット」

「下オフセット」

を全て「0」にします。

f:id:Free_Gamer:20190831184705p:plain

 

これでUMGの画面四隅に

赤枠で囲ってある白いビックリマークのようなものがあれば

OKです。

f:id:Free_Gamer:20190831185142p:plain

 

「SizeBox」

パレットの「パネル」項目内にあります。

f:id:Free_Gamer:20190831193608p:plain

「SizeBox」を

「Overlay」の子として追加します。

f:id:Free_Gamer:20190831193906p:plain

これで、「SizeBox」の子のサイズを

好きなように変えることが出来ます。

 

さっそく「SizeBox」で

サイズを指定しましょう。

 

「SizeBox」の詳細パネルを

以下のように設定します。

f:id:Free_Gamer:20190831194316p:plain

「スロット」項目内にある

「HorizontalAlignment(水平方向の配置)」

「VerticalAlignment(垂直方向の配置)」

を、真ん中に設定。

 

「ChildLayout」項目内にある

「WidthOverride(横幅)」を「500」

「HeightOverride(立幅)」を「200」

に設定。

 

これでサイズを設定することが出来ました。

 

「ScaleBox」

パレットの「パネル」項目内にあります。

f:id:Free_Gamer:20190831194909p:plain

「ScaleBox」を

「SizeBox」の子として追加します。

f:id:Free_Gamer:20190831195012p:plain

「ScaleBox」を入れることによって

「SizeBox」の数値に合わせて

「ScaleBox」が子のサイズを拡大縮小させてくれます。

 

ちょっとよくわからない??

という方はこの動画が分かりやすい・・・はず・・・です・・・

 

 

「VerticalBox」

パレットの「パネル」項目内にあります。

f:id:Free_Gamer:20190831200425p:plain

「VerticalBox」を

「ScaleBox」の子として追加します。

f:id:Free_Gamer:20190831200725p:plain

 

「VerticalBox」の詳細パネルを

以下のように設定します。

f:id:Free_Gamer:20190831201017p:plain

スロット項目内にある

「HorizontalAlignment(水平方向の配置)」

を横全体

「VerticalAlignment(垂直方向の配置)」

を、真ん中に設定。

 

「Text」

パレットの「一般」項目内にあります。

f:id:Free_Gamer:20190831201711p:plain

「Text」を

「VerticalBox」の子として追加します。

f:id:Free_Gamer:20190831201757p:plain

「Text」の詳細パネルを

以下のように設定します。

f:id:Free_Gamer:20190831201850p:plain

「スロット」項目内にある

「HorizontalAlignment(水平方向の配置)」

を真ん中

「VerticalAlignment(垂直方向の配置)」

を、縦全体に設定。

 

「Content」項目内の

「Text」内に「Pause」と入れましょう。



「Button」

パレットの「一般」項目内にあります。

f:id:Free_Gamer:20190831202440p:plain

「Button」を

「VerticalBox」の子として追加します。

f:id:Free_Gamer:20190831202344p:plain

追加した「Button」に

「ReturnButton」と名付けます。

 

ポーズ画面を解除する為のボタンという事です。

 

 

「Text」を

「ReturnButton」の子として追加します。

f:id:Free_Gamer:20190831203540p:plain

「Text」の詳細パネルを

以下のように設定します。

f:id:Free_Gamer:20190831203656p:plain

スロット項目内にある

「Padding」を「0」

 

「Content」項目内の

「Text」内に「Return」と入れましょう。

 

 

「Button」を

「VerticalBox」の子として追加します。

f:id:Free_Gamer:20190831204129p:plain

追加した「Button」に

「ExitButton」と名付けます。

 

ゲームを終了する為のボタンという事です。

 

 

「Text」を

「ExitButton」の子として追加します。

f:id:Free_Gamer:20190831204351p:plain

「Text」の詳細パネルを

以下のように設定します。

f:id:Free_Gamer:20190831204535p:plain

スロット項目内にある

「Padding」を「0」

 

「Content」項目内の

「Text」内に「Exit」と入れましょう。

 

これでUMGの作成は終了です。

 

~ポーズUMGのイベントグラフ作成~

関数「PauseSwitch」を作成

f:id:Free_Gamer:20190831182358p:plain

「PauseSwitch」の中身は

以下の通り

f:id:Free_Gamer:20190831182424p:plain

Trueに繋がる処理

ゲームをポーズする処理です。

f:id:Free_Gamer:20190831182454p:plain

Falseに繋がる処理

ポーズを解除する処理です。

f:id:Free_Gamer:20190831182513p:plain

 

作成したBPインターフェース

「UI_Interface」を追加

f:id:Free_Gamer:20190831182831p:plain

 

イベントグラフに以下の処理を

作成します。

f:id:Free_Gamer:20190831182217p:plain

 

以下の処理は

各ボタンがクリックされた時のイベントです。

f:id:Free_Gamer:20190831205111p:plain

「ReturnButton」がクリックされた時

「PauseSwitch」関数を呼び出す。

引数「Pause」は「False」で。

 

「ExitButton」がクリックされた時

ゲームを終了します。

 

「Pキー」が押された時

ポーズ画面を表示したり

非表示にしたりする処理です。

f:id:Free_Gamer:20190831205718p:plain

 

 

~ThirdpersonCharacterのイベントグラフの作成~

「ThirdpersonCharacter」を開き

以下の処理を作成します。

f:id:Free_Gamer:20190831205846p:plain

 

作成した「Pause」UMGのリファレンスを取得

f:id:Free_Gamer:20190831205952p:plain

 

「Pキー」が押された時

ゲームがポーズ状態か判定

f:id:Free_Gamer:20190831210038p:plain

 

「Pキー」押した時

ポーズ状態なら、「Pause」UMGにあるBPインターフェースイベント

「OnPauseBPI(引数『False』)」を呼び出す。

ポーズ状態でなければ、「Pause」UMGにあるBPインターフェースイベント

「OnPauseBPI(引数『True』)」を呼び出す。

f:id:Free_Gamer:20190831210136p:plain

 

 

これでプレイしてみましょう!

(何故か動画だとマウスカーソルが出ていませんがお気にせず)

youtu.be

 

「Pキー」を押したら

しっかりポーズ画面が表示されて

「Return」ボタンを押したら

しっかりゲーム画面に戻ってましたね!

 

・・・しかし、1つ問題があるのに気が付いたでしょうか??

 

「Pキー」を押してポーズ画面が表示されるのはいいのですが

もう一度「Pキー」を押してもポーズ画面が消えてくれません。

 

どうすればいいのか??

 

「Pキー」を選択し

f:id:Free_Gamer:20190831211230p:plain

詳細パネルの「ExecuteWhenPaused」にチェックを入れれば解決です!

f:id:Free_Gamer:20190831211219p:plain

どうやらゲームがポーズされると

キー入力を受け付けなくなるようです。

 

しかし、「ExecuteWhenPaused」にチェックを入れれば

ゲームがポーズされていても

キー入力を受け付けてくれるのです!

 

 

という事でもう一度プレイ!

youtu.be

 

今度は、「Pキー」を押した時と「Return」ボタンを押した時に

ポーズ画面を消すことが出来てますね!

 

 

今回はくsssssっそ長くなりましたが

画像通りにやっていけば出来るはずですw

 

分からないこと・抜けてると思われる所があれば遠慮なく

Twitterhttps://twitter.com/Demonskiller5までDMなりなんなりください!

 

それではまた^^ノシ

 

 

 

しゃがみから立ち上がれるかどうかをチェックする方法!

※前回の記事の続きとして紹介してるので

 前回の記事を読んでから見ることをお勧めします。

 

 

前回の記事で

free-gamer.hatenablog.com

しゃがみアニメーションの方法を書きました。

 

しゃがむことが出来るのは良いのですが

1つ問題があります。

 

どういう問題かというと・・・

 

もしここで立ち上がろうとしたら・・・

f:id:Free_Gamer:20190828154945p:plain

f:id:Free_Gamer:20190828155044p:plain

普通に立ち上がれてしまうのです!

思いっきり貫通してしまって

明らかにおかしいことになってしまいますよね!w

 

今回はそのようなことが起きないように

 

しゃがみから立ち上がれるかどうかをチェックする方法!

 

を紹介します!

 

 

~イベントグラフの作成~

「ThirdpersonCharacter」を開き

イベントグラフに以下の処理を作成します。

f:id:Free_Gamer:20190828160811p:plain

 

「Qキー」を押した時

立ち上がり可能か判定

f:id:Free_Gamer:20190828161645p:plain

 

FlipFlopの「A」に繋がる処理

f:id:Free_Gamer:20190828161712p:plain

インターフェース「SetPlayer_CrouchingBPI」を呼び出した後

カスタムイベント「CanPlayerStanding」を

タイマーで「0.01」秒毎に呼び出しています。

 

FlipFlop「B」に繋がる処理

f:id:Free_Gamer:20190828162327p:plain

しゃがみから立ち上がり、タイマーを止める。

 

 

~カスタムイベント「CanPlayerStanding」の作成~

カスタムイベント「CanPlayerStanding」イベントは

以下のようになってます。

f:id:Free_Gamer:20190828162026p:plain

Sphereトレースで、頭上に立ち上がるのを阻害する障害物があるかを

チェックしています。

 

トレースがヒットしたら、障害物があるとして立ち上がり不可

トレースがヒットしてなければ、障害物がないとして立ち上がり可能

 

となります。

 

 

~CapsuleComponentのサイズ調整~

そして、これは前回言い忘れたのですが・・・

Crouchノードを呼び出した時に

f:id:Free_Gamer:20190828163140p:plain

CapsuleComponentのサイズ(高さ)が自動で変化します。

 

f:id:Free_Gamer:20190828163314p:plain

f:id:Free_Gamer:20190828163331p:plain

こんな感じですね。

 

しかし、このサイズだと

場合によっては以下のようなことが起こってしまいます。

f:id:Free_Gamer:20190828163612p:plain

CapsuleComponentのサイズが小さいので

頭が貫通してしまいます。

 

そういう時は

CharacterMovementの「CharacterMovement(GeneralSetting)」項目にある

「CrouchedHalfHeight」の値を変えましょう。

f:id:Free_Gamer:20190828163949p:plain

f:id:Free_Gamer:20190828164002p:plain

デフォルトでは「40」になっているので

「60」ぐらいが丁度良いでしょう。

 

 

必要な準備はすべて終わりました。

これでプレイしてみましょう!

 

「Qキー」を押してるか分かるように

「PrintString」で画面左上に文字を表示させてます。

f:id:Free_Gamer:20190828164437p:plain

 

 

youtu.be

 

しゃがんでいる時

上に障害物があった場合

何回「Qキー」を押しても

立ち上がれていないのが分かったと思います。

 

 

それではまた!^^ノシ

しゃがみアニメーションのやり方!

~アニメーションをプロジェクトに追加~

作成したプロジェクトに

「アニメーションスターターパック」を追加します。

f:id:Free_Gamer:20190824052439p:plain

 

 

~アニメーションリターゲット~

コンテンツ内にある

「Mannequin」を開き

f:id:Free_Gamer:20190824053849p:plain

「Character」→「Mesh」と開いていきます。

f:id:Free_Gamer:20190824054008p:plain

f:id:Free_Gamer:20190824054018p:plain

「Mesh」ファイル内にある

UE4_Mannequin_Skeleton」を開きます。

f:id:Free_Gamer:20190824054104p:plain

画面上部ツールバー

「リターゲットマネージャー」をクリック。

f:id:Free_Gamer:20190824054250p:plain

画面左にリターゲットマネージャーが表示されます。

ヒューマノイドリグを選択」をクリック。

f:id:Free_Gamer:20190824054404p:plain

最後に保存してください。

f:id:Free_Gamer:20190824054626p:plain

 

コンテンツフォルダに戻り

「AnimStarterPack」ファイルを開きます。

f:id:Free_Gamer:20190824054812p:plain

UE4_Mannequin」→「Mesh」の順で開いていき

UE4_Mannequin_Skeleton」を開きます。

f:id:Free_Gamer:20190824054934p:plain

そして、先ほどの手順を行います。

「リターゲットマネージャー」を開き

ヒューマノイドリグを選択」し

最後に保存

です。

 

コンテンツフォルダに戻り

「AnimStarterPack」→「UE4_Mannequin」→「Mesh」内にある

UE4_Mannequin_Skeleton」を右クリックします。

そして、「別のスケルトンへリターゲットする」をクリック。

f:id:Free_Gamer:20190824055241p:plain

「ThirdpersonCharacter」のスケルト

UE4_Mannequin_Skeleton」を選択し

「リターゲット」します。

f:id:Free_Gamer:20190824055508p:plain

これで、「ThirdpersonCharacter」で

「AnimStarterPack」のアニメーションを使用することが出来ました。

 

 

~CharacterMovementの編集~

「ThirdPersonCharacter」を開きます。

f:id:Free_Gamer:20190824045753p:plain

「CharacterMovement」コンポーネントを選択し

f:id:Free_Gamer:20190824050037p:plain

画面左の詳細パネルにある

「NavMovement」項目にある

「▷MovementCapabilities」の「▷」マークをクリックします。

f:id:Free_Gamer:20190824050101p:plain

すると、各項目が展開されます。

「CanCrouch」にチェックをつけましょう。

f:id:Free_Gamer:20190824050336p:plain

これで、Crouch(しゃがみ)が可能になりました。

 

 

~BPインターフェースの作成~

「Anim_BP_Interface」という名の

BPインターフェースを作成します。

 

f:id:Free_Gamer:20190824050910p:plain

アニメーションBPで使うインターフェースなので

こういう名前にしました。

 

作成した「Anim_BP_Interface」を開き

新規関数「SetPlayer_CrouchingBPI」を作成します。

f:id:Free_Gamer:20190824051053p:plain

引数(インプット)は以下の通り

f:id:Free_Gamer:20190824051144p:plain

 

これでインターフェースの作成は終了です。

 

 

~インターフェースの実装~

「ThirdPersonCharacter」を開き

作成したインターフェース

「Anim_BP_Interface」を追加します。

f:id:Free_Gamer:20190824051729p:plain

 

イベントグラフに、以下の処理を作成します。

f:id:Free_Gamer:20190824051903p:plain

「Qキー」を押した時

Crouch(しゃがみ)をし、アニメーションBPのイベントを呼び出す。

引数Crouchingは「True」

 

もう一度「Qキー」押した時

UnCrouch(しゃがまない)をし、 アニメーションBPのイベントを呼び出す。

引数は「False」

 

これで「ThirdPersonCharacter」の処理は完了です。

 

 

~アニメーションBPの編集~

「ThirdPerson_AnimBP」を開きます。

f:id:Free_Gamer:20190824052627p:plain

 

作成したインターフェース

「Anim_BP_Interface」を追加します。

f:id:Free_Gamer:20190824052825p:plain

 

イベントグラフに以下の処理を作成します。

f:id:Free_Gamer:20190824053013p:plain

「ThirdpersonCharacter」から受け取った値を

変数に格納しています。

 

 

~アニメーションの実装~ 

アニムグラフに

「Crouch」という名のステートを追加します。

f:id:Free_Gamer:20190824053307p:plain

作成した「Crouch」ステートを開き

「Crouch_Idle_Rifle_Hip」アニメーションを追加します。

f:id:Free_Gamer:20190824055907p:plain

 

 

~トランディションルールの作成~

「Idle/Run」ステートと

「Crouch」ステートを繋いで

この2つのアニメーションを遷移させる為のルールを作ります。

f:id:Free_Gamer:20190824060254p:plain

「Idle/Run」→「Crouch」のトランディションルール

f:id:Free_Gamer:20190824060445p:plain

「Crouch」→「Idle/Run」のトランディションルール

f:id:Free_Gamer:20190824060511p:plain

 

最後にコンパイルして完了です。

 

実際にプレイしてみましょう!

youtu.be

 

しっかりしゃがみアニメーションが出来ていましたね!

 

ちなみに・・・

しゃがんだり立ち上がったりするとき

ちょっとカメラが速く動きすぎて気になるかもしれません。

 

そういう時は

「ThirdpersonCharacter」の

「CameraBoom」コンポーネントの詳細パネルにある

「EnableCameraLag」にチェックをつけましょう。

f:id:Free_Gamer:20190824061007p:plain

f:id:Free_Gamer:20190824061018p:plain

これでカメラがスムーズに動くようになります!

 

 

それではまた!^^ノシ

 

プレイヤーが日陰にいるかどうかの判定方法!

レベル内にある

「Light Source」を選択します。

f:id:Free_Gamer:20190815024836p:plain

「Light Source」を選択した状態で

「ブループリント/スクリプトを追加」をクリックします。

f:id:Free_Gamer:20190815025112p:plain

以下のような画面が出てくるので

「BP_Light_Source」をいう名前で

ブループリントを作成します。

f:id:Free_Gamer:20190815025338p:plain

 

 

作成された「BP_Light_Source」を開きます。

f:id:Free_Gamer:20190815025534p:plain

イベントグラフに以下の処理を作成します。

 

f:id:Free_Gamer:20190815031459p:plain
毎フレームライントレースを2つ飛ばしています。

トレース=太陽の紫外線といったところです。

 

プレイヤーの頭の位置から

自身(BP_Light_Source)の正面方向×「-100000」の位置まで

トレースを飛ばしています。

f:id:Free_Gamer:20190815030437p:plain

 

プレイヤーの脚の位置から

自身(BP_Light_Source)の正面方向×「-100000」の位置まで

トレースを飛ばしています。

f:id:Free_Gamer:20190815030612p:plain

 

2つのトレースが障害物にヒットしていればTrue。

プレイヤーに太陽の光がほぼ完全に当たっていないと判定される。

2つのうち1つでもトレースが障害物にヒットしていなければFalse。

プレイヤーに太陽の光が当たっていると判定される。

f:id:Free_Gamer:20190815031742p:plain

 

 

レベル内に障害物を何個か置いて

f:id:Free_Gamer:20190815032607p:plain

 

実際にプレイしてみましょう!

youtu.be

 

画面左上を見れば分かりますが

太陽の光が完全に当たってたり

少しでも当たっていれば「熱い!」と表示され

 

太陽の光がほぼ完全に当たっていないときは「涼しい~」と

表示されています。

 

 

ちょっとマニアックな内容でした~。

 

 

それではまた!^^ノシ

小ネタ!カテゴリー機能の便利な使い方!

皆さんはカテゴリー機能を使ってますか??

f:id:Free_Gamer:20190814005947p:plain

カテゴリーに名前を付けることで

作成した変数や関数、マクロを

分かりやすく管理することが可能です。

 

変数

f:id:Free_Gamer:20190814010402p:plain

f:id:Free_Gamer:20190814010412p:plain

f:id:Free_Gamer:20190814010451p:plain

 

関数

f:id:Free_Gamer:20190814010839p:plain

 

マクロ

f:id:Free_Gamer:20190814010854p:plain

 

さらに、”ある記号”を加えることで

カテゴリー分けをより詳細化させることが出来ます。

 

f:id:Free_Gamer:20190814011241p:plain

「Bool値|First」と入力しています。

「Bool値」と「First」の間に

「|」の記号を入れることで

カテゴリー内に更にカテゴリーを作成することが可能です。

f:id:Free_Gamer:20190814012913p:plain

 

ちなみに「|」は

以下の位置にあるキーです。

f:id:Free_Gamer:20190814012821p:plain

「|」は

「パイプ」「縦棒」「垂直バー」などと呼ばれてるそうで。

 

地味ーな小ネタですが

これを活用することで

大量に作成した変数、関数、マクロを

分かりやすく綺麗に管理する事が可能です!

 

それではまた!^^ノシ

 

 



徘徊!追跡!見失う!いない!徘徊再開!

※注意!

前回の記事「敵のランダムな徘徊方法!」を読んでいること前提で進めます!

free-gamer.hatenablog.com

 

今回は

 

視界に入ったプレイヤーの追跡方法!

見失ったら見失った地点まで移動!

一定時間待機してプレイヤーが見つからなければ徘徊再開!

 

の3本立てでお送りします。

 

 

Enum(列挙体)を作成します。

「Find_or_Lost_Player」と名付けます。

f:id:Free_Gamer:20190810003818p:plain

中身

f:id:Free_Gamer:20190810003830p:plain

この列挙体は

 

プレイヤーを見つけた(Find)か見失った(Lost)か

 

を定義する時に使います。

 

「Enemy_BB」を開きます。

「新規キー」を3つ追加します。

f:id:Free_Gamer:20190810004524p:plain

「Player」(Object型)

f:id:Free_Gamer:20190810004646p:plain

「RandomLocation」(Vector型)

f:id:Free_Gamer:20190810004748p:plain

「Find_Lost」(Enum型)

f:id:Free_Gamer:20190810004800p:plain

 

インターフェースを作成します。

「EnemyInterface」と名付けます。

f:id:Free_Gamer:20190810011613p:plain

「EnemyInterface」を開き

新規インターフェースを2つ作成します。

f:id:Free_Gamer:20190810011829p:plain

「FindPlayerBPI」は、プレイヤーを見つけた時に呼ばれるイベント

「LostPlayerBPI」は、プレイヤーを見失ったときに呼ばれるイベントです。

 

「Enemy_Con」を開きます。

「AIPerception」コンポーネントを追加します。

f:id:Free_Gamer:20190810010035p:plain

「AIPerception」の詳細パネルを以下のように設定します。

f:id:Free_Gamer:20190810010720p:plain

設定方法の詳細は以下のブログに書いています。

↓ご参考に。

qiita.com

 

関数を作成します。

「SetBlackboardValues」と名付けます。

f:id:Free_Gamer:20190810013240p:plain

「SetBlackboardValues」を開き

以下の処理を作成します。

f:id:Free_Gamer:20190810013408p:plain

ブラックボードの指定したキーに

値を格納する為の処理です。

 

「SetBlackboardValues」関数のインプットピン

f:id:Free_Gamer:20190810013554p:plain

こんな感じですね。

f:id:Free_Gamer:20190810024410p:plain


 

 

イベントグラフに

以下の処理を作成します。

f:id:Free_Gamer:20190810004916p:plain

視界に入ったアクターの情報をゲット

「GetActorsPerception」の「InfoTarget」ピンには

視界に入ったアクターが格納されています。

それを変数に格納します。

f:id:Free_Gamer:20190810004953p:plain

プレイヤーが視界に入ったかどうかの判定を行います。

プレイヤーが視界に入ったらTrue

プレイヤーが障害物で遮られたらFalse

f:id:Free_Gamer:20190810005032p:plain

↓プレイヤーが障害物で遮られたかどうかの判定は以下のノードでできます。

f:id:Free_Gamer:20190810005529p:plain

対象のアクターが障害物で遮られてない場合

視界から外れていてもTrue

対象のアクターが障害物で遮られたらFalse

といった感じです。

 

ブランチで判定を行った後は

自作関数「SetBlackboardValues」内に格納します。

f:id:Free_Gamer:20190810005724p:plain

Trueに繋がる処理

「SetBlackboardValues」関数で値を格納しています。

その後、「FindPlayerBPI」で「Enemy_Con」を所有している

「Enemy」のイベントを呼び出しています。

f:id:Free_Gamer:20190810011050p:plain

Falseに繋がる処理

SequenceノードでDoOnceにResetの処理をかけてから

「SetBlackboardValues」関数に値を格納しています。

f:id:Free_Gamer:20190810011138p:plain

 

「Enemy_BT」を開きます。

「新規タスク」を作成します。

f:id:Free_Gamer:20190810012455p:plain

新規作成されたタスクに

「VigilanceAround_BT_Task」と名付けます。

f:id:Free_Gamer:20190810012706p:plain

「VigilanceAround_BT_Task」を開き

以下の処理を作成します。

f:id:Free_Gamer:20190810012839p:plain

変数

f:id:Free_Gamer:20190810012934p:plain

 WaitDuration・・・後から編集しやすいように編集可能に。

 

「Enemy_BT」を開きます。

以下の処理を作成します。

左側から見ていきましょう。

f:id:Free_Gamer:20190810014031p:plain

徘徊処理です。

 

f:id:Free_Gamer:20190810014322p:plain

プレイヤーを見つけていない(Lost)状態だと

「Enemy」はランダムな位置に移動し続け徘徊する。

これは前回のブログ「敵のランダムな徘徊方法!」でやった内容通りでしょう。

けど1つ違うのは

Sequenceノードに「Blackboardデコレーター」が追加されているところです。

 

この「Blackboardデコレーター」の詳細パネルは以下の通り。

f:id:Free_Gamer:20190810014828p:plain

オブザーバーを中止を「Self」にしています。

「Self」にすることで

徘徊途中でプレイヤーを見つけた時

即座に徘徊処理を中止できます。

 

KeyQueryは「IsEqualTo」

KeyValueは「Lost」

BlackboardKeyは「Find_Lost」

にしてます。

 

要は

 

プレイヤーを見つけてない(Lost)した状態なら

徘徊処理を実行する

 

という感じです。

 

プレイヤーを追跡する処理です。

徘徊処理が中断されると、この処理が実行されます。

f:id:Free_Gamer:20190810015602p:plain

「MoveTo」ノードで

プレイヤーの位置まで移動という感じです。

 

この処理の「Blackboardデコレーター」の詳細パネルを以下のように設定します。

f:id:Free_Gamer:20190810015916p:plain

オブサーバーを中止を「Both」にしています。

理由は・・・
説明したいところですが自分でもはっきりわかっていないので
悔しくも割愛します・・・。すいません・・・。

 

KeyQueryは「IsEqualTo」

KeyValueは「Find」

BlackboardKeyは「Find_Lost」

 

つまり

 

プレイヤーを見つけた(Find)ら

追跡処理を実行する。

 

といった感じです。

 

「MoveTo」ノードの詳細パネルです。

「Player」の位置まで移動させたいので

BlackboardKeyを「Player」にしています。

f:id:Free_Gamer:20190810020332p:plain

 

プレイヤーを見失ったときの処理です。

f:id:Free_Gamer:20190810020534p:plain

「MoveTo」ノードで

プレイヤーを見失った位置まで移動します。

 

その後、作成したタスク「VigilanceAround_BT_Task」で

「WaitDuration」に入れた値分その場で待機。

プレイヤーが見つからなければ

この処理は成功(終了)し

また徘徊処理に戻る。

 

といった感じです。

 

この処理の「Blackboardデコレーター」の詳細パネルを以下のように設定します。

f:id:Free_Gamer:20190810021555p:plain

オブサーバーを中止を「None」に。

 

KeyQueryは「IsEqualTo」

KeyValueは「Lost」

BlackboardKeyは「Find_Lost」

 

つまり

 

プレイヤーを見失った(Lost)とき

この処理を実行する

 

といった感じです。

 

「MoveTo」ノードの詳細パネルです。

プレイヤーを見失った地点まで移動させたいので

BlackboardKeyを「LostPlayerLocation」にします。

f:id:Free_Gamer:20190810021933p:plain

 

「VigilanceAround_BT_Task」タスクの詳細パネルです。

WaitDurationの値を「5」に設定します。

これで、プレイヤーを見失った地点に到達した後

「5秒間」その場で待機することになります。

f:id:Free_Gamer:20190810022202p:plain

 

「Enemy」を開きます。

イベントグラフに以下の処理を作成します。

徘徊する時と追跡する時で

移動速度を変えています。

f:id:Free_Gamer:20190810022559p:plain

変数

f:id:Free_Gamer:20190810022906p:plain
NormalSpeed・・・徘徊速度。デフォルト値は「180」

ChaseSpeed・・・追跡速度。デフォルト値は「500」

 

これですべて完了です!

 

レベル内に障害物を何個か置いて・・・

f:id:Free_Gamer:20190810023433p:plain

 

さっそくプレイしてみましょう!

youtu.be

 

徘徊時は、ランダムな位置に移動。

移動速度は遅め。

 

プレイヤー追跡時は

移動速度が速くなる。

発見したか分かりやすいように

赤いSphereが見つかった地点に表示されるはずです。

 

プレイヤーを見失ったときは

見失った地点まで移動。

見失ったか分かりやすいように

見失った地点に

青いSphereが表示されるはずです。

 

一定時間後

プレイヤーがいなければ

再び徘徊。

 

といった感じです。

 

くssssssっそ長くてだるかったと思いますが

何も考えずにただやり方をトレースするだけでも

普通に出来るはずです。(説明不足とかなきゃ)

 

ここまで読んでくれてありがとうございますw

 

それではまた!^^ノシ