Unityで一人用フリーフォールを作ってみました

今回は色々なゲーム作りのテクニック(と言えるほどでもない)を使って、一人用のフリーフォールアトラクションを作ってみました。

フリーフォールをゲームに取り込むなんて方はまぁほとんどおられないと思いますので、中で使っているテクニックを他の機能を作る時に使ってみてください。

テクニックと言っても以前から使っている物を使っただけなので、目新しいものがあるわけではありませんが・・・・。

↑のような感じです。

本当は自己満足のおまけ程度にフリーフォールを作ってみましたと動画をアップし記事を作るだけの予定だったんですが、途中からなんやかんや付けたしてそれなりのものが出来たので作り方も公開する事にしました。

スポンサーリンク

この機能を作ると学べる事

今回の一人用フリーフォール機能を作っていくと以下のような事柄のテクニックを学ぶ事が出来ます。

  • 座るアニメーションの作成
  • アニメーションの再生位置に合わせてキャラクターの位置と角度を合わせる方法
  • Animationウインドウでの簡易アニメーションの作成
  • 3人称視点カメラと1人称視点カメラの切り替え
  • IKを使ってキャラクターの上半身をカメラの方向に向かせる
  • IKのウエイトを操作し徐々に手の位置と角度を動かす
  • キャラクターの状態を変更し、通常移動、フリーフォールに乗った状態等の切り替えをする方法
  • キャラクターを状態に応じて他のゲームオブジェクト(フリーフォール)の子要素にして一緒に動かす方法
  • キャラクターの状態に応じてコンポーネント(CharacterControllerやAnimator)の設定を変更する
  • 状況に応じてUIを表示・非表示を切り替える
  • ざっと挙げるとこんな感じですが、ゲームを作る時に非常に使えるテクニックだと思います。

    一人用フリーフォール機能の概要

    今回作成する一人用フリーフォールの機能の概要を説明します。

  • フリーフォールの近くにキャラクターが近寄った時に特定のキーを押したらフリーフォールに乗る事が出来るようにします。
  • フリーフォールに乗ったらキャラクター視点のカメラに切り替えて自分がフリーフォールに乗った時のような視点で辺りを見渡す事が出来るようにします。
  • フリーフォールの昇る高さ、昇るスピード、降りるスピード等はインスペクタで設定出来るようにします。
  • フリーフォールの開始と降りる場合はUIのボタンを押して操作するようにします。
  • フリーフォールから降りたら通常通りキャラクターを動かす事が出来るようにします。
  • とりあえず機能としてはこんな感じになります。

    細かい部分に関してはこれから紹介していきます。

    座る、立ち上がるアニメーションの作成

    まずはフリーフォールに乗る時、降りる時のアニメーションをBlenderで作成します。

    Blenderでアニメーションを作成するにはキャラクターのモデルにボーンが設定され、ボーンの動きで動くメッシュが設定されている必要があります。

    Blenderでアニメーションを作成するにはボーンを直接動かす事でも作成出来ますが、BlenderのRigifyを設定して作成する場合は

    MakeHumanで作成したキャラクターをBlenderに取り込み、ボーンを設定しリグを取りつけます。Unityで使うアニメーションを作成する時に便利です

    ↑の記事を参照して設定してください。

    Rigifyを使ってアニメーションを作成するやり方は

    Unityで使用するキャラクター用のアニメーションをBlenderを使って作成していきます。作成方法を学べば自分のゲームに自前のアニメーションを使うことが出来ます。

    ↑の記事を参照してください。

    アニメーションの細かい部分に関しては上記の記事を見て作り方を参照してもらうとして、わたくしが作ったアニメーションをフレーム毎のポーズで紹介したいと思います。

    あらかじめBlenderのアニメーションのフレームレートを60にしてUnityと合わせておきます。

    FreeFallアニメーションのフレームレートを60にする

    キャラクターモデルが置いてあるレイヤーとは別のレイヤーに椅子の形状のモデルをプリミティブ素材で作成しておきます。

    椅子自体はキャラクターが椅子に手をついて座る時の目安として使用するだけなのでサイズを調整するだけで適当に作ります。

    椅子をプリミティブ素材で作成

    レイヤーは↑の画像の下の方にある四角いマス目を選択する事で、そのレイヤーにあるオブジェクトを表示することが出来ます。

    複数のレイヤーを選択したい場合は、Shiftキーを押しながらレイヤーを押していきます。

    オブジェクトを別のレイヤーに移動したい時は移動元のオブジェクトを右クリックで選択した状態でMキーを押し移動先のレイヤーを押します。

    これで準備が出来たので椅子に座るアニメ―ションのフレーム毎のポーズを紹介します。

    椅子に座るアニメーションのフレーム毎のポーズ

    ↑のようなポーズをフレーム毎に設定しました。

    次は座っている状態から立ち上がるアニメーションです。

    椅子から立ち上がるアニメーションのフレーム毎のポーズ

    ↑のような感じのポーズを設定しました。

    細かい所は調整してください。

    今回の機能を作るにあたって一つだけ必要になるポーズが椅子に手をかける部分です。

    これは椅子の位置と手を付いた時のアニメーションの位置を合わせる為に使用します。

    これでアニメーションの作成が完了しました。

    フリーフォールアトラクションの舞台の作成

    一人用フリーフォールを設置する為の舞台(地面)は単純に3DオブジェクトのCubeやPlaneで作ってもいいんですが、今回は眺めを良くする為にTerrainで地面を作っておきます。

    Terrainで地面を作成するやり方は

    UnityのツールであるTerrainを使ってゲームに使用するフィールドを作成していきます。

    を参照して作成してみてください。

    わたくしは

    フリーフォール機能用のTerrain

    ↑のような感じで作りました。

    フリーフォールが高くまで上がる事も考慮して周りの壁を高くしてみました。

    周りの景色を楽しめるようにするならTerrainのサイズを大きく作るといいかもしれません。

    わたくしの場合は大きく作るとパソコンのスペックの影響でクラッシュする為、WidthとLengthを200にしました。

    Terrainには木にコライダを設定しTerrainの機能で木を生やしました。

    フリーフォールの作成

    次にフリーフォールを作成していきます。

    フリーフォールゲームオブジェクトの作成

    Blender等でフリーフォールの素材を作った方が綺麗になりますが、今回はUnityのプリミティブ素材を使って椅子と体を固定するバーを作成します。

    ヒエラルキー上で右クリック→Create Emptyを選択し名前をFreeFallとします。

    FreeFallの子要素にCubeをいくつか組み合わせてScaleを調整し椅子を作ります。

    またFreeFallの子要素に空のゲームオブジェクトを作成し、名前をBarとし椅子の背もたれの上の真ん中辺りに移動します。

    固定バーもCubeをいくつか組み合わせて作りますが、Barの子要素に配置します。

    これはキャラクターが椅子に座ったらBarを回転させBarを下ろすようにする為です。

    フリーフォールの階層

    ↑FreeFallの階層で、CubeとCube(1)が椅子を表していてCube(1)が背もたれの部分です。

    実際のフリーフォール画像

    ↑が作成した椅子と固定バーです。

    Cube(1)の子要素にあるLeftFootPositionは椅子に座る時の左足の位置、GetOffLeftFootPositionは椅子から立ち上がった時の左足の位置を空のゲームオブジェクトで作ったものです。

    座る時と立ちあがった時の左足の位置

    ↑のように足の位置と角度を作成します。

    角度は足が水平になるようにします。そうしないとアニメーションが足の角度に合わせて斜めになってしまいます。

    本来であれば手を椅子に付けた時のアニメーション時に、椅子の背もたれに手の位置を合わせたいところですが、手の場合は角度を合わせるのが難しい為に足にしました。

    文章を見ているだけだと解り辛いですが、後で試しに手で合わせてみてください。

    アニメーションが手の位置と角度に合わせて斜めになってしまうのがわかると思います(もちろん合わせ方によりますが)。

    Barの子要素に空のゲームオブジェクトでRightHandとLeftHandを作成し固定バーの右手の位置と左手の位置がくる場所に移動させます。

    固定バーを持つ右手と左手の位置

    ↑のような位置と角度になります。

    LeftFootPosition、GetOffLeftFootPosition、RightHand、LeftHandは後でUnityを実行しながら位置と角度を合わせるのでだいたいの場所に位置していれば問題ありません。

    これでフリーフォールのゲームオブジェクト群が出来上がりました。

    フリーフォールゲームオブジェクトに取り付けるスクリプトの作成

    次にフリーフォールのゲームオブジェクトに取り付けるスクリプトを作成していきます。

  • フリーフォール自体にキャラクターを検知するエリアを作成し、キャラクターがエリア内に侵入した時にUIの表示等を行うスクリプト。
  • フリーフォールを動かすスクリプト。
  • を作成します。

    キャラクター検知スクリプト

    まずはFreeFallにSphereColliderを取り付けIs Triggerのチェックを入れ、キャラクター検知エリアを作ります。

    フリーフォールのキャラクター検知エリア

    キャラクターを検知するエリアは、フリーフォールの前方辺りに置き後ろの方では検知しないようにします。

    これはアニメーションが椅子に手を付く時に、椅子に設定した位置と合わせるので、後ろから合わせると椅子を通過してアニメーションしてしまう為です。

    その為、前方から横からしか座る事が出来ないようにしておきます。

    キャラクターを検知するスクリプトSearchCharaを作りFreeFallに取り付けます。

    isEnterフラグでキャラクターが範囲内にいるかどうかを判断します。

    OnTriggerEnterでキャラクターを検知しキーを押す事を促すUIを表示します。

    OnTriggerExitはキャラクターが検知エリアから出た時の処理でUIを非表示にしています。

    Updateではキャラクターが範囲内にいる時に、SPACEキーを押したらキャラクター操作スクリプトFreeFallCharaの状態をフリーフォールに座る状態に変更します。

    状態を変更する時はキャラクターがノーマル状態の時だけにします。

    フリーフォールを管理するスクリプト

    次はFreeFallを管理するFreeFallスクリプトを作成します。

    FreeFallスクリプトではフリーフォールが到達する位置、上がっていく速度、下がっていく速度、上に到達してから落ちるまでの秒数等をpublicで宣言し設定値を変更出来るようにします。

    フリーフォールをスタートするボタン、フリーフォールから降りるボタンのUIをオン・オフする為UIのゲームオブジェクトを設定出来るようにしています。

    またフリーフォールの固定バーは『開く』と『閉じる』というアニメーションを後で作成しますので、FreeFallスクリプトでアニメーションを切り替えられるようにします。

    Updateメソッドではフリーフォールの状態によって処理を分岐させ、FreeFallState.up時にはVector3.MoveTowardsで一定スピードで上昇するようにしています。

    FreeFallState.wait状態は上に昇りきってからの状態で、指定時間が経過したらFreeFallState.down状態へと移行させます。

    指定秒数を計測しているのがCountDownメソッドで、コルーチンを使って指定秒数経過後にフリーフォールの状態をFreeFAllState.downに変更しています。

    コルーチンに関しては

    Unityでコルーチンを使うと定期的に何らかの処理を行える事が出来るようになります。一見解り辛いけど使い方がわかれば便利かも!?

    を参照してください。

    FreeFallState.down状態ではVector3.Lerpを使って元の位置へと移動させていますが、Vector3.MoveTowardsと違って最後はスピードが落ちます。

    SetStateメソッドではフリーフォールの状態を変更し、フリーフォールの操作ボタンのオン・オフをします。

    オン・オフをするタイミングは状態がFreeFallState.up(上がっていった時)にオフ、FreeFallState.none(フリーフォール操作を何もしていない時)にオンとしています。

    OnOffButtonメソッドは受け取った論理値でボタンのゲームオブジェクトをオン・オフしているだけです。

    SetBarメソッドは固定バーのアニメーションを操作するメソッドです。

    IsMoveBarメソッドは固定バーの開け閉めのアニメーションが再生中かどうかを判断するメソッドで、固定バーのAnimatorのClose状態にいる時でアニメーションの再生が終わっていない時にfalseを返し、それ以外はすべてtrueを返します。

    IsOpenBarは固定バーが完全に開いた状態になっているかどうかを判定します。

    判定の条件は現在のAnimatorの状態がIdle状態にいるかどうかで判断しています。

    これでFreeFallスクリプトの作成が終了しました。

    キー押しを促すUIの作成

    FreeFallスクリプトでキャラクターが検知エリア内に入った時、出た時にSPACEキーを押す事を促すUIをオン・オフしていますがそのUIを作成します。

    ヒエラルキー上で右クリック→UI→Textを選択し、Canvasの名前をInfoUIとします。

    フリーフォールのキー押しを促すUI

    ↑のようにInfoUIの子要素のTextに文字を入力し色やサイズ、位置を調整します。

    これでキー押しを促すUIの作成も終了しました。

    フリーフォール操作ボタンの作成

    次はフリーフォールに乗った時に操作するボタンUIの作成をします。

    ヒエラルキー上で右クリック→UI→Canvasを選択し名前をFreeFallButtonとします。

    子要素にUI→Buttonを2つ作成し、名前をStartとCancelとします。

    フリーフォール操作ボタン

    ↑のような階層になります。

    ボタンの位置等を調整し、左下と右下にそれぞれ表示されるようにします。

    フリーフォール操作ボタンのStartとCancel

    次にFreeFallButtonにFreeFallButtonスクリプトを新しく作り取り付けます。

    freeFallはFreeFallスクリプト、freeFallCharaはキャラクター操作スクリプトをインスペクタで設定出来るようにしておきます。

    StartFreeFallメソッドは、Startボタンを押した時に実行するメソッドでフリーフォールの状態が何もしていない状態(FreeFallState.none)の時に、フリーフォールを到達点まで上昇させる状態(FreeFallState.up)にしています。

    EndFreeFallメソッドはCancelボタンを押した時に実行するメソッドで、何もしていない状態の時にフリーフォールの固定バーを開き、操作用UIを非表示にした後、キャラクターの状態をノーマルへと移行させる状態(State.transitionToNormal)へと変更してます。

    StartボタンのインスペクタでOn Click()にFreeFallButtonスクリプトのStartFreeFallメソッド、CancelボタンのインスペクタでOn Click()にFreeFallButtonスクリプトのEndFreeFallメソッドを設定してください。

    ボタンを押した時に実行したいメソッドを設定するやり方は

    Unityでタイトル画面に表示するスタートボタン、ゲーム終了ボタンのUIを作成していきます。シーン移動や画面遷移をしたい時にボタンを押す事で移動出来るようにします

    を参照してください。

    これでフリーフォール操作ボタンの作成は終了です。

    固定バーのアニメーションの作成

    固定バーの開閉のアニメーションを作成します。

    UnityエディターのWindowからAnimationを選択しAnimationビューを表示します。

    Animationビューを表示した画像

    ↑のようにAnimationビューが表示されるのでFreeFallの子要素のBarを選択しCreateボタンを押します。

    Animationビューでのアニメーションの作成は

    ステータス画面UIのオンオフをUnityのAnimationで行います。UIゲームオブジェクトのオン・オフで単純に消したり登場させたり出来ますが、少しだけ演出を加えてUIを登場させてみましょう。
    Unityのゲームで使用している銃で弾を撃った時に銃のトリガーのアニメーションを作成していきます。

    辺りを参照して作成してみてください。

    固定バーのアニメーションを作成

    ↑のようにIdle、Close、Openの3つを作成します。

    Idleはずっと開いたままの状態、Closeは開いた状態から閉じた状態、Openは閉じた状態から開いた状態へとアニメーションをさせます。

    プロパティにPositionも入っていますが・・・、実際にはBarのRotationしか変更していません。

    Closeのアニメーションだけ見てみましょう。

    固定バーのCloseアニメーション

    ↑のように開いた状態から閉じた状態になるようにBarを回転させています。

    Openはこの逆を作成するだけです。

    固定バーのAnimatorではアニメーションパラメータにBool型のCloseを作成します。

    固定バーのAnimator

    ↑のように遷移を作成します。

    Idle→CloseはCloseがtrue
    Close→OpenはCloseがfalse

    それぞれHas Exit Timeのチェックを外しておきます。

    Open→Idleは、Has Exit Timeにチェックを入れアニメーションの終了とともにIdleに流れるようにしておきます。

    これで固定バーのアニメーションの作成が終了しました。

    ここまでで、FreeFallに関する機能の作成が終わりました。

    次は、スクリプトを設定したFreeFallゲームオブジェクトのインスペクタでFreeFallButtonやInfoUIを設定します。

    FreeFallのインスペクタの設定

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

    キャラクターの作成

    次にフリーフォールに乗るキャラクターを作成していきます。

    フリーフォールに乗るまではキャラクターを普通に操作出来るようにし、フリーフォールに乗ったらキャラクターの視点をマウス操作で変更出来るようにします。

    キャラクターの設置

    今回使用するキャラクターモデルはStandardAssets→Characters→ThirdPersonCharacter→Models→Ethanを使用します。

    ヒエラルキー上で右クリック→Create Emptyを選択し空オブジェクトを作成し名前をCharacterとします。

    Characterの子要素にEthanをドラッグ&ドロップします。

    キャラクター操作スクリプト等は全てCharacterに取り付けEthanには取り付けません。

    こうすることで主人公キャラクターの見た目を変更したい時はEthanを削除し別のモデルをCharacterの子要素、CharacterControllerのコライダの調整をするだけで実現する事が出来ます。

    CharacterにはCharacterControllerの取り付けとコライダのサイズ調整をします。

    ここら辺は

    Unityでキャラクターを移動する為に準備しておく事と、移動させる為に必要な事を考える

    を参照してください。

    キャラクター用AnimatorControllerの作成

    キャラクターのAnimatorに設定するAnimatorControllerを作成します。

    Assetsフォルダ内で右クリック→Create→AnimatorControllerを選択し名前をFreeFallとします。

    フリーフォールキャラクター用AnimatorController

    ↑のようにアニメーションパラメータにFloatのSpeed、BoolのSitDownを作成し、状態と遷移を作成します。

    Idleには立っているアニメーション、Runには走っているアニメーション、SitDownには座るアニメーション、StandUpには立ち上がるアニメーションを設定します。

    Idle、SitDown、StandUpの状態を選択し、

    フリーフォール用AnimatorのFootIKにチェックを入れる

    ↑のようにFootIKの項目にチェックを入れます。

    FootIKにチェックを入れると足元のIKが有効になります。

    座った状態で確認すると

    FootIKによって座った時の状態が変わる

    のようにFootIKにチェックを入れていないと足が地面にうまく接地出来ていません。

    立ちあがる時は

    FootIKによって変わる立ちあがる時のアニメーション

    ↑のようになります。

    IKが有効になっていると足を付いた時にそこに固定され足元がブレないようになります。

    詳しくは

    UnityのAnimator ControllerのSpeed、Mirror、Foot IK項目が何かを見ていき、スクリプトから項目の操作をしてみます。

    を参照してください。

    Idle→RunはSpeedが0.1より上
    Run→IdleはSpeedが0.1より下
    Idle、Run→SitDownはSitDownがtrue
    SitDown→StandupはSitDownがfalse

    それぞれのHas Exit Timeのチェックを外しておきます。

    StandUp→Idleは、Has Exit Timeのチェックを入れアニメーションが終わったらIdleに流れるようにしておきます。

    Base Layerの右の歯車をクリックしIK Passにチェックを入れます。

    フリーフォールキャラクターのOnAnimatorIKを呼び出す

    IK Passにチェックを入れるとスクリプトでOnAnimatorIKが呼び出されるようになります。

    これでAnimatorControllerの作成が終わったのでCharacterのAnimatorに設定してください。

    キャラクター操作スクリプトの作成

    次にキャラクター操作スクリプトを作成します。

    スクリプトが長いので分割して紹介します。

    フィールド等の宣言部

    まずはフィールド等の宣言部です。

    キャラクターは通常の移動状態やフリーフォールに乗っている状態などで操作の切り替えが出来るようにしてます。

    その為、キャラクターの状態を列挙型で作成しておきその都度状態を変更します。

    targetPosとtargetRot、destinationSpeedは右手が椅子に触った時のアニメーションで位置と回転を合わせる場合のフィールド値で今回は使用していません。

    これらのフィールドを使った処理はコメント化しています。

    一部フィールドの説明をしていきます。

    moveSpeedはキャラクターが走るスピード
    changeCameraはキャラクターがフリーフォールに乗った時にカメラをキャラクター視点のものに切り替えるスクリプトを入れます。
    leftFoot、getOffLeftFootはFreeFallに作成したLeftFootとGetOffLeftFootを指定します。
    cameraSpeedはフリーフォールに乗っている時のキャラクターの視点の移動スピードを指定します。
    myCameraはキャラクター視点のカメラを設定します。
    xRotate、yRotateはカメラの視点を変更する時に使用するフィールドです。
    initCameraRotはキャラクター視点のカメラの初期の角度を入れておくフィールドです。
    cameraRotateLimitはキャラクター視点のカメラが回転出来る限度を指定します。
    rightHand、leftHandは固定バーを持つ時の手の位置と角度で、FreeFallに作成したRightHand、LeftHandを指定します。
    handIKWeightは手の位置を段々と動かしているように見せる為のウエイトで、0だと何もしない、1だと完全に指定の位置になります。
    weightSpeedはIKのウエイトを変更するスピードを指定します。

    Startメソッド

    Startメソッドでは初期設定等をしています。

    コンポーネントの取得と移動値の初期化、カメラの初期角度を保持するという事をしています。

    Updateメソッド

    Updateメソッドではキャラクターの状態に応じて処理を分けています。

    キャラクターの状態事に処理を確認していきましょう。

    ノーマル状態

    まずは通常の状態について見ていきましょう。

    ノーマル状態では普通にキャラクターの移動処理を記述しているだけなので割愛させて頂きます。

    座り終えるまでの状態

    フリーフォールに座り終わるまでの状態を見ていきます。

    状態がState.sitDownの時はキャラクターがフリーフォールに座ろうとしている状態なので、ここでアニメーションの再生位置と椅子の位置とを合わせます。

    アニメーションがSitDownを再生している時で、最初の再生の時にanimator.MatchTargetで左足の位置を指定した位置に合わせます。

    椅子に座るアニメーションの0.100から0.360の再生位置の時に、指定した位置に合わせるように設定しています。

    ここの数値は座るアニメーションで椅子に手を合わせているのが36%辺りなので、10%から36%のアニメーションの間に指定した位置に合わせるようになります。

    数値によってはうまく合わない可能性もあるので調整してください。

    else以下では右手の位置で、アニメーションを合わせる時の処理を記述しています。

    手で合わせた場合は最終的にキャラクターが斜めになってしまう事がある為、キャラクターを椅子と水平に合わせる為に調整しています。

    else以下のこれらの処理は今回は使っていないのでコメント化しています。

    elseに行く条件は座るアニメーションが終わった時なのでキャラクターの角度をきっかりとした角度に書き換えています。

    ここで0, 270, 0と角度を指定していますが、フリーフォールの角度によってはY軸の角度を別の角度にする必要が出てきます。

    座り終わったらキャラクターの状態をフリーフォールに乗りこみが完了した状態へと移行する状態に変更します。

    フリーフォールへの移行状態

    フリーフォールに座ってから固定バーが降りるまでの状態を見ていきましょう。

    フリーフォールに乗りこみ完了までの状態(State.transitionToFreeFall)では、固定バーが動いてなければChangeCameraスクリプトのChangeメソッドを呼び出してキャラクター視点のカメラへと変更し、フリーフォール操作ボタンを有効にして、キャラクター状態をフリーフォール状態(State.freeFall)にしています。

    つまり固定バーが閉まった時にカメラを切り替え、フリーフォールの操作が出来るようにしています。

    フリーフォールに乗りこみ完了状態

    フリーフォールに座って固定バーがしまってフリーフォールを操作出来る状態について見ていきます。

    フリーフォールへの乗りこみが完了したらIKのウエイトを少しづつ増やし、両手をそれぞれ指定した位置と角度に段々と移動するようにします。

    またマウスの右ボタンを押している時は、カメラの視点を変更出来るようにしています。

    フリーフォールから降りる状態

    最後にフリーフォールから降りる状態を見ていきます。

    フリーフォールから降りてノーマル状態へと移行する状態の時は、まず固定バーが完全に開いているかどうかを調べます。

    固定バーが開いていたら、アニメーションパラメータのSitDownをfalseにし、立ち上がるアニメーションへと移行させます。

    立ち上がる時のアニメーションの20%から40%にかけて左足の位置をGetOffLeftFootの位置に合わせます。

    キャラクターがIdle状態へと移行したらCharacterControllerの有効化、親要素の解除、AnimatorのApply Root Motionの無効化をしキャラクターをノーマル状態にします。

    いきなりCharacterControllerの有効化、親要素の解除、AnimatorのApply Root Motionの無効化という話が出てきて解り辛いですが、これらはフリーフォールに乗りこむ時に逆の事をしているのでそれを元に戻しているだけです。

    CharacterControllerを無効化したのはコライダが椅子にひっかかってうまく動作しない為、キャラクターの親をFreeFallにするのはFreeFallと一緒に移動させる為、

    Apply Root Motionにチェックを入れるのはMatchTargetを使用する為に行っています。

    これらの処理は次に紹介するSetStateメソッドで行っています。

    SetStateメソッド

    SetStateメソッドはキャラクターの状態を変更する時の処理で自身のスクリプト、または他のスクリプトから呼び出して状態を変更します。

    状態を変更したらそれぞれの状態に応じて処理をしています。

    ノーマル状態の時はアニメーションパラメータのSpeedを0にして、フリーフォールに乗った時のSpeedの値を0にしてIdle状態から始まるようにしています。

    フリーフォールに座る時の状態ではCharacterControllerの無効化、Apply Root Motionの有効化、アニメーションを座るアニメーションにしています。

    フリーフォールに完全に乗りこむまでの状態では、キャラクターの親をFreeFallにしFreeFallスクリプトのSetBarメソッドを呼び出して、フリーフォールの固定バーを下ろしています。

    また、キーを押す事を促していたUIを非表示にしています。

    フリーフォールに乗りこんだ状態の時は、キャラクター視点のカメラの変更値とIKのウエイトを初期化しています。

    フリーフォールを降りてノーマル状態へと移行している状態の時は、カメラをキャラクター視点から通常のカメラへと切り替えています。

    GetStateメソッド

    GetStateメソッドはキャラクターの現在の状態を返すだけです。

    LateUpdateメソッド

    LateUpdateメソッドではカメラの角度を変更しています。

    キャラクターの状態がState.freeFallの時にカメラの角度変更値を限界角度内に納めて計算し、それをキャラクター視点カメラのローカル角度に入れています。

    Mathf.Clampは第1引数の値を第2引数と第3引数の間に収める為の標準メソッドです。

    カメラの角度をローカル角度で計算しているのは、カメラはキャラクターの子要素に設置する為で、myCamera.rotationを変更するとキャラクターの向きに関係なくカメラ角度をワールドの角度で変更してしまう為おかしくなります。

    OnAnimatorIKメソッド

    OnAnimatorIKメソッドは標準のメソッドで、キャラクターに取り付けているAnimatorのIK Passにチェックを入れると呼び出されるようになります。

    OnAnimatorIKでは、キャラクターがフリーフォールに乗りこんでいる状態の時に処理を行っています。

    SetLookAtWeightでIKのウエイトを設定し、SetLookAtPositionでキャラクターの視点の先をカメラの前方100mの辺りに向けさせています。

    SetLookAtWeightの第1引数が全体のウエイト、第2引数が体のウエイト、第3引数が頭のウエイト、第4引数が目のウエイト、第5引数がキャラクターのモーションの制限です。

    今回の場合は第2引数で体の向きをあまり動かさないように0.2f、第5引数で体のモーションの制限を半分の0.5fにして体が変に曲がらないようにしています。

    SetIKPositionWeight、SetIKRotationWeightで両手の位置と角度のウエイトを設定し、

    SetIKPosition、SetIKRotationで指定した位置と角度に両手を設定しています。

    ウエイトはUpdateメソッド内で段々と増やしていますので段々とIKが働くという感じになっています。

    これでキャラクター操作スクリプトFreeFallCharaが完成しました。

    Unity実行中にフリーフォールに座らせ、RightHand、LeftHand、LeftFootPosition、GetOffLeftFootPositionの位置と角度を調整します。

    固定バーに左手の位置を合わせる

    ↑はUnityエディター実行中にLeftHandの位置と回転を調整し、固定バーの部分に左手を合わせるようにしています。

    位置と角度が決まったらLeftHandのインスペクタのTransformで歯車のアイコンをクリックし、Copy Componentを選択します。

    その後Unityエディターの実行をやめて、LeftHandのインスペクタのTransformの歯車をクリックしPaste Component Valuesを選択します。

    これで実行中のTransformの位置と角度を停止した後のTransformに反映する事が出来ます。

    詳しいやり方は

    Unityでキャラクターの手の位置に正確に武器を持たせるように調整します。なんとなく持たせる位置を設定していた人には朗報かも!?

    を参照してください。

    LeftFootPositionは位置とY軸の角度、GetOffLeftFootPositionは位置だけを調整し、角度を変更しないようにします。

    角度を変更すると足の角度がその角度に合わせて傾くので全体のアニメーションも傾きます。

    LeftFootPosition、GetOffLeftFootPositionの位置は大体の位置を設定し実際に椅子に座らせたり立たせたりして調整していきます。

    キャラクター視点カメラ、その他のカメラの作成

    フリーフォールに乗った時のキャラクター視点のカメラとキャラクターを斜め前から写すカメラ、フリーフォールを遠目に写すカメラを作成します。

    キャラクター視点カメラ

    Characterの子要素に右クリック→Cameraを作成し、名前をMyCameraとします。

    カメラのField Of Viewを90にして視野角を広げます。

    Clipping PlanesのNearを0.01にしてより近い位置から描写できるようにしておきます。

    MyCameraをキャラクターの目の位置に移動させます。

    フリーフォール用のキャラクター視点カメラ

    IKを使ってキャラクターの体を曲げた時に、カメラの位置も調整しなければいけない為Ethanのボーンの子要素に空オブジェクトでカメラ位置を作ります。

    空オブジェクトで作ったカメラ位置

    EthanHead1のボーンに合わせてCameraPositionの位置が動きます。

    MyCameraにMoveMyCameraという新しいスクリプトを作り取り付けます。

    インスペクタでCameraPosには先ほど作ったCameraPositionを設定します。

    LateUpdateメソッド内でMyCameraの位置を常にCameraPositionの位置に変更しています。

    ややこしい感じになっていますが、IKで体を傾けているのとか、カメラ自体の角度を変更していたりするのでこんな感じになったような記憶があります。

    もっと簡潔にキャラクター視点カメラの操作が出来るような気もしますが、まぁそこら辺は試してみてください。

    キャラクターを斜め前から写すカメラ

    次にCharacterの子要素にもうひとつカメラを作成し名前をTheSkyCameraとします。

    カメラのインスペクタでAudio Listenerを削除しておきます。

    Audio Listenerは音声の耳の役割をするものでゲーム内でひとつあればいいので、メインカメラにすでに取り付けてあるのでTheSkyCameraの方は削除しておきます。

    MyCameraのAudio Listenerを削除しなかったのは、こちらはメインカメラと切り替えるカメラなので、どちらか一方にはAudio Listenerが必要になるからです。

    キャラクターを斜め前から写すカメラ

    ↑のように、キャラクターを斜め前から写すような位置と角度に変更します。

    Viewport RectでX、Yを0.7、W、Hを0.3にします。

    フリーフォールの動きを確認するカメラ

    フリーフォールの動きを遠目から確認出来るカメラも作成しておきます。

    ヒエラルキー上で右クリック→Cameraを選択し名前をFixedPointCameraとします。

    こちらはCharacterの子要素ではなく、親要素を持たないように作ります。

    カメラの設置階層

    ↑のようにCharacterの子要素には置きません。

    FixedPointCameraの位置と角度を調整し、

    フリーフォールを遠目に写すカメラ

    ↑のようにフリーフォールを遠目に写すようにします。

    カメラのViewport RectでXを0、Yを0.7、W、Hを0.3にします。

    カメラ切り替えスクリプト

    通常のカメラとキャラクター視点のカメラを切り替えるスクリプトを作成します。

    ヒエラルキー上で右クリック→Create Emptyを選択し名前をManagementとします。

    ManagementにChangeCameraという新しいスクリプトを作成し取り付けます。

    publicなフィールドでメインカメラとキャラクター視点のカメラを選択出来るようにしておきます。

    Changeメソッドでは受け取った引数によってメインカメラとキャラクター視点カメラのオン・オフをしています。

    フリーフォール機能の確認

    これで全ての解説は終わったと思います。

    抜けがあるかもしれませんが・・・・。

    ちなみにFreeFallCharaのインスペクタの設定は

    FreeFallCharaスクリプトのインスペクタの設定

    ↑のようになりました。

    最初にすでに動画で紹介しているのでまた機能の確認するのも意味はないんですが再度確認してみましょう・・・(^_^;)

    MyCamera、FreeFallButton、InfoUIは最初は見えない状態にする為、インスペクタで名前の横のチェックを外しておきます。

    最初に紹介した動画との違いを出す為に、もっと高い位置まで昇って落ちるような設定にして確認してみましょう。

    最初に紹介した動画では

    ArrivalPointYは100
    UpSpeedを5
    DownSpeedを3
    WaitCountを5

    としていました。

    今回は

    ArrivalPointYを1000
    UpSpeedを100
    DownSpeedを1
    WaitCountを3

    にします。

    また、TheSkyCameraとFixedPointCameraを無効化して、景色をもっと楽しめるようにします。

    ↑のようになりました。

    あんまり臨場感がありませんね・・・・・(^_^;)

    周りの景色がもっと広くて素晴らしければ良かったんですが・・・・。

    VR(バーチャルリアリティ)に対応すると楽しそうな気もしますが、持っていないので対応も出来ないし確認も出来ません・・・・(T_T)/~~~

    ちなみにUnityの実行がカクカクの場合はマッチターゲットがうまく働かず空中椅子をしたり本来の位置とは違うところに座ってしまいます。

    直せないのでこのままで・・・・(._.)

    いやぁ・・・この記事作成するの大変すぎですよ・・・・(ーー;)

    もう長い記事は書きたくない・・・・(;一_一)

    スポンサーリンク

    記事をシェアして頂ける方はこちら

    フォローして頂くとやる気が出ます