GetHorizontalDotProductToとは??
今回「GetHorizontalDotProductTo」という
気になるノードを見つけたので
どういうノードなのかを解説します。
このノードは
OtherActorが、ターゲットの前面・後面のどちら側にいるのかを
「1」~「-1」の値で返してくれます。
・・・よくわかんないですよね。すいません。
とりあえず実際に使ってみましょう!
~OtherActorの作成~
「ThirdpersonCharacter」をコピーし
「OtherActor」という名前を付けます。
「OtherActor」を以下のようにレベルに配置します。
「ThirdpersonCharacter」と平行な位置に配置します。
~レベルBPの編集~
レベルBPを開き
イベントグラフに以下の処理を作成します。
「Qキー」を押した時
GetHorizontalDotProductToの返す値を表示します。
実際にプレイしてみましょう。
ほぼ「0」に近い数字が返されましたね。
今度は「ThirdpersonCharacter」の向きを
「OtherActor」の方向に向けます。
これでプレイしてみましょう。
今度は「1」が返ってきました。
どういう条件で値が返されるかというと・・・
上から見た図です。
ターゲット(ThirdpersonCharacter)の前面に
OtherActorがいる場合「1」を返す。
ターゲット(ThirdpersonCharacter)の後面に
OtherActorがいる場合「-1」を返す。
というノードなのです!
なので、ターゲット(ThirdpersonCharacter)の真横に
OtherActorがいた場合は
「0」に近い値を返す
といった感じになります。
この「GetHorizontalDotProductTo」ノードを使えば
OtherActorがプレイヤーの前面・後面どちらにいるのかを
簡単に判定できます。
お役に立てれば幸いです。
それではまた!^^ノシ
ポーズ画面の実装!
今回は
ポーズ画面の実装!
方法を紹介します。
今回紹介する方法は
普段自分がやっている方法とは違うのですが
UE4初心者もこの記事を見るかもしれないので
あえて自分が普段やっている方法とは違う
(個人的に)至ってシンプルな方法を紹介します。
UE4初心者の方を混乱させないためです。
(とはいえ自分もUMGは初心者みたいなものですがw)
あと、UMGの作成の解説がクソみたいに長く
ごちゃごちゃしてるかもしれませんが
とりあえず画像の通りやれば出来るはずなので
落ち着いてやりましょう!w
実装したい事
・「Pキー」を押した時、ポーズ画面を出す。
・ポーズ中、「Pキー」を押した時、あるいは「Return(ゲームに戻る)」ボタンを
クリックした時、ポーズを解除する。
~インターフェースの作成~
「UI_Interface」という名の
BPインターフェースを作成
「UI_Interface」を開き
新規関数「OnPauseBPI」を作成
引数(インプット)
~ポーズUMGの作成~
「Pause」という名の
UMGを作成
以下の通りに
UMGを作成します。
階層は以下の通りです。
各パネルについて
上から順に説明していきます。
「Overlay」
パレットの「パネル」項目内にあります。
「Overlay」を
階層の親である
「CanvasPanel」の子として追加します。
「CanvasPanel」から少し右にズレて
追加されるはずです。
「Overlay」が
親である「CanvasPanel」の子として
追加された証拠です。
追加した「Overlay」のアンカーを
「画面全体」にします。
「Overlay」の
「左オフセット」
「上オフセット」
「右オフセット」
「下オフセット」
を全て「0」にします。
これでUMGの画面四隅に
赤枠で囲ってある白いビックリマークのようなものがあれば
OKです。
「SizeBox」
パレットの「パネル」項目内にあります。
「SizeBox」を
「Overlay」の子として追加します。
これで、「SizeBox」の子のサイズを
好きなように変えることが出来ます。
さっそく「SizeBox」で
サイズを指定しましょう。
「SizeBox」の詳細パネルを
以下のように設定します。
「スロット」項目内にある
「HorizontalAlignment(水平方向の配置)」
と
「VerticalAlignment(垂直方向の配置)」
を、真ん中に設定。
「ChildLayout」項目内にある
「WidthOverride(横幅)」を「500」
「HeightOverride(立幅)」を「200」
に設定。
これでサイズを設定することが出来ました。
「ScaleBox」
パレットの「パネル」項目内にあります。
「ScaleBox」を
「SizeBox」の子として追加します。
「ScaleBox」を入れることによって
「SizeBox」の数値に合わせて
「ScaleBox」が子のサイズを拡大縮小させてくれます。
ちょっとよくわからない??
という方はこの動画が分かりやすい・・・はず・・・です・・・
「VerticalBox」
パレットの「パネル」項目内にあります。
「VerticalBox」を
「ScaleBox」の子として追加します。
「VerticalBox」の詳細パネルを
以下のように設定します。
スロット項目内にある
「HorizontalAlignment(水平方向の配置)」
を横全体
「VerticalAlignment(垂直方向の配置)」
を、真ん中に設定。
「Text」
パレットの「一般」項目内にあります。
「Text」を
「VerticalBox」の子として追加します。
「Text」の詳細パネルを
以下のように設定します。
「スロット」項目内にある
「HorizontalAlignment(水平方向の配置)」
を真ん中
「VerticalAlignment(垂直方向の配置)」
を、縦全体に設定。
「Content」項目内の
「Text」内に「Pause」と入れましょう。
「Button」
パレットの「一般」項目内にあります。
「Button」を
「VerticalBox」の子として追加します。
追加した「Button」に
「ReturnButton」と名付けます。
ポーズ画面を解除する為のボタンという事です。
「Text」を
「ReturnButton」の子として追加します。
「Text」の詳細パネルを
以下のように設定します。
スロット項目内にある
「Padding」を「0」
「Content」項目内の
「Text」内に「Return」と入れましょう。
「Button」を
「VerticalBox」の子として追加します。
追加した「Button」に
「ExitButton」と名付けます。
ゲームを終了する為のボタンという事です。
「Text」を
「ExitButton」の子として追加します。
「Text」の詳細パネルを
以下のように設定します。
スロット項目内にある
「Padding」を「0」
「Content」項目内の
「Text」内に「Exit」と入れましょう。
これでUMGの作成は終了です。
~ポーズUMGのイベントグラフ作成~
関数「PauseSwitch」を作成
「PauseSwitch」の中身は
以下の通り
Trueに繋がる処理
ゲームをポーズする処理です。
Falseに繋がる処理
ポーズを解除する処理です。
作成したBPインターフェース
「UI_Interface」を追加
イベントグラフに以下の処理を
作成します。
以下の処理は
各ボタンがクリックされた時のイベントです。
「ReturnButton」がクリックされた時
「PauseSwitch」関数を呼び出す。
引数「Pause」は「False」で。
「ExitButton」がクリックされた時
ゲームを終了します。
「Pキー」が押された時
ポーズ画面を表示したり
非表示にしたりする処理です。
~ThirdpersonCharacterのイベントグラフの作成~
「ThirdpersonCharacter」を開き
以下の処理を作成します。
作成した「Pause」UMGのリファレンスを取得
「Pキー」が押された時
ゲームがポーズ状態か判定
「Pキー」押した時
ポーズ状態なら、「Pause」UMGにあるBPインターフェースイベント
「OnPauseBPI(引数『False』)」を呼び出す。
ポーズ状態でなければ、「Pause」UMGにあるBPインターフェースイベント
「OnPauseBPI(引数『True』)」を呼び出す。
これでプレイしてみましょう!
(何故か動画だとマウスカーソルが出ていませんがお気にせず)
「Pキー」を押したら
しっかりポーズ画面が表示されて
「Return」ボタンを押したら
しっかりゲーム画面に戻ってましたね!
・・・しかし、1つ問題があるのに気が付いたでしょうか??
「Pキー」を押してポーズ画面が表示されるのはいいのですが
もう一度「Pキー」を押してもポーズ画面が消えてくれません。
どうすればいいのか??
「Pキー」を選択し
詳細パネルの「ExecuteWhenPaused」にチェックを入れれば解決です!
どうやらゲームがポーズされると
キー入力を受け付けなくなるようです。
しかし、「ExecuteWhenPaused」にチェックを入れれば
ゲームがポーズされていても
キー入力を受け付けてくれるのです!
という事でもう一度プレイ!
今度は、「Pキー」を押した時と「Return」ボタンを押した時に
ポーズ画面を消すことが出来てますね!
今回はくsssssっそ長くなりましたが
画像通りにやっていけば出来るはずですw
分からないこと・抜けてると思われる所があれば遠慮なく
Twitterhttps://twitter.com/Demonskiller5までDMなりなんなりください!
それではまた^^ノシ
しゃがみから立ち上がれるかどうかをチェックする方法!
※前回の記事の続きとして紹介してるので
前回の記事を読んでから見ることをお勧めします。
前回の記事で
しゃがみアニメーションの方法を書きました。
しゃがむことが出来るのは良いのですが
1つ問題があります。
どういう問題かというと・・・
もしここで立ち上がろうとしたら・・・
・
・
・
普通に立ち上がれてしまうのです!
思いっきり貫通してしまって
明らかにおかしいことになってしまいますよね!w
今回はそのようなことが起きないように
しゃがみから立ち上がれるかどうかをチェックする方法!
を紹介します!
~イベントグラフの作成~
「ThirdpersonCharacter」を開き
イベントグラフに以下の処理を作成します。
「Qキー」を押した時
立ち上がり可能か判定
FlipFlopの「A」に繋がる処理
インターフェース「SetPlayer_CrouchingBPI」を呼び出した後
カスタムイベント「CanPlayerStanding」を
タイマーで「0.01」秒毎に呼び出しています。
FlipFlop「B」に繋がる処理
しゃがみから立ち上がり、タイマーを止める。
~カスタムイベント「CanPlayerStanding」の作成~
カスタムイベント「CanPlayerStanding」イベントは
以下のようになってます。
Sphereトレースで、頭上に立ち上がるのを阻害する障害物があるかを
チェックしています。
トレースがヒットしたら、障害物があるとして立ち上がり不可
トレースがヒットしてなければ、障害物がないとして立ち上がり可能
となります。
~CapsuleComponentのサイズ調整~
そして、これは前回言い忘れたのですが・・・
Crouchノードを呼び出した時に
CapsuleComponentのサイズ(高さ)が自動で変化します。
↓
こんな感じですね。
しかし、このサイズだと
場合によっては以下のようなことが起こってしまいます。
CapsuleComponentのサイズが小さいので
頭が貫通してしまいます。
そういう時は
CharacterMovementの「CharacterMovement(GeneralSetting)」項目にある
「CrouchedHalfHeight」の値を変えましょう。
デフォルトでは「40」になっているので
「60」ぐらいが丁度良いでしょう。
必要な準備はすべて終わりました。
これでプレイしてみましょう!
「Qキー」を押してるか分かるように
「PrintString」で画面左上に文字を表示させてます。
しゃがんでいる時
上に障害物があった場合
何回「Qキー」を押しても
立ち上がれていないのが分かったと思います。
それではまた!^^ノシ
しゃがみアニメーションのやり方!
~アニメーションをプロジェクトに追加~
作成したプロジェクトに
「アニメーションスターターパック」を追加します。
~アニメーションリターゲット~
コンテンツ内にある
「Mannequin」を開き
「Character」→「Mesh」と開いていきます。
↓
「Mesh」ファイル内にある
「UE4_Mannequin_Skeleton」を開きます。
画面上部ツールバーの
「リターゲットマネージャー」をクリック。
画面左にリターゲットマネージャーが表示されます。
「ヒューマノイドリグを選択」をクリック。
最後に保存してください。
コンテンツフォルダに戻り
「AnimStarterPack」ファイルを開きます。
「UE4_Mannequin」→「Mesh」の順で開いていき
「UE4_Mannequin_Skeleton」を開きます。
そして、先ほどの手順を行います。
「リターゲットマネージャー」を開き
「ヒューマノイドリグを選択」し
最後に保存
です。
コンテンツフォルダに戻り
「AnimStarterPack」→「UE4_Mannequin」→「Mesh」内にある
「UE4_Mannequin_Skeleton」を右クリックします。
そして、「別のスケルトンへリターゲットする」をクリック。
「ThirdpersonCharacter」のスケルトン
「UE4_Mannequin_Skeleton」を選択し
「リターゲット」します。
これで、「ThirdpersonCharacter」で
「AnimStarterPack」のアニメーションを使用することが出来ました。
~CharacterMovementの編集~
「ThirdPersonCharacter」を開きます。
「CharacterMovement」コンポーネントを選択し
画面左の詳細パネルにある
「NavMovement」項目にある
「▷MovementCapabilities」の「▷」マークをクリックします。
すると、各項目が展開されます。
「CanCrouch」にチェックをつけましょう。
これで、Crouch(しゃがみ)が可能になりました。
~BPインターフェースの作成~
「Anim_BP_Interface」という名の
BPインターフェースを作成します。
アニメーションBPで使うインターフェースなので
こういう名前にしました。
作成した「Anim_BP_Interface」を開き
新規関数「SetPlayer_CrouchingBPI」を作成します。
引数(インプット)は以下の通り
これでインターフェースの作成は終了です。
~インターフェースの実装~
「ThirdPersonCharacter」を開き
作成したインターフェース
「Anim_BP_Interface」を追加します。
イベントグラフに、以下の処理を作成します。
「Qキー」を押した時
Crouch(しゃがみ)をし、アニメーションBPのイベントを呼び出す。
引数Crouchingは「True」
もう一度「Qキー」押した時
UnCrouch(しゃがまない)をし、 アニメーションBPのイベントを呼び出す。
引数は「False」
これで「ThirdPersonCharacter」の処理は完了です。
~アニメーションBPの編集~
「ThirdPerson_AnimBP」を開きます。
作成したインターフェース
「Anim_BP_Interface」を追加します。
イベントグラフに以下の処理を作成します。
「ThirdpersonCharacter」から受け取った値を
変数に格納しています。
~アニメーションの実装~
アニムグラフに
「Crouch」という名のステートを追加します。
作成した「Crouch」ステートを開き
「Crouch_Idle_Rifle_Hip」アニメーションを追加します。
~トランディションルールの作成~
「Idle/Run」ステートと
「Crouch」ステートを繋いで
この2つのアニメーションを遷移させる為のルールを作ります。
「Idle/Run」→「Crouch」のトランディションルール
「Crouch」→「Idle/Run」のトランディションルール
最後にコンパイルして完了です。
実際にプレイしてみましょう!
しっかりしゃがみアニメーションが出来ていましたね!
ちなみに・・・
しゃがんだり立ち上がったりするとき
ちょっとカメラが速く動きすぎて気になるかもしれません。
そういう時は
「ThirdpersonCharacter」の
「CameraBoom」コンポーネントの詳細パネルにある
「EnableCameraLag」にチェックをつけましょう。
これでカメラがスムーズに動くようになります!
それではまた!^^ノシ
プレイヤーが日陰にいるかどうかの判定方法!
レベル内にある
「Light Source」を選択します。
「Light Source」を選択した状態で
「ブループリント/スクリプトを追加」をクリックします。
以下のような画面が出てくるので
「BP_Light_Source」をいう名前で
ブループリントを作成します。
作成された「BP_Light_Source」を開きます。
イベントグラフに以下の処理を作成します。
毎フレームライントレースを2つ飛ばしています。
トレース=太陽の紫外線といったところです。
プレイヤーの頭の位置から
自身(BP_Light_Source)の正面方向×「-100000」の位置まで
トレースを飛ばしています。
プレイヤーの脚の位置から
自身(BP_Light_Source)の正面方向×「-100000」の位置まで
トレースを飛ばしています。
2つのトレースが障害物にヒットしていればTrue。
プレイヤーに太陽の光がほぼ完全に当たっていないと判定される。
2つのうち1つでもトレースが障害物にヒットしていなければFalse。
プレイヤーに太陽の光が当たっていると判定される。
レベル内に障害物を何個か置いて
実際にプレイしてみましょう!
画面左上を見れば分かりますが
太陽の光が完全に当たってたり
少しでも当たっていれば「熱い!」と表示され
太陽の光がほぼ完全に当たっていないときは「涼しい~」と
表示されています。
ちょっとマニアックな内容でした~。
それではまた!^^ノシ
小ネタ!カテゴリー機能の便利な使い方!
皆さんはカテゴリー機能を使ってますか??
カテゴリーに名前を付けることで
作成した変数や関数、マクロを
分かりやすく管理することが可能です。
変数
関数
マクロ
さらに、”ある記号”を加えることで
カテゴリー分けをより詳細化させることが出来ます。
「Bool値|First」と入力しています。
「Bool値」と「First」の間に
「|」の記号を入れることで
カテゴリー内に更にカテゴリーを作成することが可能です。
ちなみに「|」は
以下の位置にあるキーです。
「|」は
「パイプ」「縦棒」「垂直バー」などと呼ばれてるそうで。
地味ーな小ネタですが
これを活用することで
大量に作成した変数、関数、マクロを
分かりやすく綺麗に管理する事が可能です!
それではまた!^^ノシ
徘徊!追跡!見失う!いない!徘徊再開!
※注意!
前回の記事「敵のランダムな徘徊方法!」を読んでいること前提で進めます!
今回は
視界に入ったプレイヤーの追跡方法!
と
見失ったら見失った地点まで移動!
と
一定時間待機してプレイヤーが見つからなければ徘徊再開!
の3本立てでお送りします。
Enum(列挙体)を作成します。
「Find_or_Lost_Player」と名付けます。
中身
この列挙体は
プレイヤーを見つけた(Find)か見失った(Lost)か
を定義する時に使います。
「Enemy_BB」を開きます。
「新規キー」を3つ追加します。
「Player」(Object型)
「RandomLocation」(Vector型)
「Find_Lost」(Enum型)
インターフェースを作成します。
「EnemyInterface」と名付けます。
「EnemyInterface」を開き
新規インターフェースを2つ作成します。
「FindPlayerBPI」は、プレイヤーを見つけた時に呼ばれるイベント
「LostPlayerBPI」は、プレイヤーを見失ったときに呼ばれるイベントです。
「Enemy_Con」を開きます。
「AIPerception」コンポーネントを追加します。
「AIPerception」の詳細パネルを以下のように設定します。
設定方法の詳細は以下のブログに書いています。
↓ご参考に。
関数を作成します。
「SetBlackboardValues」と名付けます。
「SetBlackboardValues」を開き
以下の処理を作成します。
ブラックボードの指定したキーに
値を格納する為の処理です。
「SetBlackboardValues」関数のインプットピン
こんな感じですね。
イベントグラフに
以下の処理を作成します。
視界に入ったアクターの情報をゲット
「GetActorsPerception」の「InfoTarget」ピンには
視界に入ったアクターが格納されています。
それを変数に格納します。
プレイヤーが視界に入ったかどうかの判定を行います。
プレイヤーが視界に入ったらTrue
プレイヤーが障害物で遮られたらFalse
↓プレイヤーが障害物で遮られたかどうかの判定は以下のノードでできます。
対象のアクターが障害物で遮られてない場合
視界から外れていてもTrue
対象のアクターが障害物で遮られたらFalse
といった感じです。
ブランチで判定を行った後は
自作関数「SetBlackboardValues」内に格納します。
Trueに繋がる処理
「SetBlackboardValues」関数で値を格納しています。
その後、「FindPlayerBPI」で「Enemy_Con」を所有している
「Enemy」のイベントを呼び出しています。
Falseに繋がる処理
SequenceノードでDoOnceにResetの処理をかけてから
「SetBlackboardValues」関数に値を格納しています。
「Enemy_BT」を開きます。
「新規タスク」を作成します。
新規作成されたタスクに
「VigilanceAround_BT_Task」と名付けます。
「VigilanceAround_BT_Task」を開き
以下の処理を作成します。
変数
WaitDuration・・・後から編集しやすいように編集可能に。
「Enemy_BT」を開きます。
以下の処理を作成します。
左側から見ていきましょう。
徘徊処理です。
プレイヤーを見つけていない(Lost)状態だと
「Enemy」はランダムな位置に移動し続け徘徊する。
これは前回のブログ「敵のランダムな徘徊方法!」でやった内容通りでしょう。
けど1つ違うのは
Sequenceノードに「Blackboardデコレーター」が追加されているところです。
この「Blackboardデコレーター」の詳細パネルは以下の通り。
オブザーバーを中止を「Self」にしています。
「Self」にすることで
徘徊途中でプレイヤーを見つけた時
即座に徘徊処理を中止できます。
KeyQueryは「IsEqualTo」
KeyValueは「Lost」
BlackboardKeyは「Find_Lost」
にしてます。
要は
プレイヤーを見つけてない(Lost)した状態なら
徘徊処理を実行する
という感じです。
プレイヤーを追跡する処理です。
徘徊処理が中断されると、この処理が実行されます。
「MoveTo」ノードで
プレイヤーの位置まで移動という感じです。
この処理の「Blackboardデコレーター」の詳細パネルを以下のように設定します。
オブサーバーを中止を「Both」にしています。
理由は・・・
説明したいところですが自分でもはっきりわかっていないので
悔しくも割愛します・・・。すいません・・・。
KeyQueryは「IsEqualTo」
KeyValueは「Find」
BlackboardKeyは「Find_Lost」
つまり
プレイヤーを見つけた(Find)ら
追跡処理を実行する。
といった感じです。
「MoveTo」ノードの詳細パネルです。
「Player」の位置まで移動させたいので
BlackboardKeyを「Player」にしています。
プレイヤーを見失ったときの処理です。
「MoveTo」ノードで
プレイヤーを見失った位置まで移動します。
その後、作成したタスク「VigilanceAround_BT_Task」で
「WaitDuration」に入れた値分その場で待機。
プレイヤーが見つからなければ
この処理は成功(終了)し
また徘徊処理に戻る。
といった感じです。
この処理の「Blackboardデコレーター」の詳細パネルを以下のように設定します。
オブサーバーを中止を「None」に。
KeyQueryは「IsEqualTo」
KeyValueは「Lost」
BlackboardKeyは「Find_Lost」
つまり
プレイヤーを見失った(Lost)とき
この処理を実行する
といった感じです。
「MoveTo」ノードの詳細パネルです。
プレイヤーを見失った地点まで移動させたいので
BlackboardKeyを「LostPlayerLocation」にします。
「VigilanceAround_BT_Task」タスクの詳細パネルです。
WaitDurationの値を「5」に設定します。
これで、プレイヤーを見失った地点に到達した後
「5秒間」その場で待機することになります。
「Enemy」を開きます。
イベントグラフに以下の処理を作成します。
徘徊する時と追跡する時で
移動速度を変えています。
変数
NormalSpeed・・・徘徊速度。デフォルト値は「180」
ChaseSpeed・・・追跡速度。デフォルト値は「500」
これですべて完了です!
レベル内に障害物を何個か置いて・・・
さっそくプレイしてみましょう!
徘徊時は、ランダムな位置に移動。
移動速度は遅め。
プレイヤー追跡時は
移動速度が速くなる。
発見したか分かりやすいように
赤いSphereが見つかった地点に表示されるはずです。
プレイヤーを見失ったときは
見失った地点まで移動。
見失ったか分かりやすいように
見失った地点に
青いSphereが表示されるはずです。
一定時間後
プレイヤーがいなければ
再び徘徊。
といった感じです。
くssssssっそ長くてだるかったと思いますが
何も考えずにただやり方をトレースするだけでも
普通に出来るはずです。(説明不足とかなきゃ)
ここまで読んでくれてありがとうございますw
それではまた!^^ノシ