第8回では、前回Playerへ追加した人型モデルに待機と歩行のアニメーションを付けます。WASDの入力から作った移動量をAnimatorへ送り、止まっているときはIdle、移動中はWalkへ切り替えます。
PlayerMoveからMoveSpeedを更新し、WASDでPlayerが動くと人型モデルも歩く状態にします。途中で表示されたコンパイルエラーも、Consoleを使って直します。
Animator Controllerを複製しよう
Supercyan Character Pack Free Sample/AnimatorControllersにあるFreeAnimationsを複製し、PlayerAnimationsという名前にします。アセット付属の設定を直接変更せず、プレイヤー専用のControllerとして使うためです。
Ctrl + Dで行えます。右側が作成したPlayerAnimationsです。HierarchyでFreeSample_male_1を選び、AnimatorコンポーネントのControllerへPlayerAnimationsを設定します。Apply Root Motionはオフのままにします。
今回の移動はPlayerMoveとCharacter Controllerが担当します。アニメーション側の移動まで反映すると、位置が二重に動くことがあるためです。
Animatorの中身を確認しよう
PlayerAnimationsをダブルクリックしてAnimatorウィンドウを開きます。ControllerにはMovement、Jump、Midair、LandのStateが用意されています。
MoveSpeedと、TriggerやBoolのパラメーターがあります。今回使うのはMoveSpeedとGroundedです。MoveSpeedへ移動量を送り、Groundedをtrueにして地上のMovementを使います。
PlayerMoveからAnimatorを使えるようにしよう
PlayerMove.csの変数を宣言している場所へ、次の1行を追加します。
public Animator animator;
publicにすると、PlayerのInspectorへAnimator欄が表示されます。移動量をAnimatorへ送ろう
moveを作り、長さを1以下にそろえた直後へAnimatorの処理を追加します。完成したPlayerMove.csは次のとおりです。
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerMove : MonoBehaviour
{
public float moveSpeed = 4f;
public Animator animator;
CharacterController controller;
Transform cameraTransform;
void Start()
{
controller = GetComponent<CharacterController>();
cameraTransform = Camera.main.transform;
}
void Update()
{
if (Keyboard.current == null)
{
return;
}
float horizontal = 0f;
float vertical = 0f;
if (Keyboard.current.aKey.isPressed)
{
horizontal -= 1f;
}
if (Keyboard.current.dKey.isPressed)
{
horizontal += 1f;
}
if (Keyboard.current.sKey.isPressed)
{
vertical -= 1f;
}
if (Keyboard.current.wKey.isPressed)
{
vertical += 1f;
}
Vector3 forward = cameraTransform.forward;
Vector3 right = cameraTransform.right;
forward.y = 0f;
right.y = 0f;
forward.Normalize();
right.Normalize();
Vector3 move =
forward * vertical + right * horizontal;
move = Vector3.ClampMagnitude(move, 1f);
if (animator != null)
{
animator.SetFloat(
"MoveSpeed",
move.magnitude,
0.1f,
Time.deltaTime);
animator.SetBool("Grounded", true);
}
controller.Move(
move * moveSpeed * Time.deltaTime);
}
}
move.magnitude移動方向Vector3の長さです。停止中は0、移動中は最大1になります。SetFloatAnimatorのFloatパラメーターへ数字を送ります。0.1f値をなめらかに変える時間です。IdleとWalkが急に切り替わるのを抑えます。コンパイルエラーをConsoleで直そう
作業中に「Please fix compile errors before creating new state machine behaviours」と表示されました。これはAnimatorの問題ではなく、C#スクリプトにコンパイルエラーが残っているという案内です。
CS0841: Cannot use local variable 'move' before it is declaredと表示されています。原因は、Vector3 moveを作る前にmoveを使用していたことでした。コードは上から順番に実行されるため、必ず次の順に並べます。
Vector3 move =
forward * vertical + right * horizontal;
move = Vector3.ClampMagnitude(move, 1f);
// この後でmoveをAnimatorと移動処理に使う
重複していたcontroller.Moveも1つに整理し、保存してUnityへ戻るとエラーが消えました。
モデルのAnimatorを登録しよう
HierarchyでPlayerを選び、Player MoveコンポーネントのAnimator欄へ、子オブジェクトFreeSample_male_1をドラッグします。
FreeSample_male_1 (Animator)と表示されれば設定完了です。Player
├─ PlayerMove
│ └─ Animator欄 → FreeSample_male_1のAnimator
│
└─ FreeSample_male_1
└─ Animator
└─ Controller → PlayerAnimations
再生して歩行を確認しよう
Playを押し、GameビューをクリックしてWASDを操作します。キーを離すとIdleになり、WASDを押すとWalkへ切り替われば成功です。
- 停止中はIdleになる。
- WASDを押している間はWalkになる。
- Playerの移動速度が以前と変わっていない。
- Consoleに赤いエラーがない。
進む方向へキャラクターを向けよう
次回はModelRootを作り、モデルに必要なY回転-90を保ったまま、WASDで進む方向へ体を向けます。

コメント