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"に設定します。
スクリプトの変更
スクリプトファイルを編集します。下記のコードに変更します。
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ボタンをクリックしてプロジェクトを開始します。
キャラクターは前後にしか動きませんが、カーソルの[↑]キーを押すと歩くモーションで前進します。[↓]キーを押すと、歩くアニメーションのまま後ろに移動します。
方向転換を実装する
先のコードで歩くモーションでの移動ができるようになりましたが、前後のみの移動です。方向転換ができるようにコードを修正します。
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.AddRelativeForce(0, 0, z * force);
}
if (Input.GetKey("right")) {
transform.Rotate(0, 10, 0);
}
else if (Input.GetKey("left")) {
transform.Rotate(0, -10, 0);
}
}
}
解説
キャラクターの移動に関しては先のコードと同様のロジックです。
キャラクターに対して力をかける処理は、AddForceではなくAddRelativeForceを利用することで、キャラクターのローカル座標軸で力を与える方向を設定できます。下記のコードによりキャラクターが向いている方向に力をかけることができます。
if (rbody.velocity.magnitude < 2.0f) {
rbody.AddRelativeForce(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.AddRelativeForce(0, 0, z * force);
}
transform.Rotate(0, 10* x, 0);
}
}
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用