UnityUnityメモ

Unityでジャンプ距離を計算して表示!初心者向けキャラクターコントローラー&Raycast入門

Unity

1. はじめに

Unityでキャラクターがジャンプした距離を計算し、それを表示してみたいと思ったことはありませんか?本記事では、Unity初心者の方でも簡単に実装できる方法を解説します。使用する主な機能は、「キャラクターコントローラー」と「Raycast」です。

「キャラクターコントローラー」は、キャラクターの動きを簡単に制御できるコンポーネントで、特にプレイヤーキャラクターの移動やジャンプを実現するのに便利です。一方、「Raycast」は、仮想的な「光線」を使ってオブジェクトとの接触や位置関係を判定する強力なツールです。今回は、この2つを組み合わせてジャンプ距離を計算する仕組みを作ります。

この記事では、Unityのプロジェクトをセットアップするところから、実際にスクリプトを作成して動作確認を行うところまで、ステップバイステップで解説します。Unityの基本操作を学びながら、ジャンプ距離を計算する方法を楽しくマスターしましょう!

Unityを触ったことがないという方はコチラの記事から見てみてください!



2. Unityプロジェクトのセットアップ

このセクションでは、Unityプロジェクトで必要なオブジェクトを配置し、「キャラクターコントローラー」を設定する手順を解説します。初心者でも簡単にできるように、具体的な手順をステップ形式で説明します!


1. ヒエラルキーにオブジェクトを配置する

まずは、プレイヤーや地面になるオブジェクトをUnityのシーンに配置しましょう。

  1. キューブを配置する
    1. ヒエラルキー(Hierarchy)ウィンドウを右クリックします。
    2. メニューから「3D Object」→「Cube」を選択します。
    3. シーンビューにキューブが表示されます。これがプレイヤーキャラクターになります。
    4. インスペクター(Inspector)ウィンドウでキューブの名前を「Player」に変更しておくとわかりやすいです。
  2. 地面(Plane)を配置する
    1. 再びヒエラルキーを右クリックします。
    2. メニューから「3D Object」→「Plane」を選択します。
    3. シーンビューにPlaneが表示されます。これがプレイヤーが移動する地面になります。
  3. オブジェクトの位置を調整する
    • 「Player」キューブを選択した状態で、インスペクターのTransform欄を確認します。
    • PositionのYを「1」に設定して、地面の上に浮かせておきます。
    • Planeはそのままで大丈夫です。

2. キャラクターコントローラーを追加する

次に、キューブに「キャラクターコントローラー」をアタッチして、キャラクターの動きを制御できるようにします。

  1. Playerキューブを選択する
    • ヒエラルキーで「Player」と名前を変更したキューブを選択します。
  2. インスペクターでコンポーネントを追加する
    1. インスペクターウィンドウで「Add Component」ボタンをクリックします。
    2. 検索バーに「Character Controller」と入力します。
    3. 検索結果に表示される「Character Controller」を選択して追加します。
  3. キャラクターコントローラーの設定を確認する
    • キャラクターコントローラーを追加すると、インスペクターに新しい設定項目が表示されます。
    • デフォルト設定のままで問題ありませんが、必要に応じて調整できます。

これで、Unityのシーンにオブジェクトを配置し、キャラクターコントローラーを設定する準備が整いました!次は、プレイヤーキャラクターがジャンプした距離を計算するスクリプトを作成していきましょう。



3. スクリプトの作成

ここでは、キャラクターがジャンプした距離を計算し、表示するスクリプトを作成します。このスクリプトは「JumpDistance」という名前で保存し、キューブにアタッチします。それでは手順を見ていきましょう!


スクリプトの作成手順

  1. スクリプトの新規作成
    • プロジェクトウィンドウを右クリックします。
    • メニューから「Create」→「C# Script」を選択します。
    • スクリプトの名前を「JumpDistance」に変更します。
  2. スクリプトをオブジェクトにアタッチ
    • 作成した「JumpDistance」スクリプトを、ヒエラルキーにあるキューブにドラッグ&ドロップします。
    • インスペクターを確認し、キューブにスクリプトがアタッチされていることを確認します。
  3. スクリプトを編集
    • スクリプトをダブルクリックして開きます。
    • 以下のコードをコピーして、スクリプトに貼り付けます。

スクリプトコード

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class JumpDistance : MonoBehaviour
{
    private float rayDistance; // Raycastの距離
    private float speed = 6.0f; // キャラクターの移動速度
    private float jumpSpeed = 8.0f; // ジャンプ時の速度
    private float gravity = 20.0f; // 重力
    private Vector3 moveDirection = Vector3.zero; // キャラクターの移動方向
    private CharacterController controller; // CharacterControllerの参照
    private float startPos; // ジャンプ開始位置
    private float groundPos; // 着地位置
    private float jumpDistance; // ジャンプ距離

    void Start()
    {
        controller = GetComponent<CharacterController>(); // CharacterControllerを取得
        rayDistance = 1.0f; // Raycastの距離を設定
    }

    void Update()
    {
        // Raycastによる接地判定
        Vector3 rayPosition = transform.position + new Vector3(0.0f, 0.0f, 0.0f);
        Ray ray = new Ray(rayPosition, Vector3.down);
        bool isFloor = Physics.Raycast(ray, rayDistance);

        Debug.DrawRay(rayPosition, Vector3.down * rayDistance, Color.red);

        if (controller.isGrounded)
        {
            // 移動方向を計算
            moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0.0f, Input.GetAxis("Vertical"));
            moveDirection = transform.TransformDirection(moveDirection) * speed;

            // ジャンプ処理
            if (Input.GetButtonDown("Jump"))
            {
                moveDirection.y = jumpSpeed;
            }
        }

        // 重力を適用
        moveDirection.y -= gravity * Time.deltaTime;
        controller.Move(moveDirection * Time.deltaTime);

        // ジャンプ距離の計算
        if (isFloor)
        {
            startPos = transform.position.x; // 地面にいる場合、開始位置を記録
        }
        else
        {
            groundPos = transform.position.x; // 空中にいる場合、現在位置を記録
            jumpDistance = groundPos - startPos; // 距離を計算
            Debug.Log("Jump Distance: " + jumpDistance); // デバッグログで表示
        }
    }
}

コードのポイント解説

  • Raycastを使用した接地判定
    • Rayを下方向に飛ばし、キャラクターが地面に接しているかを確認します。
    • 接地時と空中時で処理を分けて、ジャンプの開始位置と終了位置を記録します。
  • ジャンプの処理
    • Input.GetButtonDown("Jump")でジャンプボタンが押されたことを検知し、jumpSpeedを適用します。
  • 距離計算
    • 空中にいる間にジャンプ距離を計算し、Debug.Logでコンソールに出力します。

これでスクリプトの作成は完了です!次のステップでは、このスクリプトを使った動作確認とデバッグについて説明します。



4. 動作確認とデバッグ

ここでは、作成したスクリプトが正しく動作しているか確認し、必要に応じてデバッグを行う方法を解説します。


ゲームビューでの確認手順

  1. シーンを保存する
    まず、現在のシーンを保存しましょう。メニューバーから「File」→「Save As」を選び、適当な名前を付けて保存します。
  2. プレイモードを開始する
    Unityエディターの上部にある「▶」(再生ボタン)をクリックしてプレイモードを開始します。
  3. ジャンプ動作をテストする
    キーボードのスペースキーを押して、キューブをジャンプさせます。以下の点を確認してください:
    • キューブが正しくジャンプするか。
    • ジャンプ中に距離が正しく計算され、コンソールに表示されているか。
    : ジャンプ中にコンソールに次のような出力が表示されます。コードをコピーする2.5
  4. 停止する
    テストが終わったら「■」(停止ボタン)をクリックしてプレイモードを終了します。

Debug.Logを使ったデバッグ方法

もしスクリプトが期待通りに動作しない場合、次のようにデバッグを行いましょう。

  1. Consoleウィンドウを確認する
    Unityエディター下部にある「Console」タブを開き、スクリプトが出力するメッセージを確認します。
    • 「ジャンプ距離」が出力されない場合、以下のステップを試してください。
  2. コードの見直し
    スクリプト内のRaycast部分やジャンプ距離の計算ロジックを再確認します。特に以下のポイントに注意してください:
    • Raycastの距離(rayDistance)が適切に設定されているか。
    • キャラクターコントローラーがシーン内のキューブに正しくアタッチされているか。
  3. Debug.Logを追加する
    問題の箇所を特定するため、Debug.Logを活用します。例えば、Raycastの接地判定が正しく動作しているか確認するには、以下のようにコードを追加します:
    if (isFloor) { Debug.Log("地面に接地しています"); } else { Debug.Log("空中にいます"); }
  4. 解決例
    • Raycastが地面を検知しない場合:
      • 原因: 地面(Plane)のLayerが正しく設定されていない。
      • 対処法: PlaneオブジェクトのLayerを「Default」に設定し、スクリプトでPhysics.RaycastがこのLayerを認識できるようにします。
  5. リアルタイムでの確認
    プレイモード中に値をリアルタイムで確認するため、Unityの「インスペクター」ウィンドウを使うことも便利です。ジャンプ開始地点や現在位置をスクリプト内で公開して、リアルタイムに値を確認しましょう:
    public float startPos; public float groundPos;
    これにより、Unityエディターで「Start Pos」や「Ground Pos」がインスペクターに表示され、値を視覚的に確認できます。

デバッグが終わったら、シーンやスクリプトを再度保存しておきましょう。これで、ジャンプ距離を計算する仕組みが完成です!

次に進む準備が整いましたね。お疲れさまでした! 😊



よくある質問(FAQ)

Q
Raycastが正しく動作しないのですが、どうすればいいですか?
A

Raycastが正しく動作しない場合、以下の点を確認してください:

  • オブジェクトにColliderが付いているか:RaycastはColliderが付いているオブジェクトに当たります。Planeやその他の地形オブジェクトにColliderが付いていることを確認してください。
  • Raycastの距離(rayDistance)が適切か:距離が短すぎると地面に届かないことがあります。必要に応じて距離を調整してください。
  • デバッグ用Rayの描画Debug.DrawRayでRayの進行方向を可視化し、正しい方向に飛んでいるか確認してください。
Q
ジャンプ距離が常にゼロになってしまいます。原因は何でしょうか?
A

ジャンプ距離がゼロになる場合、以下の原因が考えられます:

  • ジャンプ開始位置(startPos)が正しく記録されていない:地面にいる状態でRaycastが正常に動作しているかを確認してください。地面判定のロジックを見直すと良いでしょう。
  • 地面に着地する前に計算されている:空中にいる間のgroundPosが適切に記録されているかをデバッグして確認してください。
Q
キャラクターがジャンプしません。どうしたらいいですか?
A

キャラクターがジャンプしない場合は以下を確認してください:

  • ジャンプボタンの設定:Input Managerで「Jump」に設定されているキーが正しいか確認してください(デフォルトではスペースキー)。
  • ジャンプ速度(jumpSpeed)が十分大きいか:ジャンプ速度が小さい場合、ジャンプが目に見えないことがあります。jumpSpeedの値を増やしてみてください。
  • 重力(gravity)の影響:重力が強すぎるとジャンプの高さが抑えられます。適切なバランスで調整してください。

おすすめのアセット

「Jump Jump Jump – Complete Game Template」は、簡単にモバイルやPC向けのカジュアルゲームを作成できるテンプレートです。このアセットは、プレイヤーがキャラクターをジャンプさせて障害物を避けながら進むシンプルなゲームを提供し、完成されたテンプレートとしてすぐにリリース可能な状態になっています。