イライラ棒的なゲームを作ろう!(棒じゃないけどw)
イライラ棒、いやイライラ「球」を作ろう!
仕様としては・・・
・マウスのドラッグ操作で球を動かす
・弾が何かにヒットしたらゲームオーバー
・ゴールに到達したらクリアー
~カメラの設置~
上から全体を見下ろせる位置にカメラを設置。
~プレイヤーコントローラー・ゲームモード作成~
「IraIra_Con」という名のPlayerControllerを作成。
クラスのデフォルトの詳細パネル「MouseInterface」欄の赤枠で囲った部分にチェック。
これでクリックイベントが有効になり、ゲーム開始時常にマウスカーソルが表示されるようになった。
「IraIraGameMode」という名のゲームモードを作成。
クラスのデフォルト詳細パネルの「Classes」欄の赤枠で囲った部分を変更する。
先程作成したプレイヤーコントローラー「IraIra_Con」を割り当てよう。
デフォルトポーンは、「None」で。
ワールドセッティングのGameModeに、作成したゲームモード「IraIraGameMode」を割り当てる。
~球の作成~
「IraIra」という名のアクタークラスのBPを作成。
コンポーネントを以下の通り。
ドラッグ操作するための処理
このアクターがクリックされたときに呼ばれるイベント「OnClicked」と、
このアクターがクリックし終わった時に呼ばれるイベント「OnReleased」を追加。
「OnClicked」は、GateノードのOpenに。
「OnReleased」は、Closeに繋げる。
GetHitResultUnderCursorByChannel
TraceChannel・・・カーソルのトレースチャンネル(コリジョン)
HitResult・・・カーソルのヒット情報
ResultValue・・・カーソルがヒットしたかどうか
このノードは、「GetPlayerController」からじゃないと出てこない。
マウスカーソル位置に球を追従させたいので、HitResultを分解(BreakHitResult)し、Locationを分解(BreakVector)する。
XとYのみ自由に移動させるようにする。Zは「80」で。
理由は後程。
移動させる処理として、SetActorLocationを使用。
Sweepにチェックを入れるのを忘れずに。
さて、先ほどの
XとYのみ自由に移動させるようにする。Zは「80」
の理由だが、
例えば、Zを「0」にしたらどうなるか。
埋まる。
理由は、床の位置とちょうど被るから。
これは床を球とぶつからないように下げるか、球のZを「80」にすればいい。
今度は、以下のようにしたらどうなるだろう。
カメラのほうに向かって勢いよく向かってくる。
なぜなら、
カメラはワールド内のZの位置に設置している。
という事は、実際球を動かす時XとYを自由に動かせるようにしないといけない。
Zにまで移動可能にすると、Zの位置に設置してあるカメラのほうに向かってきてしまうから。
だから、Zにまで動かす必要が無いのだ。
何かとぶつかった時の処理
シンプル。
何かとヒットした時に、爆発エフェクトを出して、球を破壊してるだけだ。
ここで、適当にステージを組もう。
~UMGの作成~
クリアーしたときのUMG
「Clear」という名のUMGを作成。
「CLEAR!」というテキストを追加。
真ん中に設置。
ゲームオーバーした時のUMG
「GameOver」という名のUMGを作成。
先程とほとんど同じ。
ゴール位置の表示
「Goal」という名のUMGを作成。
先程と同じ。
~ゲームオーバー処理~
「IraIra」のイベントグラフに以下の処理を追加。
DestroyActorの後に、GameOverUMGを表示。
~クリアー処理~
まず、ゴールを設置。
ボックストリガーを置こう。
設置したボックストリガーに、コンポーネントを追加しよう。
Widgetの詳細にある「UserInterface」欄は以下のように設定。
Space・・・Screen
WidgetClass・・・作成したUMG「Goal」を設定。
「IraIra」のイベントグラフに以下の処理を追加。
ブランチを追加し、Conditionには「Clear?」という名のBool値を繋いだ。
デフォルト値はFalseに。
レベルBPに以下の処理を。
レベル内に設置したボックストリガーを選択状態にしたまま、レベルBPのイベントグラフを右クリックし、
OnActorBeginOverLapを追加。
設置したゴール(ボックストリガー)に、「IraIra」がオーバーラップしたら、「Clear」UMGを表示し、「IraIra」BPにある「Clear」Bool値をTrueにセット。
こうすることで、ドラッグ操作による球の移動が不可能になる。
これでプレイしてみよう!
プレイ映像(死亡ラッシュ)
クリアー時
非常にシンプルだが、とりあえずゲームっぽいものはできた。
何回も死ぬ羽目になるので、リセット機能は必須かもしれないw
他にも、いろいろとステージやギミックを増やして面白くするのもいいかもしれない。
それではまた!^^ノシ
SetTimerByEvent・SetTimerByFunctionNameとは??
~SetTimerByEvent~
「Time」に入れた秒数後に、「Event」に繋がってるカスタムイベントを実行する。
Delayのような感じ。
「Looping」で、「Time」に入れた秒数後、Timerをリセットして再度カウントダウンを始める。
~使用例~
Qキー押す。
↓
SetTimerByEventが実行され、「Time」に入れた秒数分カウントダウンを開始。(画像だと「3.0」と入れたので、3秒間のカウントダウンとなる)
↓
3秒後、作成したカスタムイベント「TimerTest」に処理が走り、カスタムイベントに繋がってる処理(画像だと「SpawnEmitteratLocation」)が実行される。
サードパーソンキャラの位置に、爆発エフェクトを出すようにしてある。
実際にやってみると・・・
こんなかんじになるはずだ(適当)
Loopingにチェックを入れると・・・
3秒おきにエフェクトが出ているのが分かる。
~SetTimerByFunctionName~
SetTimerByEventと違うのは、
実行するカスタムイベント名を指定できる事。
SetTimerByEventは直接ピンで繋げていたが、SetTimerByFunctionNameは「FunctionName」に実行させたいカスタムイベント名を入れる事が可能。
あとはSetTimerByEventと同じ。
Timeに入れた秒数分カウントダウン開始。
Loopingはカウントダウンをループさせるかどうか。
Object??わかんネ(マジすいません・・・)
先程とほぼ同じ処理。
キャラの位置でエフェクトを出す。
「1秒」おきに何度もエフェクトを出すようにしてある。
「FunctionName」には実行させたいカスタムイベント名を入力。
しっかり「1秒」おきにエフェクトが出てるのが分かる。
~カウントダウンの止め方~
さて、SetTimerByEventとSetTimerByFunctionNameの機能は分かったが、
もしかしたら「途中でカウントダウンを止めたい!」という時があるかもしれない。
止めるときはこれを使う。
「ClearandInvalidateTimerbyHandle」だ。
~使用例~
「0.5秒」おきに繰り返しカスタムイベントの処理を実行。
Qキー押した時、SetTimerByEventを実行し、カウントダウンを開始。
Qキー放した時に、実行されてるSetTimerByEventのカウントダウンを停止。
ClearandInvalidateTimerbyHandleの「Handle」に、停止させたいSetTimerByEventの値を繋ぐ。
途中でしっかり処理が止まってるはずだ。
実際にやってみよう。
もちろんSetTimerByFunctionNameでも同じことができるぞ。
~小ネタ~
SetTimerByEvent・SetTimerByFunctionNameを使って、EventTickとほぼ同じ動作をさせることが可能だ。
Timeに「0.008333」を入れてやれば、ほぼEventTickと同じ動作が可能だ。
非常に目に痛い動画だが、EventTickとほぼ同等の動作と言える。
これで、SetTimerByEventとSetTimerByFunctionNameの機能と、ちょっとした小ネタを知ることが出来た!
それではまた!^^ノシ
Splineで遊ぼう!~Splineでちょっとしたプロシージャルメッシュ作成~
ActorクラスのBPを作成。
名前は何でも。(自分は「BP_Spline」にした。)
~Splineコンポーネント追加~
「Spline」というコンポーネントを追加。
~ConstractionScript~
~変数~(全部編集可能にする)
NumberOfMeshs・・・配置するメッシュの数
OrientToSpline・・・メッシュの向き(角度)をSplineの角度に合わせるか??
NumberOfMeshsで配置するメッシュの数を決める。
デフォルト値は「2」にした。
配置するメッシュの数が「0」、つまりNumberOfMeshsが「0」の場合、ブランチの条件によりFalseに処理が流れる。
NumberOfMeshsの値「2」から1引いた値をForLoopのLastIndexに渡す。
同時にNumberOfMeshsの値「2」から1引いた値をGetSplineLengthの値で割る。
GetSplineLength・・・Splineの長さを取得
ちなみに、Splineの長さはデフォルトだと「100」
つまり、NumberOfMeshsのデフォルト値には「2」を入れたので、
100÷1=「100」
になる。
「100」をIndexの値で掛け算する。
FirstIndex「0」
LastIndex「1」なので・・・
0×100=「0」
1×100=「100」
となる。
この値は、配置するメッシュの位置を決める値となる。
この値を、GetLocationAtDistanceAlongSplineでVector値に変換。
これを、InverseTransFormLocationで相対座標に変換。
相対座標に変換した値をMakeTransFormで一纏めにして、AddStaticMeshComponentノードのRelativeTransFormに繋ぐ。
これで、メッシュを指定した数の分だけ配置が可能になった。
最後に、GetRotationAtDistanceAlongSplineでSplineの角度をワールド座標の角度に変換。
Distanceには、先程の「Indexの値×100」の値を繋ぐ。
GetRotationAtDistanceAlongSplineでワールド座標に変換したSplineの角度を、SetWorldRotationに渡す。
その前に、ブランチを挟む。
ConditionがTrue・・・メッシュの角度をSplineの角度に合わせる。
ConditionがFalse・・・合わせない。
さてどうなっているか!?
見事!(自己満)
ここで整理しよう。
NumberOfMeshsの値が「2」だった場合。
相対座標、X「0」とX「100」の位置にメッシュが配置される。
「0」「100」は、先程やった「Indexの値×100」の奴だ。
0×100=「0」・・・1個目に配置するメッシュの位置
1×100=「100」・・・2個目に配置するメッシュの位置
となる。
まあ、Splineは昨日触ったばっかなので、色々違う部分はあるかもしれないw
その場合は遠慮なく指摘してほしい。
それではまた!^^ノシ
DestroyComponentの注意点!~なぜDestroyComponentを使ってるのに何も破壊されないのか??~
今回DestroyComponentで躓いた点があったので紹介する。
前回の記事とほぼ同じな為、ある程度説明を省く。
「落ちてる武器を拾って、プレイヤーにアタッチする」という処理なのだが、
落ちてる武器を拾った時
↓
落ちてる武器と同じ武器をプレイヤーの指定したソケットにスポーン
↓
スポーンした武器を、プレイヤーの指定したソケットにアタッチ
↓
落ちてた武器を破壊(削除)
といった処理だ。
~処理~
武器を取得時、指定したソケットに武器をスポーン。
取得した武器のSphereコリジョンを破壊。落ちてた武器を破壊。
※変数「Rifle」と「WeaponMaster」と「Sphere」については先に載せた記事を参考ください。
これでプレイすると・・・
落ちてる武器は破壊されたものの、背中にアタッチされた武器はSphereコリジョンが残ったまま。
先程の画像の処理で確かにRifle(武器)に、コンポーネントとして追加してあるSphereコリジョン(オーバーラップコリジョンコンポーネント)を、破壊(Destroy)したはずなのに。
実はこの処理だと破壊されないのだ。
どういう事かと言うと・・・
DestroyComponent・・・そのアクター自身のコンポーネントを破壊するノード。
ここで言うアクター自身というのは、「操作キャラ」、つまり「サードパーソンキャラ」の事になる。
このサードパーソンキャラのコンポーネントには、Sphereコリジョンなんてものは存在しない。
「え??でもAttachtoComponentでRifle追加してるんでしょ??それで追加したRifleのコンポーネントにSphereコリジョンがあるんだから、普通に存在してるんじゃねえの??」と思うかもだが。それは違う。
AttachtoComponentは、ただ単に「キャラに追従させてる」だけ。もっと簡単な言い方をすれば「くっつけてる」だけ。
だから、「コンポーネントに追加」してるわけではないのだ。
つまり、DestroyComponentでサードパーソンキャラのSphereコリジョンコンポーネントを破壊しようとした所で、そもそもサードパーソンキャラにSphereコリジョンコンポーネントなんてものは無いから、何も変化が無かったのだ。
じゃあどうすればいいか??
WeaponMasterのイベントグラフに、Sphereコリジョンを破壊する為のカスタムイベントを追加すればいいのだ。
「DestroyComponent」という名のカスタムイベントを追加。(名前が一緒でややこしいかもだがw)
武器をアタッチさせた後に、「DestroyComponent」カスタムイベントを呼び出す。
これでプレイしてみよう!
武器を拾った後、アタッチされた武器のコンポーネントであるSphereコリジョンがしっかり破壊されていた!
今回はDestroyComponentの躓きポイントを紹介した。
もし同じようなことで悩んでいるならこの記事を読んでほしい。
それではまた!^^ノシ
アウトラインを表示する方法(金のかかるやり方だが)
今回は、アウトライン表示方法をやるのだが、
残念ながら僕はマテリアルはめっきりよく分かんない為、
アセットの力を借りることにした。
「OutLiner」という名のマテリアルアセットだ。
このアセットは確か2000円ぐらいだったはず。(16$ぐらいだったかな??)
このアセットを使って、アウトライン表示処理を実装しよう!
PostProcessVolumeの設定
PostProcessVolumeの詳細欄に画像のような項目がある。
Arrayの隣にある「+」をクリックすると、適用したいアウトラインマテリアルを設定できる。
アウトラインマテリアルは3つまである。(多分)
今回は、赤枠で囲った奴の一番左にあるやつを使う。
アクタークラスのBPを作成
コンポーネントにCubeを追加しただけのシンプルなアクター。
以下の処理を組む。
SetCustomDepthStencilValueにあるValueの数値は何を示しているかというと・・・
先程PostProcessVolumeに設定したマテリアルを見てみよう。
赤枠で囲ってある部分の数値の事だ。
つまり、Valueに「1」を入れた場合「OutLineClolor(S1)」に設定されてある色(画像だとオレンジ色)がアウトラインの色として設定される。
「2」は、ちょっと濃いオレンジ。
「3」は、青色。
というように、数字によってアウトラインの色が変えられるようだ。
プロジェクト設定
エンジン→RenderingのPostprocessingという項目にある赤枠で囲った部分を変更する。
恐らくデフォルトでは「Enabled」になってるはずなので、これを「EnabledWithStencil」に変更する。
これでプレイしてみよう!
しっかりアウトラインの表示がされていた!
このアセットがあれば、わざわざ自分でマテリアルを自作しなくても済むだろう!
それではまた!^^ノシ
落ちてるアイテムをピックアップ(取得)する処理!
1日ブログすっぽかした者です。(´・ω・)
今回は、シューティングゲームを作るという体で行くため、「落ちている『武器』を拾う」というシチュエーションにする。
やりたい事!
・武器を拾うためのBPの作成
・拾う武器の作成
・武器に近づいたら、武器名をスクリーンに表示
・武器の近くで指定したキーを押したら、キャラに装備
その他諸々・・・
※TPSテンプレート使用。アニメーションスターターパック使用。
・プレイヤーに武器をアタッチする為のソケットを追加
「Hand_r(右手)」にソケットを追加。
名前は任意で。(画像では「WeaponSocket」にした。)
・プレイヤーBP
カスタムイベント(PickUp)が呼び出された時、武器を指定したソケットに追加。
カスタムイベントの詳細。
・武器を拾うためのBPの作成
ActorクラスのBPを作成。
名前は任意で。(画像では「WeaponPickUp_Master」にしてある。)
以下のように、コンポーネントを追加。
Weapon・・・武器。スケルタルメッシュ。(スタティックメッシュでもいい)
Widget・・・ウイジェットを表示するためのコンポーネント。
これで、武器を拾うためのBPの作成は終了。
・武器に近づいたら、武器名をスクリーンに表示
武器に近づいたときに、武器の上に武器名を表示させる為のウイジェットを作成する。
武器名は何でも良い。(僕はライフルのアセットがあるので「Rifle」と明記)
階層にTextBlockを追加。
TextBlockに任意の武器名を入力。
フォントサイズは要調整。
・拾う武器の作成
僕のとこには「ライフル」と「ショットガン」のアセットがあるので、
2つの武器BPを作成する。
「Rifle」と「ShootGun」という名のBPだ。
2つともアクタークラスのBP。
作成した武器BPを開き、クラス設定を選択。
詳細パネルの親クラスを、作成した「WeaponPickUp_Master」に変更。
こうすることで、作成した「WeaponPickUp_Master」BPの機能(コンポーネント、BP)を継承(引き継ぐ)する事が可能。
例えば、武器BPを5個作成するとして、5個の武器BPすべてに「WeaponPickUp_Master」と全く同じ処理を1個づつ一々組まなきゃいけないのは面倒だし非効率。
ましてや、もし5個全ての武器BPの処理を変更する!ってなった時に、1個づつ同じように処理を変更するのはとても過酷。
これが10個、50個、100個となったら・・・個数は大げさかもだが、考えただけで全身の血の気が引く。
だったら、元となるMasterBP(WeaponPickUp_master)を作成して5個全ての武器BPに継承させれば、たとえ5個全ての武器BPの処理を変更するとなった時も、元となるMasterBPさえ変更すれば、後の5個全ての武器BPも変更されるという事になるのだ。
分かりづらいイラストで申し訳ない。だが、今の説明がしっかり理解できたなら幸いだ。
Space・・・Screenにする。
WidgetClass・・・作成したウィジェットを指定。
後は、ウィジェットを表示させたい位置に調整する。
・武器の近くで指定したキーを押したら、キャラに装備
「WeaponPickUp_Master」に以下の処理を組む。
オーバーラップコリジョンにプレイヤーがオーバーラップしたら、ウィジェットを表示。武器を取得する為のキー入力を受け取るためEnableInputを実行。
オーバーラップコリジョンから出て行ったら、ウィジェットを非表示。そして、キー入力も無効にする。(DisableInput)
取得する為のキーが押されたら、プレイヤーBPのカスタムイベント(PickUp)を呼び出し、オーバーラップコリジョンを破壊する。
これでプレイしてみよう!
プレイヤーの接近による武器名の表示。武器のアタッチ。ピックアップ処理。
やりたいことが全部出来ていた!あっぱれ!><///
今回は、ピックアップ処理ともう1つクラスの継承の方法も知れたので、一石二鳥!
それではまた!^^ノシ
IK!~ずれてる手の位置を修正!~
とあるお方から教えてもらいました。本当に感謝です。
さて、今回シューティングもどきを作ってる時の事、非常に困ったことがあり・・・
明らかに左手の位置が合ってないのだ。
これでは違和感バリバリなので、これを修正する方法を紹介する。
TwoBoneIKを使おう!
EffectorLocation・・・修正するボーンの位置。
JointTargetLocation・・・今回は使わない。
Animグラフ
Hand_R
IKBone・・・実際に動かすボーンを指定
Hand_L
あとは、EffectorLocationの値を変えて手の位置を調整すればOK!
EffectorLocationの値を変えれば、ちゃんと右手の位置が変わっていた!
右手を動かせば、それに連なるボーン(肘、肩)もしっかり動いていた!
これで修正が楽になるというわけだ!
というか今回右手しか修正していなかったね・・・笑
でもIKの簡単な使い方が分かったんじゃあないだろうか。
自分自身IKは全然詳しくないから、興味があれば自分で色々調べてみるといい。
それではまた!^^ノシ