2018-01-01
氷の作り方
writer : toppon
氷の作り方
私はゲーム内で,水の中で氷の怨挟術をした時に,水中からプレイヤーが乗ることができる氷が水面まで上がってきて,時間が立つと小さくなって消えるというものを作りました.
ということで,この記事では,氷を発生させ,上昇させて,接触していたものの表面(=水面)まで出たら止まるところを説明したいと思います.
早速,作っていきましょう.
まず,ブループリントから,新規の空のブループリントクラスを選択します.
すると,このような画面が出てくるので,Actorを選んでください.
そして,ここでblueprintを選択し,名前をつけ,OKを押すと,作成できます.今回は氷なので,Iceという名前にしました.ここからはここで作ったものをIceと呼ぶことにします.
次に,このような画面が出てくるので,左上のコンポーネントを追加のところから,球やキューブや平面を自由に配置し,形を作ってください.私は氷を作りたいので,下図のようにキューブを6つ,変形させて六角形になるように配置しました.
ここからは,ブループリントを触っていきます.
マップに戻り,ブループリントからレベルブループリントを開くを選択します.
出てきた画面で右クリックすると,ウィンドウが出てくるので,状況に合わせた表示のチェックを外してから,Xキーの入力をとるインプットの中のキーボードイベントのXを探し,クリックしてください.
これで,Xキーが押された時,このノードが動くようになります.
ここのPressedから線を伸ばし,適当なところで離してください.
ここで,状況に合わせた表示のチェックをつけます.
ここで,Line Trace For Objectsというノードを探して,選択してください.
Line Trace For Objectsというノードは,簡単に言えば指定した座標から別の指定した座標までに物体があって,かつそれが指定された物体であれば,trueと当たった物体の情報を取れるという機能をもっています.
このStartのところに主人公の座標を取り,Endのところに主人公の座標をz方向に-500だけ動かしたものを取ります.これは,若干エフェクトが水面から上方向に離れていても,氷を発生するためにしたものです.
まず,Startのところに,GetActorLocationというノードをつなぎます.これは,ターゲットのところに繋げられたアクターの位置を取得するというノードです.ターゲットのところに,さらにGetPlayerControllerというノードをつないでください.これは,簡単に言えば主人公のアクターを指定するためのものです.FirstParsonからつくらず,一番基本から作ってる人は,GetPlayerCameraManagerというノードを使ってください.
また,GetActorLocationの先から線を伸ばし,-と打つと,vector – vector というノードが出てくるので,これを選んでください.
ここで,z方向だけ500を入力し,右の点から,LineTraceForObjectsのEndにつなげます.これで,StartとEndの設定は完了です.
ここからObject Typesのところから線を伸ばし,makeと打つと,配列を作成というものが出てきます.ここに,水のものを設定すると,水に当たったらtrueと当たった物体の情報を返すものになります.今は,仮にWorldStaticだけにしておきます.
ここからは,氷を発生させるという,アクタのスポーンというものをします.
LineTraceForObjectsから白線を伸ばし,spawnと打つと,クラスからアクタをスポーンというものがあるので,選択してください.
これは指定したアクタを一つ指定した位置に発生させるノードです.
ここで,classからIceを選択してください.
次に,LineTraceForObjectのOut Hitから,線を伸ばすと,Break Hit Result というものがあるので,選んでください.このノードは,当たったものの位置や何が当たったかなどの詳しい情報をとるものです.
Break Hit ResultのLocationから,SpawnActor IceのSpawn Transformのところに繋いでください.
これで,Xキーをおした時,自分の座標から500下までにWorldStaticの物体と触れていたら,氷を発生させるというところが完成しました.
ここからは,水面に当たるまで氷を上昇させる,という部分を作っていきます.
考え方としては,「発生した瞬間からちょっとずつz座標を上に上げ,氷の真上に最後に追加した小さなボックスが水と当たらなくなるまで上げる」という処理になります.
まず,発生した瞬間にちょっとずつz座標を上げる,というところを作ります.
Iceの方のブループリントエディタに移動してそこからイベントグラフを開けてください.
ここで,適当なところで右クリックし,Begin Playから,白い線を伸ばし,addworldoffsetというノードをつなぎます.
このaddworldoffsetというノードは,指定したアクタを指定した座標分だけずらすというものです.今回はzのところに5を設定しました.
ここから白い線を伸ばし,retriggerable delayというノードにつなぎます.このノードは,少し時間を待ってくれる機能があります.このDurationは0.05に設定しておきます.
このノードの先から,図のように先程のaddworldoffsetにつなぎます.
線が混じって見にくいので,線をダブルクリックすると線の上に丸がでてきます.
これを移動させて,見やすくしてしてください.
これで,このアクタが発生した瞬間から,ちょっと上がる→ちょっとだけ待つ→ちょっと上がる→ちょっとだけ待つ→・・・の繰り返しになり,ちょっとずつ上がっていく感じになります.
ここから,氷が水の表面まで上がってきたら止まるというところを作っていきます.
ループごとに,上のボックスが水と当たっているかを判定し,当たっていなければ繰り返しを抜けるというものです.
まず,addworldoffsetから,新たに線を引き,ifと打ちます.するとブランチと言うものが出てくるので,それを選んでください.
このブランチというノードは,Conditionに書かれている条件がtrueかfalseかによって,次に実行するノードを変えるというものです.
これで,上のボックスが水と当たらなくなったら氷を上がるループを抜けるように,trueからはretriggerable delay につなぎ,falseのときには抜けてもらうこととします.
これで,Conditionがtrueのとき,回り続け,falseになったら抜けるというコードになります.ここからは,Conditionをどうするかを書いていきます.
ここには,上のボックスが水にあたっていたらtrue,当たっていなかったらfalseを返すことになります.
ここでは,CollisionOverlapActorsというノードを使います.これは,このコリジョンに何かが当たっていたらtrue,当たっていなかったらfalseを返すノードです.Objectsのところに,makeと打って配列を作成を選び,WorldStaticとしてください.また,Componentのところには,左の画面から上にあるボックスをドラッグして持ってきて,それをつなげてください.Component Transformは,GetActorTransformというものを使って,位置や座標を取ります.
ここからは,先程作った氷を発生させるところをいじっていきます.
氷が上がるようになっているので,当たったところより低い座標から発生させたいと思います.
BreakHitResultのところの,Hit Locationのところから,vector - vectorノードを出してきて,座標を100だけ下げて,それをSpawnActor IceのTransFormにつなげます.
こうすることで,氷が上がってくるようになりました!