RidgeBodyが適用されたオブジェクトをモーションを付けて移動させる - Unity

RidgeBodyが適用されたオブジェクトをモーションを付けて移動させるコードを紹介します。

概要

こちらの記事ではRidgeBodyが適用されたオブジェクトを移動させる手順を紹介しました。この記事ではさらにモーションを付けてキャラクターを移動させるコードを紹介します。

事前準備

地形とキャラクターの配置をします。詳細はこちらの記事を参照してください。

アニメーションモーションの設定

モーションの設定

モーションの設定はこちらの記事で紹介している手順とほぼ同様です。

シーンウィンドウでキャラクターをクリックして選択します。[インスペクター]ウィンドウの[アニメーター]セクションの"Controller"にコントローラーが設定されていることを確認します。今回はキャラクターにユニティちゃんを利用しており、"SD_unitychan_motion_Generic"を指定しています。


[Assets]ウィンドウでキャラクターに設定されているコントローラーをダブルクリックして編集画面を表示します。


[アニメーター]ウィンドウ内の[パラメーター]タブをクリックします。下図の画面が表示されますタブウィンドウの右上の[+]ボタンをクリックします。下図のポップアップメニューが表示されます。メニューの[Bool]の項目をクリックしてBool型のパラメーターを追加します。


パラメーターが追加されました。パラメーター名を "IsWalk" とします。


アニメーターウィンドウの右側の[Standing(loop)]と[Walking(loog)]を結ぶ下向きの矢印をクリックして選択します。右側の[Conditions]エリアのパラメーターを "IsWalk"に変更し値を"true"に設定します。


同様に、アニメーターウィンドウの右側の[Standing(loop)]と[Walking(loog)]を結ぶ上向きの矢印をクリックして選択します。右側の[Conditions]エリアのパラメーターを "IsWalk"に変更し値を"false"に設定します。

スクリプトの変更

スクリプトファイルを編集します。下記のコードに変更します。

UnityChanMove.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UnityChanMove : MonoBehaviour
{
  private Rigidbody rbody;
  private Animator animator;
  private enum UnityChanState { STAND, WALK };
  private UnityChanState state;

  // Start is called before the first frame update
  void Start()
  {
    rbody = GetComponent<Rigidbody>();
    animator = GetComponent<Animator>();
  }

  // Update is called once per frame
  void Update()
  {
    float force = 500.0f;

    float z = Input.GetAxis("Vertical");
    System.Diagnostics.Debug.WriteLine(z);

    if (rbody.velocity.magnitude > 0f) {
      if (state == UnityChanState.STAND) {
        state = UnityChanState.WALK;
        animator.SetBool("IsWalk", true);
      }
    }
    else {
      if (state == UnityChanState.WALK) {
        state = UnityChanState.STAND;
        animator.SetBool("IsWalk", false);
      }
    }

    if (rbody.velocity.magnitude < 1.0f) {
      rbody.AddForce(0, 0, z * force);
    }
  }
}

解説

基本的な動作はこちらの記事と同様です。移動によりキャラクターの速度がある場合には、stateの値をWALKに変更し、IsWalkパラメーターをtrueに設定し歩くモーションに移行します。速度が0になりキャラクターが止まったことが検出された場合は、stateの値をWALKからSTANDに変更し、IsWalkパラメータをfalseに設定し、立ちアニメーションに戻します。

表示結果

Playボタンをクリックしてプロジェクトを開始します。


キャラクターは前後にしか動きませんが、カーソルの[↑]キーを押すと歩くモーションで前進します。[↓]キーを押すと、歩くアニメーションのまま後ろに移動します。


方向転換を実装する

先のコードで歩くモーションでの移動ができるようになりましたが、前後のみの移動です。方向転換ができるようにコードを修正します。


UnityChanMove.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UnityChanMove : MonoBehaviour
{
  private Rigidbody rbody;
  private Animator animator;
  private enum UnityChanState { STAND, WALK };
  private UnityChanState state;

  private Vector3 position;


  // Start is called before the first frame update
  void Start()
  {
    rbody = GetComponent<Rigidbody>();
    animator = GetComponent<Animator>();
  }

  // Update is called once per frame
  void Update()
  {
    float force = 500.0f;

    float x = Input.GetAxis("Horizontal");
    float z = Input.GetAxis("Vertical");
    System.Diagnostics.Debug.WriteLine(z);

    if (rbody.velocity.magnitude > 0f) {
      if (state == UnityChanState.STAND) {
        state = UnityChanState.WALK;
        animator.SetBool("IsWalk", true);
      }
    }
    else {
      if (state == UnityChanState.WALK) {
        state = UnityChanState.STAND;
        animator.SetBool("IsWalk", false);
      }
    }

    if (rbody.velocity.magnitude < 2.0f) {
      rbody.AddRelativeFor​​ce(0, 0, z * force);
    }
   
    if (Input.GetKey("right")) {
      transform.Rotate(0, 10, 0);
    }
    else if (Input.GetKey("left")) {
      transform.Rotate(0, -10, 0);
    }
  }
}

解説

キャラクターの移動に関しては先のコードと同様のロジックです。
キャラクターに対して力をかける処理は、AddForceではなくAddRelativeFor​​ceを利用することで、キャラクターのローカル座標軸で力を与える方向を設定できます。下記のコードによりキャラクターが向いている方向に力をかけることができます。
  if (rbody.velocity.magnitude < 2.0f) {
    rbody.AddRelativeFor​​ce(0, 0, z * force);
  }

左右のカーソルキーを押された場合はキャラクターを回転させます。このコードですとキーボードのみの操作しか対応できないため、Input.GetAxis("Horizontal")を利用するコードへの見直しが後々必要そうです。
  if (Input.GetKey("right")) {
    transform.Rotate(0, 10, 0);
  }
  else if (Input.GetKey("left")) {
    transform.Rotate(0, -10, 0);
  }

表示結果

Playボタンをクリックしてプロジェクトを実行します。下図の画面が表示されます。


カーソルの[↑]キーを押すと、キャラクターが向いている方向に前進します。


左右キーでキャラクターの向きを変更できます。変更後[↑]キーを押すことでキャラクターが向いている方向に移動できます。

キャラクターの回転もGetAxisの入力値を利用する修正

キャラクターの回転もGetAxisの入力値を利用するよう下記のコードに修正します。動作はほぼ変わりませんが、ゲームパッドでの操作もできるようになります。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UnityChanMove : MonoBehaviour
{
  private Rigidbody rbody;
  private Animator animator;
  private enum UnityChanState { STAND, WALK };
  private UnityChanState state;

  private Vector3 position;


  // Start is called before the first frame update
  void Start()
  {
    rbody = GetComponent<Rigidbody>();
    animator = GetComponent<Animator>();
  }

  // Update is called once per frame
  void Update()
  {
    float force = 500.0f;

    float x = Input.GetAxis("Horizontal");
    float z = Input.GetAxis("Vertical");
    System.Diagnostics.Debug.WriteLine(z);

    if (rbody.velocity.magnitude > 0f) {
      if (state == UnityChanState.STAND) {
        state = UnityChanState.WALK;
        animator.SetBool("IsWalk", true);
      }
    }
    else {
      if (state == UnityChanState.WALK) {
        state = UnityChanState.STAND;
        animator.SetBool("IsWalk", false);
      }
    }

    if (rbody.velocity.magnitude < 2.0f) {
      rbody.AddRelativeFor​​ce(0, 0, z * force);
    }

    transform.Rotate(0, 10* x, 0);
  }
}
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
掲載日: 2018-12-25
iPentec all rights reserverd.