今回は移動キーを押した時にユニティちゃんが床の上を移動するところまでを作成したいと思います。
ユニティちゃんの当たり判定と移動機能はCharacterControllerコンポーネントの機能を使い、移動キーを押した時の移動やアニメーションの切り替えはスクリプトを使って行い、
アニメーションの状態や遷移条件等はAnimator Controllerを使って行います。
前回はプロジェクトの作成とユニティちゃんモデルパッケージのインポート、警告とエラーの修正を行いました。
ユニティちゃんのRPGを作ってみようの他の記事は
から見ることが出来ます。
保存先の作成
最初にゲームのスクリプト等を保存するフォルダを作成します。
Assetsエリア内で右クリックからCreate→Folderを選択し名前をRPGとします。
これから作成していくゲームのスクリプト等はRPGフォルダ内に作成します。
新しいシーンの作成
シーンを作成します。
シーンはゲームの一つの場面で、例えばタイトルのシーン、ワールドマップのシーン、村の中のシーン、戦闘のシーン等に分けます。
RPGフォルダ内で右クリックからCreate→Folderを選択し名前をScenesとします。
Scenes内で右クリックし、Create→Sceneを選択し、名前をVillageとします。
Villageシーンが出来たらダブルクリックしてVillageシーンを表示します。
簡易的な地面を作成
ユニティちゃんを移動させるにはまず移動する地面がないと駄目なので地面を作成しておきます。
ヒエラルキー上で右クリックから3D Object→Planeを選択し、名前をSampleGroundとします。
SampleGroundのインスペクタのTransformでPositionとRotationのXYZ全てを0にし、ScaleのXYZを全て10にします。
これで簡易的な地面が出来上がりました。
ユニティちゃんプレハブの配置
ユニティちゃんの髪や顔のアニメーション設定がされているユニティちゃんのプレハブをシーン上に配置します。
Assets/UnityChan/Prefabs/unitychan_dynamicをヒエラルキー上にドラッグ&ドロップします。
unitychan_dynamicを選択した状態でF2キーを押して名前をUnityChanに変更します。
名前は好きに変更してもいいですし、変更しなくてもかまいません。
UnityChanのインスペクタのTransformでPosition、RotationのXZを全て0にし、RotationのYを180にします。
PositionとRotationを0にしたのは単にわかりやすい位置と角度にする為です。
カメラの位置と角度を変更する
ユニティちゃんの位置と角度を変えたことでGameビューでユニティちゃんが写らなくなってしまったかもしれません。
そこでカメラの位置と角度を変更し正面からユニティちゃんが写るようにします。
ヒエラルキー上のMain Cameraを選択しインスペクタのTransformの位置をXを0、Yを1、Zを-5とし、RotationのXYZ全てを0とします。
この変更を行うとGameビューでは
上のようにユニティちゃんが正面から表示されるようになりました。
AnimatorControllerの作成
次にアニメーションの状態と遷移を管理するAnimator Controllerを作成します。
アニメーターコントローラーについては
も参照してください。
RPGフォルダ内で右クリックからCreate→Folderを選択し、名前をAnimatorsとします。
Animatorsフォルダ内で右クリックからCreate→Animator Controllerを選択し、名前をUnityChanとします。
Animatorウインドウが開いていない場合は今作成したUnityChanという名前のAnimator Controllerをダブルクリックします。
Animatorウインドウを開いた状態でAnimator ControllerのUnityChanを選択します。
アニメーションの遷移条件に使うアニメーションパラメータを作成します。
Animatorウインドウの左上のParametersを押した後、+を押してFloatを選び名前をSpeedとします。
Animatorウインドウ内で右クリックからCreate State→Emptyを選択し、インスペクタで名前をIdleとします。
同じようにMoveForwardを作成します。
Idleを選択した状態で右クリックからMake Transitionを選択しMoveForward状態を押します。
同じようにMoveForwardからIdleへの遷移を作成します。
Idle状態を選択しインスペクタのMotionにWAIT00のアニメーションクリップを設定します。
Blend Treeの作成
歩き状態と走る状態はアニメーションパラメータのSpeedの値によって変更します。
なので歩き状態と走る状態を別々に作って作成するよりもBlend Treeを利用するとSpeedの値によってモーションを変化させることが出来るので便利です。
MoveForward状態を選択し、右クリックからCreate new BlendTree in Stateを選択し、その後MoveForward状態をダブルクリックします。
Blend Treeを選択した状態で右クリックし、Add Motionを選択します。
その後もう一度同じ事をしてモーションを二つにします。
Blend Treeを選択してインスペクタのモーションを設定します。
MotionにWalk00_FとRun00_Fを設定し、Automate Thresholdのチェックを外し、Walk00_FのThresholdは0.1、Run00_FのThresholdは0.5にします。
これでアニメーションパラメータのSpeedの値が0.1の辺りはWalk00_Fのアニメーションで0.1から0.5まではWalk00_FとRun00_Fのブレンドのアニメーション、0.5以降はRun00_Fのアニメーションとなります。
これでブレンドツリーが出来ましたので、Base Layerを押して戻ります。
Idle→MoveForwardの遷移を選択しインスペクタのHas Exit Timeのチェックを外しSpeedがGreaterで0.1の時にMoveForwardへ遷移するようにします。
同じようにMoveForward→Idleの遷移を選択し、インスペクタのHas Exit Timeのチェックを外しSpeedがLessで0.1の時にIdleへ遷移するようにします。
またSettingsのInterrupt SourceにNext Stateを設定します。
Interrupt SourceにNext Stateを設定するとMoveForward→Idleへの遷移途中にIdle→MoveForwardの遷移条件が成立した時に割り込みが発生し、直ぐに遷移します。
ここら辺は
を参照してみてください。
顔用のレイヤーを作成
次にAnimatorウインドウの左上のLayersを押し+を押し、名前をFace Layerとします。
Face Layerは顔のみのアニメーションを適用するレイヤーにします。
Weightを1にします。
Face Layerの右の歯車を押し、Maskにface only maskを設定します。
face only maskアバターマスクは顔だけアニメーションを適用する為に設定しています。
face only maskはユニティちゃんパッケージに既にあるのでそれを設定するだけです。
face Layerには顔用のアニメーション状態を作成しておき、スクリプトから顔のアニメーションを変化させることが出来ますが、現時点では何も設定しません。
これでユニティちゃんのアニメーターコントローラーが出来たので、ヒエラルキー上のUnityChanゲームオブジェクトを選択し、インスペクタのAnimatorにUnityChanアニメーターコントローラーをドラッグ&ドロップします。
またAnimatorのApply Root Motionのチェックを外し、アニメーションの変化でキャラクターが移動しないようにします。
CharacterControllerの取り付け
次にUnityChanゲームオブジェクトを選択した状態でインスペクタのAdd ComponentからPhysics→CharacterControllerを選択し取り付けます。
CharacterControllerは衝突をするコライダと移動機能を持っています。
CharacterControllerの設定を変更しユニティちゃんの衝突範囲を変更します。
CenterのYを0.8、Radiusを0.3、Heightを1.4とします。
シーンビューでユニティちゃんの回りに緑色のコライダの範囲が表示されました。
このコライダが他のゲームオブジェクトとの衝突判定に使われます。
これでコライダと移動機能の取り付けが完了しました。
キャラクター操作スクリプトの作成
AnimatorControllerの作成と取り付け、CharacterControllerの取り付けが終わったので、後はスクリプトからCharacterControllerの移動機能を使って移動させ、アニメーターコントローラーのアニメーションパラメータのSpeedの値を操作してアニメーションの遷移をさせるだけです。
RPGフォルダ内で右クリックからCreate→Folderを選択し名前をScriptsとします。
Scripts内で右クリックからCreate→C# Scriptを選択し、名前をUnityChanScriptとします。
UnityChanScriptをヒエラルキー上のUnityChanゲームオブジェクトにドラッグ&ドロップし取り付けます。
Assets/RPG/Scriptsフォルダ内のUnityChanScriptファイルをダブルクリックしvisual studioでスクリプトを開きます。
以下のスクリプトをUnityChanScript内に記述します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | using System.Collections; using System.Collections.Generic; using UnityEngine; public class UnityChanScript : MonoBehaviour { private CharacterController characterController; private Animator animator; // キャラクターの速度 private Vector3 velocity; // キャラクターの歩くスピード [SerializeField] private float walkSpeed = 2f; // キャラクターの走るスピード [SerializeField] private float runSpeed = 4f; // Start is called before the first frame update void Start() { characterController = GetComponent<CharacterController>(); animator = GetComponent<Animator>(); } // Update is called once per frame void Update() { if(characterController.isGrounded) { velocity = Vector3.zero; var input = new Vector3(Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical")); if(input.magnitude > 0.1f) { transform.LookAt(transform.position + input.normalized); animator.SetFloat("Speed", input.magnitude); if (input.magnitude > 0.5f) { velocity += transform.forward * runSpeed; } else { velocity += transform.forward * walkSpeed; } } else { animator.SetFloat("Speed", 0f); } } velocity.y += Physics.gravity.y * Time.deltaTime; characterController.Move(velocity * Time.deltaTime); } } |
CharacterControllerとAnimatorを入れておくcharacterControllerとanimatorフィールド、キャラクターの速度を入れておくVector3型のvelocity、歩くスピードを入れるwalkSpeedと走るスピードを入れるrunSpeedを宣言します。
walkSpeedとrunSpeedには[SerializeField]アトリビュートを取り付けインスペクタで値を設定出来るようにします。
Startメソッドはゲームオブジェクトが最初に登場した時に1回だけ呼ばれるのでここでCharacterControllerとAnimatorコンポーネントをGetComponentを使って取得しておきます。
Updateメソッドは1秒間に何十回も呼ばれるメソッドでパソコンの処理能力に応じて呼ばれる回数が異なります。
characterController.IsGroundedでキャラクターが接地しているかどうかがわかるので接地していた時は速度であるvelocityにVector3.zeroを入れて速度を0にしています。
Input.GetAxis(“Horizontal”)で横軸の入力、Input.GetAxis(“Vertical”)で縦軸の入力が得られるので、その値をinputに代入しています。
input.magnitudeで入力(ベクトル)の長さが得られるので0.1より大きい時に入力がされていると判断することにします。
transform.LookAtは引数で指定したベクトルの方向を向かせるメソッドでtransform.positionでキャラクターの位置を得て、それにinput.normalizedで入力の単位ベクトル(長さが1のベクトルで方向を得る)を足すことで現在の位置に入力した方向を足して、その方向を向かせるようにします。
そのあとanimator.SetFloat(“Speed”, input.magnitude)でアニメーションパラメータのSpeedの値にinput.magnitudeの値を渡します。
input.magnitudeは入力の方向の長さが入っているので、例えば何も移動キーを押していなければ0、完全に右方向キーを押していれば1の値、ちょっとだけ右方向を押していれば0.1等の値、上と右のキーを同時に押していれば1以上の値が入ってきます。
input.magnitudeが0.1以下の時はanimator.SetFloat(“Speed”, 0f)でアニメーションパラメータのSpeedを0にしてIdle状態へと遷移するようにします。
キャラクターには重力を働かせたいのでvelocity(速度)のY方向にPhysics.gravity.y(UnityメニューのEdit→Project Settings→Physicsで設定されている値)でY軸方向に重力値を足しています。
デフォルトでは-9.81が設定されていてそれにTime.deltaTimeを掛ける事で重力加速度を計算しています。
ここら辺は
を参照してください。
その後characterControllerのMoveメソッドの引数に速度を渡してキャラクターを移動させています。
ユニティちゃんを動かしてみる
AnimatorControllerの作成と設定、CharacterControllerの取り付け、キャラクターの操作スクリプトの作成と取り付けが終わったのでユニティちゃんを移動させてみます。
その前にUnityChanゲームオブジェクトを選択し、Unpack Prefab Completelyを選択します。
UnityChanはunitychan_dynamicプレハブから作成したインスタンスで元のプレハブとリンクされています。
なのでUnityChanに施した変更をプレハブに反映することもプレハブの設定に戻すことも出来てしまいます。
Unpack Prefab Completelyを選択する事で元のプレハブとのリンクを切り離すことが出来ます。
UnityChanゲームオブジェクトを選択し、インスペクタでIdle Changerコンポーネントの右側の歯車からRemoveを選択し削除します。
同じようにIK Ctrl Right Handコンポーネントも削除します。
次にRandomWindスクリプトとFaceUpdateスクリプトのOnGUIメソッドをコメントにします。
1 2 3 4 5 6 7 | //void OnGUI () //{ // Rect rect1 = new Rect (10, Screen.height - 40, 400, 30); // isWindActive = GUI.Toggle (rect1, isWindActive, "Random Wind"); //} |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | //void OnGUI() { // GUILayout.Box("Face Update", GUILayout.Width(170), GUILayout.Height(25 * (animations.Length + 2))); // Rect screenRect = new Rect(10, 25, 150, 25 * (animations.Length + 1)); // GUILayout.BeginArea(screenRect); // foreach (var animation in animations) { // if (GUILayout.RepeatButton(animation.name)) { // anim.CrossFade(animation.name, 0); // } // } // isKeepFace = GUILayout.Toggle(isKeepFace, " Keep Face"); // GUILayout.EndArea(); //} |
RandomWindスクリプトはユニティちゃんの髪を揺らすスクリプトで、FaceUpdateは顔のアニメーションを変化させるスクリプトで両方とも使用しますが、OnGUIメソッドがあるとボタンが表示されそれで簡易的に切り替えることが出来てしまうのでそれらをコメントにしました。
これで設定が完了したのでUnityの実行ボタンを押して確認してみます。
ユニティちゃんを動かすと
上のようになりました。
キーボードの矢印キーの移動だとinput.magnitudeは直ぐに1になってしまう為に歩きのモーションがほとんど確認出来ません。
なので途中でPS3コントローラーをパソコンに繋いでアナログスティックの入力を微妙に変化させて歩きのモーションを確認しました。
PS3コントローラー等でキャラクターを操作する機能は後の記事で作成します。
終わりに
今回は移動キーを押したらユニティちゃんが移動するという基本的なところを作成しました。
元々のユニティちゃんプレハブに顔のアニメーション変化スクリプトや髪の毛を揺らしたりするスクリプトはそのまま使う為に残してあります。
ただアニメーターコントローラーは自分で作成した方がわかりやすいかなと思ってそうしています。
この作品はユニティちゃんライセンス条項の元に提供されています