UnityUnityメモ

Unity初心者向け!衝突でスクリプトを停止する簡単なテクニック

Unity

はじめに

こんにちは!今回は Unityでオブジェクトが衝突したときに特定のスクリプトを停止する方法 を紹介します。例えば、プレイヤーが動いている障害物にぶつかった際に、その障害物の動きをピタッと止める、そんなシンプルだけど実用的なテクニックを実現します。


今回は具体例として、以下のシチュエーションを再現します。

  • 障害物(Sphere)が常に動き続けている
  • プレイヤー(Cube)がCapsuleに触れると、障害物(Sphere)が動きを止める

Unity初心者でも安心して取り組めるよう、手順をひとつひとつ丁寧に解説します。サンプルコードも用意しているので、ぜひ一緒に試してみてくださいね!それでは早速始めましょう!

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



必要な準備

Unityでオブジェクトが衝突した際にスクリプトを非アクティブにする仕組みを作るには、まず基本的なオブジェクトの配置や設定を行う必要があります。以下の手順に従って準備を進めていきましょう!


1. Unityプロジェクトを作成する

  1. Unity Hubを開きます。
  2. 新しいプロジェクトを作成し、テンプレートとして「3D」を選択します。
  3. プロジェクト名を「CollisionScriptTutorial」としておきましょう(任意で変更可能です)。

2. 使用するオブジェクトを配置する

今回使用するオブジェクトは以下の3つです:

  • Sphere(動く障害物)
  • Cube(プレイヤー)
  • Capsule(トリガーとなるポイント)

以下の手順でこれらのオブジェクトをヒエラルキーウィンドウに配置します。

  1. ヒエラルキーウィンドウを右クリックします。
  2. **「3D Object」→「Sphere」**を選択します。
    • これでシーン内にSphereが追加されます。
  3. 同様に、「3D Object」→「Cube」、**「3D Object」→「Capsule」**を選択して、それぞれ追加します。

これでシーンに3つのオブジェクトが配置されました。


3. オブジェクトの初期配置を調整する

各オブジェクトが適切に動作するように、位置を設定します。

  • Sphere
    インスペクターウィンドウでPositionを以下に設定します。
    • X: 0, Y: 0.5, Z: -3
  • Cube
    インスペクターウィンドウでPositionを以下に設定します。
    • X: 0, Y: 0.5, Z: 0
  • Capsule
    インスペクターウィンドウでPositionを以下に設定します。
    • X: 0, Y: 0.5, Z: 3



3. オブジェクトの設定

Unityで「Sphere」「Cube」「Capsule」の3つのオブジェクトを正しく設定することで、衝突判定とスクリプトの制御がスムーズに行えるようになります。このセクションでは、それぞれのオブジェクトに必要な設定を詳しく解説します。


1. Rigidbodyを追加する(SphereとCube)

「Sphere」と「Cube」に物理挙動を追加するために、Rigidbodyコンポーネントを設定します。

  1. SphereにRigidbodyを追加
    • ヒエラルキー(Hierarchy)ウィンドウで「Sphere」を選択します。
    • インスペクター(Inspector)ウィンドウの下部にある「Add Component」ボタンをクリックします。
    • 検索バーに「Rigidbody」と入力し、表示されたRigidbodyを選択します。
    • 追加後、「Use Gravity」のチェックを外します(オブジェクトが重力で落下しないようにするため)。
  2. CubeにRigidbodyを追加
    • ヒエラルキーウィンドウで「Cube」を選択します。
    • インスペクターウィンドウで「Add Component」をクリック。
    • 「Rigidbody」を検索して選択します。
    • こちらも「Use Gravity」のチェックを外します。

2. CapsuleのColliderをTriggerに設定

「Capsule」のColliderに触れることでイベントを発生させるため、「Is Trigger」を有効にします。

  1. CapsuleのColliderを設定
    • ヒエラルキーウィンドウで「Capsule」を選択します。
    • インスペクターウィンドウの「Capsule Collider」コンポーネントを確認します。
    • 「Is Trigger」のチェックボックスをオンにします。

設定の確認

最後に、それぞれのオブジェクトが正しく設定されているかを確認しましょう。

  • 「Sphere」と「Cube」にはRigidbodyが追加され、「Use Gravity」がオフになっていますか?
  • 「Capsule」のColliderに**「Is Trigger」がオン**になっていますか?

これらの設定が完了したら、次のステップに進みましょう!オブジェクトが適切に機能するための重要な準備が整いました。



4. スクリプトの作成と設定

ここでは、Cube(プレイヤーオブジェクト)とSphere(障害物オブジェクト)に必要なスクリプトを作成し、設定していきます。それぞれのスクリプトの役割とコードについて詳しく解説します。


1. CubeMoveスクリプトを作成

まずは、プレイヤーオブジェクトであるCubeの動きを制御するスクリプトを作成します。このスクリプトでは、Cubeが矢印キーで動き、Capsuleに衝突したときにSphereのスクリプトを停止します。

  1. スクリプトを作成する プロジェクトウィンドウで右クリックして、
    **「Create」→「C# Script」**を選択します。スクリプト名を「CubeMove」に変更します。
  2. スクリプトを編集する 「CubeMove」スクリプトをダブルクリックして開き、以下のコードを入力します。
using UnityEngine;

public class CubeMove : MonoBehaviour
{
    [SerializeField] GameObject sphere; // Sphereオブジェクトの参照
    private float speed = 3.0f;         // Cubeの移動速度

    void Start()
    {
        // Sphereオブジェクトをシーン内から検索して取得
        sphere = GameObject.Find("Sphere");
    }

    void Update()
    {
        // 矢印キーでCubeを移動
        float moveX = Input.GetAxis("Horizontal") * Time.deltaTime * speed;
        float moveZ = Input.GetAxis("Vertical") * Time.deltaTime * speed;
        transform.position = new Vector3(
            transform.position.x + moveX, 
            0, 
            transform.position.z + moveZ
        );
    }

    void OnTriggerEnter(Collider other)
    {
        // Capsuleに衝突したとき、Sphereのスクリプトを無効化
        if (other.gameObject.name == "Capsule")
        {
            sphere.GetComponent<SphereMove>().enabled = false;
        }
    }
}
  1. コードのポイント
    • GameObject.Find("Sphere") で、シーン内にあるSphereオブジェクトを取得します。
    • OnTriggerEnter メソッドで、CubeがCapsuleに触れた際にSphereMoveスクリプトを無効化します。

コード全体の説明

このスクリプトは、キューブを矢印キーで動かし、カプセルに触れたときにスフィアの動きを止めるというものです。

各部分の説明

  1. using UnityEngine;
    • Unityの機能を使うための宣言です。
  2. public class CubeMove : MonoBehaviour
    • CubeMoveという名前のクラスを定義しています。このクラスは、UnityのMonoBehaviourという基本クラスを継承しています。
  3. [SerializeField] GameObject sphere;
    • sphereというゲームオブジェクトを定義しています。[SerializeField]は、Unityエディタ上でこの変数を設定できるようにするためのものです。
  4. private float speed = 3.0f;
    • キューブの移動速度を設定しています。この場合、速度は3.0fです。
  5. void Start()
    • ゲームが始まったときに一度だけ呼ばれる関数です。ここでは、シーン内にある「Sphere」という名前のオブジェクトを探してsphereに代入しています。
  6. void Update()
    • 毎フレーム呼ばれる関数です。ここでキューブの移動を処理しています。
      • float moveX = Input.GetAxis(“Horizontal”) * Time.deltaTime * speed;
        • 水平方向の入力を取得し、時間経過と速度を掛け合わせて移動量を計算しています。
      • float moveZ = Input.GetAxis(“Vertical”) * Time.deltaTime * speed;
        • 垂直方向の入力を取得し、時間経過と速度を掛け合わせて移動量を計算しています。
      • transform.position = new Vector3(transform.position.x + moveX, 0, transform.position.z + moveZ);
        • 計算した移動量を使って、キューブの位置を更新しています。
  7. void OnTriggerEnter(Collider other)
    • 他のオブジェクトと衝突したときに呼ばれる関数です。
      • if (other.gameObject.name == “Capsule”)
        • 衝突したオブジェクトの名前が「Capsule」だった場合
        • sphere.GetComponent<SphereMove>().enabled = false;
          • sphereオブジェクトにアタッチされているSphereMoveスクリプトを無効化しています。

全体の動き

  1. ゲームがスタートすると、シーン内の「Sphere」を探します。
  2. 毎フレーム、矢印キーの入力に応じてキューブの位置を更新します。
  3. キューブがカプセルに触れると、スフィアの動きを止めます。

2. SphereMoveスクリプトを作成

次に、障害物であるSphereの動きを制御するスクリプトを作成します。このスクリプトでは、Sphereが一定時間動いた後に方向を反転します。

  1. スクリプトを作成する 再びプロジェクトウィンドウで右クリックし、
    **「Create」→「C# Script」**を選択して、「SphereMove」と名前を付けます。
  2. スクリプトを編集する 「SphereMove」スクリプトをダブルクリックして開き、以下のコードを入力します。
using UnityEngine;

public class SphereMove : MonoBehaviour
{
    private int counter = 0;          // カウント変数
    private float move = 5.0f;        // Sphereの移動速度

    void Update()
    {
        // 前方向に移動
        transform.Translate(new Vector3(0, 0, move * Time.deltaTime));
        counter++;

        // 一定カウントに達したら方向を反転
        if (counter == 100)
        {
            counter = 0;
            transform.Rotate(new Vector3(0, 180, 0));
        }
    }
}
  1. コードのポイント
    • Translate メソッドでSphereを前方に移動させます。
    • counter が100に達すると、Rotate メソッドで180度回転して進行方向を反転します。

コード全体の説明

このスクリプトは、スフィア(球体オブジェクト)を前後に動かし、100フレームごとに180度回転させます。

各部分の説明

  1. using System.Collections; using System.Collections.Generic; using UnityEngine;
    • 必要なライブラリをインポートしています。System.CollectionsSystem.Collections.Genericはコレクション(リストや配列など)を使うためのものです。UnityEngineはUnityの基本的な機能を使うためのものです。
  2. public class SphereMove : MonoBehaviour
    • SphereMoveという名前のクラスを定義しています。このクラスは、UnityのMonoBehaviourクラスを継承しています。
  3. private int counter = 0;
    • counterという名前の整数型変数を定義しています。これは、スフィアが移動するフレーム数を数えるためのカウンターです。
  4. private float move = 5.0f;
    • moveという名前の浮動小数点型変数を定義しています。これは、スフィアの移動速度です。この場合、速度は5.0fです。
  5. void Update()
    • 毎フレーム呼ばれる関数です。ここでスフィアの移動と回転を処理しています。
      • transform.Translate(new Vector3(0, 0, move * Time.deltaTime));
        • スフィアを前方向に移動させます。move * Time.deltaTimeを使って、フレームレートに依存しない移動を実現しています。
      • counter++;
        • カウンターを1増やします。
      • if (counter == 100)
        • カウンターが100に達したとき
        • counter = 0;
          • カウンターをリセットします。
        • transform.Rotate(new Vector3(0, 180, 0));
          • スフィアをY軸を中心に180度回転させます。これでスフィアの進行方向が反転します。

全体の動き

  1. 毎フレーム、スフィアは前方向に移動します。
  2. 100フレームごとにカウンターがリセットされ、スフィアは180度回転して進行方向を反転させます。

これで、Cubeの移動とCapsuleへの衝突によるSphereの動作停止が実現します。



5. スクリプトのアタッチ

ここでは、作成したスクリプトを対応するオブジェクトにアタッチする方法を解説します。スクリプトを正しくアタッチすることで、各オブジェクトが期待通りに動作するようになります。


1. CubeMoveスクリプトをCubeにアタッチする

  1. プロジェクトウィンドウを開き、先ほど作成したCubeMoveスクリプトを見つけます。
  2. このスクリプトをヒエラルキーウィンドウ内のCubeオブジェクトにドラッグ&ドロップします。
  3. 正しくアタッチされると、Cubeオブジェクトを選択したときにインスペクターウィンドウCubeMoveスクリプトが表示されます。

2. SphereMoveスクリプトをSphereにアタッチする

  1. 同様に、プロジェクトウィンドウSphereMoveスクリプトを探します。
  2. このスクリプトをヒエラルキーウィンドウSphereオブジェクトにドラッグ&ドロップします。
  3. アタッチされたスクリプトは、Sphereオブジェクトのインスペクターウィンドウで確認できます。

3. 必要に応じた設定の確認

  • CubeMoveスクリプト内のSphere設定
    • CubeMoveスクリプトには、Sphereオブジェクトを参照するコードがあります。これを正しく機能させるため、Sphereの名前が**”Sphere”**であることを確認してください。
    • 名前が異なる場合は、ヒエラルキーウィンドウでSphereオブジェクトを選択し、名前を変更してください。

注意点

  • スクリプトが正しくアタッチされていないと、エラーが発生したり、動作しない場合があります。
  • インスペクターでスクリプトが表示されない場合は、ヒエラルキーのオブジェクト名やスクリプト名にスペルミスがないか確認してください。

これでスクリプトのアタッチは完了です!次は、プレイモードで実際に動作を確認してみましょう。衝突時にスクリプトが停止するかどうかをチェックしてください。


この手順ならUnity初心者でも簡単にスクリプトをアタッチできます!不明点があれば、Unityのドキュメントやコミュニティも参考にしてくださいね。



6. 動作確認

ここまでで、すべての設定とスクリプトの作成が完了しました。それでは、実際に動作確認を行い、設定が正しく機能しているか確認してみましょう。

プレイモードに切り替える

  1. Unityのエディタ上部にある「再生ボタン」をクリックしてプレイモードに切り替えます。
  2. シーン内のオブジェクトが動作を開始します。

Cubeを操作する

  1. キーボードの矢印キーまたは W, A, S, D キーを使って、Cubeを移動させます。
  2. Cubeを操作して、Capsuleに近づけます。

衝突時の挙動を確認する

  1. CubeがCapsuleに触れると、Sphere(障害物)が停止することを確認してください。
    • Sphereが停止するのは、「SphereMove」スクリプトが無効化されているためです。
  2. Sphereが動かなくなったら、衝突判定が正しく機能していることがわかります。

注意点とトラブルシューティング

もし期待通りに動作しない場合は、以下を確認してください:

  • Capsule Colliderの「Is Trigger」にチェックが入っているか
    • これが有効でないと、トリガーイベントが発生しません。
  • CubeMoveスクリプトがCubeに正しくアタッチされているか
    • 「Inspector」ウィンドウで確認してください。
  • SphereMoveスクリプトがSphereにアタッチされているか
    • 同様に確認し、Sphereが「Sphere」という名前になっていることも確認しましょう。

実際のゲームでの応用

この動作確認ができたら、さらに発展させてみましょう:

  • 障害物を複数設置して、それぞれ異なる挙動をさせる。
  • Cubeが別のオブジェクトと衝突した際に、別のイベントを発生させる。

これで 動作確認は完了です!正しく機能した場合は、おめでとうございます!次はさらに高度な機能を追加して、より面白いゲームを作ってみましょう。



よくある質問

Q
「Sphereが止まらないのはなぜ?」
A

SphereがCapsuleに触れても動きが止まらない場合、以下を確認してください:

  1. CapsuleのCollider設定
    • Capsuleの「Is Trigger」がオンになっているか確認してください。
    • オフになっていると、OnTriggerEnterメソッドが呼び出されません。
  2. CubeMoveスクリプトの設定
    • CubeMoveスクリプトがCubeに正しくアタッチされているか確認してください。
    • スクリプト内で sphere = GameObject.Find("Sphere"); が正しくSphereを参照しているかチェックしてください。
  3. SphereMoveスクリプトのアタッチ
    • SphereMoveスクリプトがSphereにアタッチされていることを確認してください。
    • また、SphereMoveスクリプトの「enabled」が正しく制御されているかインスペクターで確認しましょう。
Q
「スクリプトを別のオブジェクトに適用する方法は?」
A

現在のCubeMoveスクリプトでは、「Sphere」という名前のオブジェクトを検索しています。他のオブジェクトを制御したい場合、以下を変更してください:

  • GameObject.Findの引数を変更する
    例えば、GameObject.Find("Obstacle"); に変更すれば、”Obstacle” という名前のオブジェクトを制御対象にできます。
  • インスペクターで設定可能にする
    スクリプト内の sphere フィールドを公開し、インスペクターから制御したいオブジェクトをドラッグ&ドロップで指定できます。
    [SerializeField] GameObject sphere; // インスペクターで設定可能

おすすめのアセット

この「Bubble Shooter Game Toolkit」は、誰でも簡単に人気のバブルシューターゲームを作れるツールキットです。カラフルなバブルを使ったゲームの基本的な仕組みがすべて含まれており、初心者でも直感的に操作できます。