FPSを作ってみよう9-上半身のアニメーションだけ変更する-

今回は上半身のアニメーションだけを変更し、銃を構えた状態で歩く、走る、ジャンプする事が出来るようにしていきます。

上半身のアニメーションだけ変更するにはアニメーターのレイヤー機能とアバターの機能を使います。

アニメーターのレイヤー機能とアバター機能に関しては

Unityのレイヤー、アバターマスクを使って体の一部分を別のアニメーションにする
Unityで体の一部分だけ別のアニメーションに変更したい場合はAnimatorControllerのレイヤーとアバターマスクを使う事で実現出来ます。

も参考にしてください。

前回までの記事で

FPSを作ってみよう7-アニメーションの作成とUnityでの取り込み-
FPSゲームに使うアニメーションの作成とUnityでの取り込みまでを行います。アニメーション作成にはblender2.76bを使って作成していきます。

で銃を構える、撃つといったアニメーションを作成し、

FPSを作ってみよう8-IKを使って銃に手を合わせる-
FPSゲームでIKを使って銃に手を合わせていきます。またblenderでうまくアニメーションが出来ない人用に両手にIKをほどこしUnityのAnimationで銃を持ったり、構えたりするアニメーションを作成するやり方も載せています。

でIKを使って左手を銃を支えるような位置に移動させています。
もしまだ作り終えてない方は記事を参照して作成してみてください。

スポンサーリンク

上半身用のレイヤーを作成する

まずはMusasiAnimatorに上半身のアニメーションを管理するUpperBodyレイヤーを作成します。

アニメーターのレイヤーを作成する

↑のようにMusasiAnimatorのLayerを表示した状態で+をクリックします。

上半身用レイヤーの名前をUpperBodyにする

新しいレイヤーが出来るので名前をUpperBodyとしておきます。

UpperBodyの右側の歯車マークをクリックすると新しいウインドウが表示されますが、ここでAvatarMaskを設定してアニメーションで動かす部位を指定する事になります。

AvatarMaskはまだ作ってないので作成していきましょう。

上半身用のアバターマスクを作成する

アバターマスクの作り方

Projectウインドウで右クリック→Create→Avatar Maskを選択します。

アバターマスクの名前をUpperBodyにする

名前をUpperBodyにして、選択するとインスペクタにアバターマスクの情報が表示されます。

上半身だけが動くようにアバターマスクの設定をする

↑のように上半身だけを緑色にして、下半身は赤色に設定します。

UpperBodyレイヤーにUpperBodyアバターマスクを設定する

MusasiAnimatorのUpperBodyレイヤーの右側の歯車をクリックしてWeightを1、Maskにさきほど作成したUpperBodyアバターマスクを設定します。

これでUpperBodyレイヤーに状態や遷移を作成するとBase Layerのアニメーションに上半身だけ上書きしたアニメーションが再生されます。

上半身のアニメーションの状態と遷移を作成する

アニメーターで上半身用の状態と遷移を作成する

MusasiAnimatorにアニメーションパラメータBool型のWaitShotとTrigger型のShotを作成します。

GunIdleをデフォルト状態にし、GunIdleアニメーションを設定、
WaitShotにはWaitShotアニメーション、
ShotにはShotアニメーションを設定します。

それぞれ遷移を繋げて

GunIdle→WaitShotはWaitShotがtrue、Has Exit Timeのチェックを外す
WaitShot→GunIdleはWaitShotがfalse、Has Exit Timeのチェックを外す
WaitShot→ShotはShotがtrue、Has Exit Timeのチェックを外す
Shot→WaitShotは条件なしで、Has Exit Timeのチェックを入れる

Shot→WaitShotへの遷移はアニメーション終了まで待つので連続で撃ちたい場合はアニメーション速度を上げるか、アニメーションパラメータのShotをTriggerではなくBool型として条件で遷移させる方法に変えた方がいいかもしれません。

現状はとりあえずこのままでいきます。

Shot→WaitShotの遷移ではWaitShotの構え終わる前のアニメーションは再生したくないので、

ShotからWaitShotに遷移する時のアニメーションブレンド

とWaitShotのアニメーションを左にドラッグし93%と構え終わったあたりから再生するようにします。

キャラクター操作スクリプトMyCharaに銃を構える処理、銃を撃つ処理を追加

次にキャラクター操作スクリプトMyCharaに銃を構える処理、銃を撃つ処理を追加します。

waitShotは銃を構えているかどうかのフラグです。

Updateメソッドに銃を構える処理と銃を撃つ処理を追加します。

Input.GetButton(“Fire2”)に対応するボタンが押されていたら銃を構えます。

デフォルトではマウスの右ボタンが対応しています。

銃を構えている状態でFire1に対応するボタンが押されたら銃を撃ちます。

デフォルトでFire1にはマウスの左ボタンが設定されています。

上半身は銃を構えた状態で下半身は歩いている状態になるかどうか確認する

これでスクリプトが出来たのでUnityの実行ボタンを押して確認してみましょう。

上半身は別のアニメーションが再生されるかどうかSceneウインドウで確認

↑がScene画面で動作を確認した動画です。
銃を構えた状態で歩いているのを確認出来ると思います。
(^^)v

上半身を別のアニメーションにしたのでGameウインドウで確認

↑がGame画面(実際のゲーム画面)で確認した動画です。
上半身だけが別アニメーションになっているかどうかはわかりません。

常に手が揺れてしまう為、動かないようにする

さらに、銃を構えている時に手が横に揺れている為狙いを定めるのが難しそうですね・・・。

歩いている時や走っている時はもちろん体が上下に動くのでいいと思いますが、せめて移動していない時ぐらいは狙いを固定出来るようにしましょう。

手が横に揺れているのはBase LayerのIdleのアニメーションが再生されているからです。

Base LayerのIdleにGunIdleを設定してください。

これで手が横に揺れる事はなくなりました。
ただ今度はまったく動かなくはなりますが・・・・(^_^;)

手を動かしたい場合はGunIdleのアニメーションで常に腕を動かすアニメーションにしておくといいかもしれません。

それでは再度確認してみましょう。

Game画面で上半身がブレないか確認する

↑がGame画面で確認した動画です。

動いていない時は完全に腕が動かないのでやっぱりGunIdleのアニメーションを修正した方がいいかも・・・(T_T)
アニメーションじゃなくボーンを少し揺らすというのでもいいかなぁ・・・。

Scene画面で上半身がブレないかどうか確認する

↑がScene画面で確認した動画です。

銃を構えた状態から通常の持っている状態への切り替わりが早すぎるのでうまい具合に調整してください。
WaitShot→GunIdleの遷移のアニメーションブレンドを調整してください。

でもまぁ・・・WaitShot→GunIdleの遷移画像を載せてないので上の動画のようにみんながわたくしと同じブレンドにしてるとは限りませんね・・・(-.-)

これで上半身のアニメーションをレイヤーとアバターマスクを使って変更する事が出来るようになりました。

銃を構える時だけIKを有効にし銃に左手を添える(2019/12/09に追記)

歩いている時等は左手にIKを働かせず、銃を構えた時に初めてIKを有効にし、左手を銃に添えたい事もあります。

そんな時はAnimatorControllerのStateにビヘイビアを取り付けて、そのState(状態)に入った時や抜けた時にIKのウエイトを操作することで実現出来ます。

MusashiAnimatorのUpperBodyレイヤーを選択し、Idle状態を選択してインスペクタのAdd Behaviourボタンを押して新しくLeftHandIKBehaviourビヘイビアスクリプトを作成します。

FPSの上半身用のレイヤーでIdleを選択する

FPSの上半身用のレイヤーのIdleにビヘイビアを取り付ける

LeftHandBehaviourはIdle状態に取り付けたのでIdle状態に入った時や抜けた時に実行されるメソッドを修正していきます。

OnStateEnterは状態に入った時に呼ばれるのでそこで引数で受け取ったanimatorからムサシに取り付けているHandIKスクリプトを取得し保持します。

Idle状態に入った時にはIKのウエイトを0にしたいのでHandIKスクリプトのReSetWeightメソッドを呼び出します。

HandIKスクリプトは後で修正するので置いておきます。

OnStateExitはIdle状態を抜けた時に呼ばれるので、そこでHandIKスクリプトのSetWeightメソッドを呼び出し、ウエイトを1にします。

これで上半身用のレイヤーのIdle状態にビヘイビアスクリプトを取り付ける事が出来ました。

次にHandIKスクリプトに追記をします。

changingWeightはウエイトを変更中かどうか、ikWeightはIKのウエイト、destinationWeightはウエイトの目的値、changeSpeedはウエイトを変更するスピードです。

Updateメソッドではウエイトを変更中であれば現在のウエイトを目的のウエイトへと変更します。

Mathf.Approximatelyを使ってfloat値の比較をし、現在のウエイトと目的のウエイトが同じになったらウエイトの変更を終了します。

OnAnimatorIKで左手のIKのウエイトを1にしていましたが、そこをikWeightに変更します。

SetWeightとReSetWeightは目的のウエイトを設定し、ウエイトを変更中にしています。

これで通常の移動時はIKのウエイトが0で、銃を構えた時は1になります。

ここまでで銃を構えた時だけ上半身のアニメーションの上書きが出来ましたが、さらに左腕をBase LayerのアニメーションにするならUpper Bodyレイヤーに使用しているUpper Bodyアバターマスクの左腕部分を無効化します。

FPSで上半身の右側だけのレイヤーにする

左腕部分用のレイヤーを新たに作成し、UpperBodyレイヤーと同じように状態と遷移を作成します。

FPSで左腕用のレイヤーを作成

新しくアバターマスクを作成し、左腕部分だけが有効になるようにして、AnimatorControllerの左腕用のレイヤーの右の歯車を押して設定します。

FPSで左腕用のアバターマスクを作成

これで歩きや走りの時はBase Layerのアニメーション、銃を構えた時にBase LayerをUpperBodyレイヤーの上半身の右側、LeftHandレイヤーの左側で上書きすることになります。

他にもっと簡単なやり方がありそうですね。

次回は主人公キャラが視点を上下させた時に上半身の角度を視点の方向に曲げ銃口の先も視点の先になるようにしていきます。

最後の動画で既にその機能が出来ていますが、その部分は追記部分なので無視してください。(^_^;)

コメント

  1. そばぼうろ より:

    いつも参考にさせて頂いております。
    GunIdle時のAnimationで右手は銃を持ったまま、左手は手ぶらの状態にしていました。

    そうすると左手のIKがきいておかしなポジションになるのですが、
    Animatorの遷移毎にIKを有効にさせる方法はないのでしょうか。
    もっともこの記事のようにGunIdle時も両手で銃を持った状態にすればよいのですが…。

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