Unityでダークソウル風のロープを掴んで下りる機能を作る

記事内に広告が含まれています。

今回は主人公キャラクターがロープ(滑車付きロープでもいいかも)を掴んで下りていく機能を作成します。

ダークソウル2?にあった板が重なり合ったステージで初心者には道案内の白が必要なエリアにあった機能を作ってみました。
わたくしもよく白になって道案内をしていました。

・・・やったことない人にはまったくわからないですね、やった事ある人もわからないかもしれませんが・・・。

とりあえずそのステージにあったロープを掴んで下りる機能を作成していきます。
PS3が壊れたのでどんなんだったか忘れていますが・・・・(^_^;)

まずはロープ等のゲームオブジェクトを作成します。

スポンサーリンク

ロープや坂、ロープを掴むエリアを作成

ロープはCubeのサイズを変更して作成しました。

ロープなのでCylinderで作る事をお勧めします・・・・・(T_T)作った後に気がつくおバカさん

ロープを降りる機能の階層

上のように階層を作ります。

RopeSystemは空のゲームオブジェクトで作成し、その子要素にロープ系のゲームオブジェクトを詰め込みます。

RopeSystemの子要素に空のゲームオブジェクトを作成し、名前をMoveHandPosとしてます。MoveHandPosはキャラクターの手の位置を合わせる場所でロープを掴んで降りる時に動かします。

MoveHandPosの子要素にはIKで指定する右手(RightHand)、左手(LeftHand)の位置と角度を合わせる空のゲームオブジェクトを作成します。

最初に設定する位置や角度は後で調整するので大体で設定しておきます。

RopeObj(CubeもしくはCylinderで作成)はロープ自体の見た目のゲームオブジェクト、SearchArea(Cubeで作成)はキャラクターがロープを下る場所に来たかどうかを判断するエリアとして使います。

StartBasePosition(空のゲームオブジェクトで作成)はロープを降りる時の最初のキャラクターの位置で、EndHandPos(空のゲームオブジェクトで作成)はロープを降り切ったとする手の位置になります。

ロープシステムで使うゲームオブジェクトの画像

真正面から見ると、

真正面から見たロープで使うゲームオブジェクト

上のような感じになります。

主人公がロープを掴む動作をするエリアSearchAreaにスクリプトを設定

SearchAreaのゲームオブジェクトは上の画像のbaePositionの辺りにCubeを使って作成します。

SearchAreaのMesh FilterとMesh Rendererは使わないので削除します(元々空のゲームオブジェクトを作成しBox Colliderを取り付けるだけでもOK)。

このエリアと接触したらロープを掴み降りていく動作をさせます。

なので、SearchAreaオブジェクトにSearchCharaというスクリプトを作成し設定します。

今回はOnTriggerEnterでSearchAreaに進入したキャラ(厳密にはコライダ)にPlayerタグが設定されたものだったら、そのゲームオブジェクトに設定されているRopeCharaスクリプトのSetStateメソッドを呼び出しキャラクターの状態を変更します。

キャラクター操作スクリプトにロープを掴んでいる時の処理を追加する

主人公操作スクリプトにロープを掴んで下りていく間は移動機能を無効化する必要があります。

ロープを下りていく間にキャラクターを操作出来ると空中を移動してしまいますからね・・・・(=_=)

ロープを掴んでいる状態を追加しています。

キャラクター移動処理はState.Normalの時だけ実行し、ロープを掴んで下りている時は動作しないようにします。

ロープを掴んでいる間は重力も働かせないようにします。

StartメソッドではMoveHandPosの位置とStartBasePositionの位置の差を取得しておきます。

これはロープを掴んでいる時にMoveHandPosを動かしますが、それに合わせてキャラクターの位置も動かしたい為、最初にその差を取得しておき、

キャラクターの位置はMoveHandPosにその差を加味した位置に移動させる為です。

またMoveHandPosは移動させるので、キャラクターがロープを離した時に元の位置に戻す必要があります。

その為、MoveHandPosの最初の位置はdefalutStartPositionにあらかじめ保持しておきます。

キャラクターがState.Ropeの状態の時はVector3.Leapで徐々にEndHandPosに移動させます。

ある程度EndHandPosに近付いたらキャラクターの状態をState.Normalに戻します。

RightHand、LeftHandの位置や角度もUnityの実行時に位置と角度を調整します。

RightHand、LeftHandは実行時にインスペクタのTransformの歯車をクリックしCopyComponentを選択した後実行を解除し、Transformの歯車からPasteComponentValuesを選択し実行時の値をペーストします。

SetStateメソッドではノーマル状態とロープを掴んだ状態に応じて設定を変更しています。

SetRopePositionメソッドはロープのサーチエリア内に入った時、キャラクターの位置と角度をStartBasePositionと合わせます。

その為、StartBasePositionのローカルのZ方向(青い矢印)はロープを下っていく方向に回転させておきます。

こうすることでキャラクターがロープのサーチエリアに入ったらロープを降りる方向に向くようになります。

ResetHandPosメソッドは動かしたMoveHandPosを元の位置に戻す処理です。

機能の確認をしてみる

これでロープを掴んで下りる機能が完成しました。

HandIKは

RopeCharaの設定

↑のように設定します。

それでは実行して確認してみましょう。

ロープ4

上のように手はロープを掴みキャラクターも移動します。
上半身のアップだけだと分かりづらいので全体を確認します。

ロープ5

上のようにロープを掴んで下りてくる動作が確認出来ました。

ロープを下りる時は専用のカメラに切り替えて主人公の頭の後ろから覗くような感じにするのもいいかもしれません。

ロープの移動で距離を計ったり、検知エリアを使ってロープを早く離す

キャラクターが目的地付近に来るとものすごくスピードが遅くなりロープを離すまでがもどかしい!!という方は

としている0.1fのところの数字を大きくすると目的地より前のスピードがある時にロープを離します。

これでは目的地の所で離さず手前で離してしまって本来の目的地とは違う場所になります。

それが嫌だという方は目的地との距離ではなく検知エリアを作りそこにキャラクターが入ったらロープを離すようにするといいかもしれません。

MoveTowardsを使って同じ速度でロープの移動を行う

もっと簡単に等速度でロープを降りたい時はVector3.MoveTowardsを使います。

とVector3.Lerpでなめらかに移動させている箇所を

とします。

Time.deltaTimeのままだと遅いので5をかけました。

MoveTowardsを使うと、

MoveTowardsを使ったロープの移動サンプル

↑のように同じ速度で最初の位置から目的地の位置まで移動するようになります。

ちょっとだけダークソウル風のロープを降りる機能が出来ました!

アクションゲームでロープをつたって降りる機能を作りたい時は参考にしてみてください。

タイトルとURLをコピーしました