RidgeBodyが適用されたオブジェクトを移動させる - RidgeBody を利用したキャラクター移動 - Unity

RidgeBodyが適用されたオブジェクトを移動させるコードを紹介します。

概要

こちらの記事ではTerrainオブジェクトの地形にキャラクターを配置しました。ここからキャラクターを移動させたいですが、単純にxやyの座標値を増減しただけでは地面にキャラクターがめり込む動作になってしまい、起伏のある地形の上を移動できません。地形の起伏に合わせて地面との接触判定をしつつキャラクターを移動させる方法を紹介します。

事前準備

地形の作成とキャラクターの配置

Terrainオブジェクトを利用して地形を作成しキャラクターを配置します。手順はこちらの記事を参照してください。

手順

スクリプトの作成

移動のロジックを記述するスクリプトを作成します。[Assets]のウィンドウの作成ボタンをクリックします。下図のポップアップメニューが表示されます。メニューの[C# スクリプト]をクリックします。


[Assets]ウィンドウにC#のスクリプトファイルが追加されます。ファイル名を "UnityChanMove"とします。


作成したC#スクリプトをダブルクリックして開きます。Visual Studioが起動しますので、下記のコードを記述します。
UnityChanMove.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UnityChanMove : MonoBehaviour
{
  private Rigidbody rbody;

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

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

    float x = Input.GetAxis("Horizontal");
    float z = Input.GetAxis("Vertical");
    rbody.AddForce(x * force, 0, z * force);
  }
}

解説

下記のコードで方向キーやジョイスティックからの入力を受け取ります。キーボードの場合は上下のカーソルキーが"Vertical"の値に、左右のカーソルキーの値が"Horizontal"になります。
  float x = Input.GetAxis("Horizontal");
  float z = Input.GetAxis("Vertical");

キャラクターに力を加えます。上下方向はZ軸に力を加えます。左右方向はX軸に力を加えます。大きな数値で力を加えないとオブジェクトは移動しないため、キー入力の値を500倍した値を力の値としています。
  rbody.AddForce(x * force, 0, z * force);

スクリプトの割り当て

作成したスクリプトをキャラクターに割り当てます。シーンウィンドウで移動させたいキャラクター(ユニティちゃん)をクリックして選択します。右側の[インスペクター]ウィンドウの下部の[コンポーネントを追加]ボタンをクリックします。


検索ボックスを使うか、メニューの[スクリプト]カテゴリを選択して作成した、"UnityChanMove"スクリプトを選択します。


スクリプトがオブジェクトに割り当てられます。[インスペクター]ウィンドウに"Unity Chan Move (Script)"の項目が追加されます。

動作確認

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


カーソルの[↑]キーを押します。なんとユニティちゃんが前のめりに倒れてしまいました。


[↓]キーを押すと、倒れたまま引きずられるように移動します。


左右のカーソルキーを押すと、蹴り飛ばされたようにゴロゴロ転がりながら移動していきます。


回転の抑制

先ほどの転がってしまう動作を防ぐため、回転を抑制する処理を有効にします。シーンウィンドウでキャラクターを選択します。


右側の[インスペクター]ウィンドウの[リジッドボディ]のセクションの [Constraints] を開きます。下図の画面が表示されます。[回線を固定]のチェックボックスがありますので、[X][Y][Z]3つのチェックボックスにチェックを付けます。

動作確認

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


カーソルキーを入力します。今度は回転せずに、直立したまま滑るように前後に移動します。


速度の抑制

先の実行結果で、期待した動作になりましたが、キーを押している間は力がかかり続けているため、かなりの加速になります。ちょっとキーを押しただけでキャラクターがすっ飛んでいくような動作になります。一定の速度に達したらキャラクターに力を与えない動作にすることで、最高速度を制限します。
UnityChanMove のスクリプトを下記に変更します。

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

public class UnityChanMove : MonoBehaviour
{
  private Rigidbody rbody;

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

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

    float x = Input.GetAxis("Horizontal");
    float z = Input.GetAxis("Vertical");

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

解説

AddForceメソッドで力をかける前に、velocity.magnitude の値を確認し、速度が1以下の場合のみに力をかけるようにします。これにより、キャラクタの最高速度が1になります。
  if (rbody.velocity.magnitude < 1.0f) {
    rbody.AddForce(x * force, 0, z * force);
  }

動作確認

Playボタンをクリックしてプロジェクトを実行します。キーを入力して動作を確認します。一定速度で移動できるようになったことが確認できるはずです。

次の処理

キャラクター(ユニティちゃん)が移動できるようになりましたが、まだモーションがついていません。移動時に歩くモーションを設定します。 こちらの記事を参照してください。

補足:方向キーを入力したときのGetAxisの値

方向キーを入力したときのGetAxisの値は以下になります。キーボードでは半押しはありませんが、GetAxisの値は0,1ではなく、キー押下後に徐々に値が1になる動作になります。
-0.050301
-0.0993996
-0.1493184
-0.1988013
-0.2484993
-0.2993214
-0.3478998
-0.3982887
-0.4493409
-0.4972932
-0.548313
-0.5963994
-0.6473027
-0.6957986
-0.7463042
-0.7973315
-0.8453201
-0.8946017
-0.9443249
-0.9939995
-1
-1
-1
-1
-1
(中略)
-1
-1
-1
-1
-1
-1
-0.9500893
-0.9006046
-0.8509015
-0.8000794
-0.7490797
-0.7018027
-0.6500881
-0.6021004
-0.5511025
-0.5030032
-0.4520884
-0.4036042
-0.353089
-0.3042052
-0.2540776
-0.2048045
-0.1551023
-0.1054025
-0.05570146
-0.006002858
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
掲載日: 2018-12-24
iPentec all rights reserverd.