UnityのIKを使って物に手を合わせ、押せるようにする

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

今回は何か物があった時に、キャラクターがそれを押す事が出来るようにしたいと思います。

物を押すアニメーションを作成し、押している間はそのアニメーションにしてもいいのですが、今回は普通に歩いているアニメーションを使い、両手を物に合わせて押しているようにします。

今回の機能を作成すると、

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

手からレイを飛ばしブロックに接触していた場合に手を付くようにするので、肩手だけブロックに手を付く事もあります。

物を押す力は主人公の前方に加えている為、肩手だと力を弱めたり、ブロックの接触面の方向と主人公の方向の角度から力を計算するのもいいかもしれませんね。

力の加減については今回の記事ではやっておりません。(-_-)

スポンサーリンク

物を押すスクリプトPushBoxを作成する

物を押すスクリプトPushBoxを作成します。

PushBoxは主人公に設定してください。

右肩と左肩付近にRightRayTransformとLeftRayTransformを作成し、外側の上辺りにrayDistanceの長さのレイを飛ばします。
もしそこでBlockレイヤーに指定したゲームオブジェクトに当たっていた場合はその位置を保存します。

の部分で接触面から接触面の表面の向いている方向にwallHandOffset値の位置を右手の位置にします。

としている部分でhit.normalはレイが当たった面の角度で、Vector3.upがY軸の上向きで、
Quaternion.FromToRotationでその間の角度を算出出来ます。

それに元々のQuaternionであるtransform.rotationをかける事で、元の角度も加味する事が出来ます。

あとで試す時に、キャラクターの手がBlockを触っている時にBlockの角度を変更してみるとわかりやすいかもしれません。

右肩からのレイがBlockレイヤーに当たっていたらisTouchRightをOnにします。

左肩からのレイの処理も右肩と同じです。

次にウエイトの値を変化させる処理をみていきます。

↑は右手用のウエイトを変化させている部分で、右手がブロックに付いている場合はMathf.MoveTowardsを使って現在のウエイトを1に変化させ、付いていない場合は0へと変化させます。

こうすることで手が付いていない状態から付いている状態へ以降する時に滑らかに手の位置を移動させる事が出来ます。

左手の処理も同じです。

次にキャラクターがブロックと接触している時にブロックのRigidbodyに力を加える処理を見ていきます。

OnControllerColliderHitはCharacterControllerを持っていた場合に他のコライダと接触したら呼び出されます。

ぶつかった相手のコライダのレイヤーがBlockだったら主人公の前方に力を加えています。

次にIKの設定処理を見ていきます。

右手のIK、左手のIKのウエイトを設定し、それぞれの位置や角度に設定しているだけです。

これでPushBoxスクリプトが完成しました。

次に右肩、左肩からレイを出す位置RightRayTransformとLeftRayTransformゲームオブジェクトを作成します。

キャリー1

上のようにキャラクターの子要素に設定します。

キャリー2

Debug.DrawRayで見える化したレイが上のようになります。
このレイがBlockレイヤーに設定した物に当たった場合、そこの位置と角度に合わせて、右手と左手をもっていきます。

主人公が押すブロックの設定

押す物のサンプルとしてCubeを作り、インスペクタで上のようにRigidbodyを追加します。

Mass(質量)を50にします。

Collision DetectionはContinuousにします。

Collision Detectionは連続的な衝突検知の方法でBlockに主人公がめり込まないようにする為
Continuousにしました。Continuousは連続した検知をするのに適しています。

これで機能が完成しました。

キャラクターに設定したPushBoxスクリプトの設定は

PushBoxスクリプトの設定

↑のように設定しました。

Unityの実行ボタンを押して確認してみましょう。

キャリー4

上のようにBlockレイヤーに指定された物を押す事が出来るようになりました。

キャリー5

上のようにレイが外れている左手は物を触りません。

これでIKを使って物に手を合わせ、押す事が出来るようになりました。

主人公の移動スピードそのままなのと、歩いているアニメーションをそのまま使っているので、ダンボールのような軽い物を押している感じになっています。

押している状態になったら、アニメーションのスピードを落としたり、アニメーション自体を別に作成したり、といった対処が必要になるかと思います。

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