敵のランダムな徘徊方法!

~今回やりたい事~

・敵をうろうろ徘徊させる!!

 

以上!!(上から目線)

 

 

「ThirdPersonCharacter」をコピーし

コピーした奴に「Enemy」と名付けます。

f:id:Free_Gamer:20190808181630p:plain

 

「Enemy」を動かすためのコントローラー

「AIController」を作成します。

f:id:Free_Gamer:20190808182020p:plain

「Enemy_Con」と名付けます。

 

ビヘイビアツリー・ブラックボードを作成します。

ビヘイビアツリーには「Enemy_BT」

ブラックボードには「Enemy_BB」と名付けました。

f:id:Free_Gamer:20190808182447p:plain

 

「Enemy_Con」を開き

以下の処理を組みます。

f:id:Free_Gamer:20190808184154p:plain

これでブラックボードとビヘイビアツリーの使用が可能になります。

 

「Enemy_BB」を開きます。

Vector」型のキーを追加します。

「RandomLocation」と名付けました。

f:id:Free_Gamer:20190809115954p:plain

 

「Enemy_BT」を開きます。

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

f:id:Free_Gamer:20190809120211p:plain

コンテンツブラウザに作成された新規タスクがあるので

「RandomMove_BT_Task」と名付けます。

f:id:Free_Gamer:20190809120346p:plain

 

「RandomMove_BT_Task」を開きます。 

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

f:id:Free_Gamer:20190809121136p:plain
変数

f:id:Free_Gamer:20190809120600p:plain

後から編集しやすいように「MoveRadius」を編集可能に。

「RandomLocation」は絶対編集可能に。

じゃないと動きません。

 

「Enemy_BT」を開きます。

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

f:id:Free_Gamer:20190809121519p:plain

「RandomMove_BT_Task」を選択し

画面右側にある詳細パネルを以下のように設定します。

f:id:Free_Gamer:20190809121621p:plain

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

f:id:Free_Gamer:20190809121714p:plain

 

 

ビューポートに戻ります。

AIを動かすための領域

「NavMeshBoundsVolume」をレベル内に配置します。

f:id:Free_Gamer:20190809121846p:plain

 

「NavMeshBoundsVolume」の大きさを

「20」ぐらいに設定します。

f:id:Free_Gamer:20190809122334p:plain

この箱の中を十分に覆いつくすぐらいの大きさですね。

f:id:Free_Gamer:20190809122422p:plain

「P」キーを押すと

AIの動ける範囲が緑色で表示されます。

 

「Enemy」を開きます。

f:id:Free_Gamer:20190808181630p:plain

「クラスのデフォルト」の詳細パネルの

「Pawn」項目内にある

「AI ControllerClass」を「Enemy_Con」に設定します。

f:id:Free_Gamer:20190809122828p:plain

f:id:Free_Gamer:20190809122907p:plain

これで「Enemy」は

「Enemy_Con」によって操作されるようになりました。

 

 

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

youtu.be

 

うろうろうろうろ目障りなぐらいに移動してますね!^^

 

ちなみに

「RandomMove_BT_Task」の

「MoveRadius」の値を「5000」にすると

「Enemy」の移動距離が伸びます。

f:id:Free_Gamer:20190809124008p:plain

 

逆に「100」とか小さい数値にすると

移動距離が少なくなります。

 

いろいろいじって遊んでみてください^^

 

それではまた!^^ノシ

 

 

カメラの向きに上限を設定する方法!

とある理由で

 

カメラの向きに上限を設けたい!

 

と思ったとします。

 

例えば

 

カメラの上下方向(Pitch)に「45度」の上限を設けるとします。

 

↓その場合、以下の処理を組みましょう。

f:id:Free_Gamer:20190804221355p:plain

レベルBPでもキャラクターBPでもどちらでもいいので

この処理を組みます。

 

これで、カメラの上下方向(Pitch)に「45度」の上限を設けることが出来ました。

f:id:Free_Gamer:20190804222205p:plain

実際にプレイしてみると

カメラを上下に向けた時

一番上(90度)・一番下(‐90度)までは見えません。

 

上方向には「45度」

下方向には「‐45度」

 

までしか見えないはずです。

 

 

左右方向(Yaw)にも上限を設けることが可能です。

 

極端に「10度」の上限を設定してみましょう。

f:id:Free_Gamer:20190804224007p:plain

f:id:Free_Gamer:20190804224105p:plain

これでカメラの左右方向(Yaw)に「10度」の上限を設けることが出来ました。

 

カメラを左に向けると

「‐10度」に達したところで

それ以上カメラは左に向きません。

 

カメラを右に向けると

「10度」に達したところで

それ以上カメラは右に向きません。

 

カメラの向きに上限を設けたいと思ってる人はぜひ参考に!

 

それではまた!^^ノシ

 

 

プレイヤー(自分)が敵の正面/背面どちらに立っているかを判定する方法!

レベルBPを開きます。

 

以下のような処理を組みます。

f:id:Free_Gamer:20190729225315p:plain

Qキーを押した時、自分が敵の正面にいるか背面にいるかを判定する処理です。 

 

 

それでは解説していきます。

 

 

f:id:Free_Gamer:20190729225349p:plain

 

敵の前面ベクトルと位置を取得

プレイヤーの位置も取得しています

f:id:Free_Gamer:20190729225424p:plain

↓上から見るとこんな感じですね

 

f:id:Free_Gamer:20190729224344p:plain

赤枠が敵

青枠がプレイヤー

赤矢印が敵の前面ベクトルです。

 

敵の位置と自分の位置から角度を割り出します。

f:id:Free_Gamer:20190729225533p:plain

↓上から見た図です

f:id:Free_Gamer:20190729230716p:plain

この場合、FindLookAtRotationから返される値は
おおよそ「Pitch:135」といったところじゃあないでしょうか。

 

そして、FindLookAtRotationの返した角度を

GetForwardVectorで正規化します。

 

例えば、FindLookAtRotationから返された値が「Pitch:90」だった場合

その値を正規化したら「Y:1」になります。

「Pitch:-90」だった場合は

「Y:-1」です。

 

角度が正の値だった場合正規化される値は「正の値の1」

角度が負の値だった場合正規化されえる値は「負の値の1」

 

になるわけです。

f:id:Free_Gamer:20190729232036p:plain

この場合、正規化された値は、

「X:-0.765362 Y:0.643600」ぐらいです。

 

敵の前面ベクトルと

FindLookAtRotationで求めた角度を正規化した値から

内積を求めます。

 

内積を求めたら

ACOSとかいうよくわからんノード

角度を求めます。(適当w)

f:id:Free_Gamer:20190729232704p:plain

赤矢印が敵の前面ベクトル

黄色矢印がFindLookAtRotationで求めた角度の正規化したベクトル

 

この2つで内積を求める。

そして求めた内積で角度を割り出す。

 

緑色で塗りつぶされているのが角度。

この場合だと、大体「45度」ぐらい。

f:id:Free_Gamer:20190729233245p:plain

 

角度によって正面か背面かを判定

f:id:Free_Gamer:20190729223815p:plain

ACOSdから返された値をInRangeのValueに繋ぐ。

角度が「0~90」だった場合、敵の正面にいると判定

それ以外は背面と判定されるようになっている。

 

これで完了です。

 

それではまた!^^ノシ

 

 

プレイヤー(自身)と最も近い敵にアイコン(UMG)を表示させる方法!

プレイヤー(自身)と最も近い敵に
アイコン(UMG)を表示させる方法!

 

を今回は紹介します。

 

↓最終的な出来としては以下のようになります。

youtu.be

 

※サードパーソンテンプレートを使用します

 

~敵の作成~

コンテンツフォルダ>ThirdPersonBP>Blueprintフォルダの中にある
「ThirdPersonCharacter」をコピーし、

コピーしたやつに「Enemy」という名前を付けます。

f:id:Free_Gamer:20190728014904p:plain

 

 

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

「MyInterface」という名前のBPインターフェースを作成。

f:id:Free_Gamer:20190728015109p:plain

 

「MyInterface」開き

「SetUMGVisibilityBPI」という名のインターフェースを作成します。

f:id:Free_Gamer:20190728015354p:plain

インプット

f:id:Free_Gamer:20190728015547p:plain

 

~ThirdPersonCharacterにコンポーネントを追加~

「ThirdPersonCharacter」を開きます。

 

Sphereコンポーネントを追加します。

f:id:Free_Gamer:20190728015950p:plain

SphereRadiusを「225」にします。

f:id:Free_Gamer:20190728020124p:plain

 

~変数の作成~

f:id:Free_Gamer:20190728020743p:plain

デフォルト値の編集は特に無し。

 

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

オーバーラップイベントを使います。
f:id:Free_Gamer:20190728020302p:plain

 

Beginオーバーラップイベントです。

f:id:Free_Gamer:20190728021002p:plain

オーバーラップしたアクターがタグ持ちだった場合、配列に加える処理です。

配列に加えた後、タイマーイベントを開始しています。

このタイマーイベントは、自身に最も近い敵を算出する為のイベント「FindClosestEnemy」を、指定秒数間隔で呼び出しています。

 

「ActorIsValid」は自作マクロです。

f:id:Free_Gamer:20190728021151p:plain

中身はこうです。

f:id:Free_Gamer:20190728021205p:plain

 

Endオーバーラップイベントです。

f:id:Free_Gamer:20190728021649p:plain

 

f:id:Free_Gamer:20190728021759p:plain

f:id:Free_Gamer:20190728021821p:plain

f:id:Free_Gamer:20190728021833p:plain

f:id:Free_Gamer:20190728021847p:plain

f:id:Free_Gamer:20190728021910p:plain

f:id:Free_Gamer:20190728021931p:plain

 

タイマーで呼び出せれているイベント

「FindClosestEnemy」の処理を作成します。

f:id:Free_Gamer:20190728022235p:plain

 

カスタムイベント「FindClosestEnemy」が呼び出された時

オーバーラップしたアクターが格納されてる配列「OverlapEnemys」に

「1つ」以上アクターが格納されていればTrue。

f:id:Free_Gamer:20190728022249p:plain

 

自身の位置とSphereコンポーネントRadiusを変数に格納

f:id:Free_Gamer:20190728022524p:plain

 

ループ処理を行います。

f:id:Free_Gamer:20190728022626p:plain

 

↓LoopBodyに繋がる処理です。

トレース処理

f:id:Free_Gamer:20190728022652p:plain

 

自身と敵の距離を測定

f:id:Free_Gamer:20190728025657p:plain

 

トレースがヒットした時

自身と敵との距離を変数に格納します。

そして、ForEachLoopの「ArrayElement」を変数「TempFrontEnemy」に格納します。

f:id:Free_Gamer:20190728022808p:plain


↓Compleateに繋がる処理です。

ここはもうちょっと上手くコメントを書いて、説明したかったのですが

個人的にここの説明はなかなか難しかったので

単純に「AとBが不一致ならTrue」という雑な説明になってます。すいません・・・。

f:id:Free_Gamer:20190728022913p:plain

 

インプット値のVisibilityがFalseになってるインターフェースのターゲットを変数「Enemy」と繋げる。

Trueになってる方のターゲットは、変数「TempFrontEnemy」と繋げる。

f:id:Free_Gamer:20190728023050p:plain

変数「TempFrontEnemy」を変数「Enemy」にセット。

その後、変数「TempFrontEnemy」を空にする。

f:id:Free_Gamer:20190728023253p:plain

 

これでThirdPersonCharacterの編集は終わりです。

 

~アイコン(UMG)の作成~

「Takedown」という名のUMGを作成。

f:id:Free_Gamer:20190728023635p:plain

 

「Takedown」UMGの中身はこんな感じです。

f:id:Free_Gamer:20190728023710p:plain

f:id:Free_Gamer:20190728024020p:plain

正直各パネルの使い方がこれで正しいかどうかは分かりませんw

UMGは滅法詳しくないので。

Overlayの使い方もこれでいいのかさっぱりw

 

SizeBoxの詳細パネル

f:id:Free_Gamer:20190728024310p:plain

Textの詳細パネル

f:id:Free_Gamer:20190728024322p:plain

 

UMGはこれで終わりです。(適当)

 

 

~敵にコンポーネントを追加~
「Enemy」を開きます。

f:id:Free_Gamer:20190728024508p:plain

 

Widgetコンポーネントを追加

f:id:Free_Gamer:20190728024716p:plain

Widgetコンポーネントの詳細パネルで

「Space」を「Screen」にします。

「WidgetClass」を作成したUMG「Takedown」にします。

f:id:Free_Gamer:20190728024818p:plain

Widgetコンポーネントの位置は、「Z:90」で。

 

~イベントグラフ~

非常に単純です。

ゲーム開始時、Widgetコンポーネントを非表示

ThirdPersonCharacterから

「SetUMGVisibilityBPI」イベントが呼び出された時

Widgetコンポーネントの表示/非表示を行います。

f:id:Free_Gamer:20190728024558p:plain


これで完了です。

 

これで、一番最初にお見せした動画のようになるはずです。

 

それではまた!^^ノシ







 

 

風を起こして物を飛ばそう!

今回は

 

風を巻き起こして

物を吹き飛ばす方法!

 

を紹介します!

 

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

 

~BPインターフェース~

「MyInterface」という名前にしました。

f:id:Free_Gamer:20190702230051p:plain

「AddImpulseActorBPI」という名のインターフェースを作成。

物を吹き飛ばすイベントとして扱います。

f:id:Free_Gamer:20190702230101p:plain

f:id:Free_Gamer:20190702230119p:plain

 

~BP_Wind~

f:id:Free_Gamer:20190702230720p:plain

コンポーネント

f:id:Free_Gamer:20190702224759p:plain

WindArea

f:id:Free_Gamer:20190702224958p:plain

WindDirection

f:id:Free_Gamer:20190702225019p:plain

f:id:Free_Gamer:20190702224834p:plain

 

変数

f:id:Free_Gamer:20190702225540p:plain

WindLength・・・デフォルト値「1000」

WindArea・・・Boxコリジョンコンポーネント

WindDirection・・・Arrowコンポーネント

 

イベントグラフ

f:id:Free_Gamer:20190702225757p:plain

 

WindAreaコンポーネントの詳細パネルで

「HiddenInGame」のチェックを外しましょう。

WindAreaの範囲を可視化する為です。

f:id:Free_Gamer:20190702231546p:plain

 

 

~吹き飛ばすアクターの作成~

「BP_SimulatePhysicsObject」という名前にしました。

f:id:Free_Gamer:20190702230247p:plain

コンポーネント

f:id:Free_Gamer:20190702231018p:plain

f:id:Free_Gamer:20190702231027p:plain

 

※作成したインターフェースを追加するのを忘れずに。

f:id:Free_Gamer:20190702231258p:plain

 

コンストラクションスクリプト

SimulatePhysicsをONにします。

f:id:Free_Gamer:20190702233025p:plain

 

イベントグラフ

BP_Windから受け取った値(Impulse)分、吹き飛ばすアクターに衝撃を与えます。

f:id:Free_Gamer:20190702230459p:plain

 

 

~BP_Windをレベルに配置~

f:id:Free_Gamer:20190702231631p:plain

これだと範囲が小さすぎるので

スケールを

 

「X:12 Y:3.5 Z:3.5」

 

にしましょう。

f:id:Free_Gamer:20190702231848p:plain

Arrowコンポーネントが引き伸ばされてちょっと目障りですね。

なので・・・

 

アクターの大きさに影響されずに

Arrowコンポーネントだけ常にデフォルトのサイズ

なるようにしましょう。

 

BP_Windを開き、

ConstructionScriptに以下の処理を組みます。

f:id:Free_Gamer:20190702232331p:plain

X,Y,Z「1」に

自身のアクターのサイズ(X,Y,Z)を割ることで

Arrowコンポーネントのサイズを

常にデフォルトのサイズに設定するようにしています。

 

コンパイルし、確認すると・・・

f:id:Free_Gamer:20190702232741p:plain

Arrowコンポーネントのサイズがアクターのサイズに影響されず

デフォルトのままを保ってるのが分かります。

 

BEFOR

f:id:Free_Gamer:20190702232842p:plain

AFTER

f:id:Free_Gamer:20190702232638p:plain

一目瞭然ですね。

 

~吹き飛ばすアクターの配置~

作成した「BP_SimulatePhysicsObject」の子BPを作成します。

f:id:Free_Gamer:20190702233248p:plain

 

とりあえず

2つの子BPを作成しましょう。

f:id:Free_Gamer:20190702233710p:plain

Chair(椅子)とTable(机)です。

 

StaticMeshコンポーネントにメッシュを追加しましょう。

f:id:Free_Gamer:20190703000356p:plain

 

Chair

f:id:Free_Gamer:20190702234219p:plain

Table

f:id:Free_Gamer:20190702234235p:plain

 

レベルに配置します。

f:id:Free_Gamer:20190702234324p:plain

当然、Boxコリジョンの中に入れるように配置しましょう。

 

いざ、プレイ!

youtu.be

 

よく吹き飛んでいますね!^^

「BP_Wind」で編集可能にしてある

「WindLength」の値を更に大きくすれば

もっと勢いよく吹き飛んでくれます。

 

それではまた!^^ノシ

Findノードとは何か!?

Findというノードがあります。

f:id:Free_Gamer:20190530213654p:plain
これは、

Bの値が、

Aの配列内にある値と

一致するものがあれば

一致した値の

インデックス値を返す

 

ノードです。

 

 

例えば・・・

Name(名前)型の配列変数

普通の変数を用意し、

画像のようにします。

f:id:Free_Gamer:20190530213633p:plain
TestArray・・・配列

TestName・・・普通の変数

 

↓配列内はこんな感じに。

f:id:Free_Gamer:20190530211151p:plain

 

普通の変数には、

配列内にある

いずれかの値(文字)を入れます。

f:id:Free_Gamer:20190530212917p:plain

例えば、「木」にしましょう。

 

これでプレイすると・・・

f:id:Free_Gamer:20190530211740p:plain

f:id:Free_Gamer:20190530211754p:plain

 

「3」と表示されるはずです。

 

 

何故なら、

配列内には「木」という値がある。

f:id:Free_Gamer:20190530211949p:plain

普通の変数に入れた値は「木」

f:id:Free_Gamer:20190530213755p:plain

「木」という値が一致したので、

一致したインデックス値は「3」を返す。

という感じです。

 

 

ちなみに・・・

 

普通の変数の値が、

配列内にある値と

何も一致しなかった場合

果たしてFindノードは

いくつのインデックス値を

返すでしょうか??

 

答えは「-1」です。

 

一致するものが無い場合、

Findノードは

「-1」を返します。

 

試しに、普通の変数に配列内には無い

全く関係ない値を入れましょう。

f:id:Free_Gamer:20190530214428p:plain

 

これでプレイすれば・・・

f:id:Free_Gamer:20190530214531p:plain

f:id:Free_Gamer:20190530214550p:plain

 

「鼻くそ」

配列内には無いので、

「-1」を返します。

 

今回はここまで!それではまた!^^ノシ
 

 

 

魚眼レンズの実装方法! 『あるもの』を使えば   簡単に実装可能!

P.T.

 

というホラーゲーム、ご存知でしょうか?

 

f:id:Free_Gamer:20190509235307j:plain

あのMGSで有名な小島監督が作った

ホラーゲームです。

知らない人はggってね。

 

さて、このP.T.。恐怖を掻き立てる為に

色々な要素や演出が

盛り込まれているのですが・・・

 

その恐怖を掻き立てる要素の一つに・・・

 

魚眼レンズ

 

があるのです。

 

よく見てみると・・・

 

右側の壁の輪郭が

若干曲線になってるのが

分かりますでしょうか??

f:id:Free_Gamer:20190509235737j:plain

曲線が分かりやすくなるように、

近くに赤い真っ垂直な赤線を引きました。

魚眼レンズの影響で

外側の物体が反っているのが

分かると思います。

f:id:Free_Gamer:20190510000141p:plain

 

今回はその

 

魚眼レンズの

実装方法

 

を紹介します!

 

そのためには

必ず必要なものがあります!

 

それは・・・

 

↓このアセットです!

f:id:Free_Gamer:20190510000843p:plain

この

 

「ChameleonPostProcess」

 

というアセットは、

ポストプロセスを使って、

画面にあらゆるエフェクトを

掛けることが出来るアセットです。

(2019年5月中はずっと無料です。タダで手に入れるなら今!)

 

UE4に最初っから備わっている

ポストプロセスマテリアルの拡張版

といった感じの解釈でいいと思います。

 

このアセットを使えば、

魚眼レンズを

秒で作れます!

 

 

「ChameleonPostProcess」を

プロジェクトに追加。

 

コンテンツフォルダに

「Chameleon」

というフォルダがあるので、

それをダブルクリック。

f:id:Free_Gamer:20190510002058p:plain

「Chameleon」という名のBPがあるので、

f:id:Free_Gamer:20190510002313p:plain

それをレベル内にD&D(ドラッグアンドドロップ

f:id:Free_Gamer:20190510002441p:plain

 

レベル内に置いた

「Chameleon」を選択し、

詳細パネルにある

「MonitorEffects」という項目を

見つけましょう。

f:id:Free_Gamer:20190510002624p:plain

 

「MonitorEffects」

チェックを入れると・・・

f:id:Free_Gamer:20190510002959p:plain

モニター画面風になります。

この時点でもう魚眼レンズになっています。

f:id:Free_Gamer:20190510003038p:plain

 

ですが、

 

画面にかかってる

モニター風の

細かいラインが邪魔!

 

という場合は・・・

 

「MonitorEffectsLineCount」の値を

「1000」から「0」にすれば・・・

f:id:Free_Gamer:20190510003554p:plain

ラインが「0」本になって、

完全に消えます。

f:id:Free_Gamer:20190510003635p:plain

 

ただ、このままだと

全体が緑に染まっていて、

気になりますね。

 

これを無くす場合は・・・

「MonitorEffectsIntensity2」

の値を、「0」にします。

f:id:Free_Gamer:20190510005251p:plain

はい。

これで魚眼レンズの完成です。簡単でしょう??

f:id:Free_Gamer:20190510005404p:plain

 

更に、

 

魚眼レンズによる

画面の「反り」

 

を調整したい場合は・・・

 

「MonitorEffectsDistortion2」の値を

調整すれば変更可能です。

f:id:Free_Gamer:20190510010511p:plain

 

値「1」

かなり反っています

f:id:Free_Gamer:20190510010651p:plain

値「0」

全く反らない。

もはや魚眼じゃない。

f:id:Free_Gamer:20190510010730p:plain

 

 

 

 

P.T.のような、魚眼レンズで

臨場感と恐怖感を掻き立てるような

ホラーゲームを作りたい場合には、

役に立つ内容だと思います!

 

それではまた!^^ノシ