UnityUnityメモ

Unityでオブジェクトが一定距離離れたら動く仕組みを簡単に実装する方法

Unity

1. はじめに

こんにちは!今日はUnityを使って「距離を測定して動作を実行する仕組み」を作る方法を解説します。
このチュートリアルでは、3Dオブジェクトを使い、**Cube(プレイヤー)Sphere(ターゲット)**から一定の距離離れたときにSphereが落下するシンプルな動きを作ります。

Unity初心者の方でも安心してください!ステップごとに詳しく説明するので、基本からしっかり学べますよ。今回の内容をマスターすれば、ゲーム開発で距離に基づいたさまざまな仕組みを応用できるようになります。

「ちょっと難しそう」と思うかもしれませんが、大丈夫!一緒にやっていきましょう。それでは、始めていきます!

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



2. 準備

まずは今回の仕組みを作るために必要な準備をしていきましょう。ここでは、Unityで新しいプロジェクトを作成し、必要なオブジェクトを配置します。


プロジェクトの作成

  1. Unity Hubを開く
    Unity Hubで「新しいプロジェクト」をクリックします。
  2. テンプレートの選択
    「3D Core」を選びます。
  3. プロジェクト名の設定
    プロジェクト名を「DistanceAction」として保存場所を指定し、「作成」をクリックします。

3Dオブジェクトの配置

次に、距離を測定する対象となるCube(プレイヤー)、Sphere(ターゲット)、Plane(地面)を作成します。

  1. Cubeを作成
    1. Hierarchyウィンドウで右クリック。
    2. 「3D Object」→「Cube」を選択します。
    3. 名前を「Player」に変更します。
  2. Sphereを作成
    1. Hierarchyウィンドウで右クリック。
    2. 「3D Object」→「Sphere」を選択します。
    3. 名前を「Target」に変更します。
  3. Planeを作成
    1. Hierarchyウィンドウで右クリック。
    2. 「3D Object」→「Plane」を選択します。
    3. 名前はそのままでOKです。

オブジェクトの配置を調整

各オブジェクトを見やすい位置に配置します。

  • Player(Cube)
    • Transform → Position: (0, 0.5, 0)
  • Target(Sphere)
    • Transform → Position: (3, 1, 0)
    • Rigidbodyコンポーネントをアタッチ(落下を有効にするため)。
      • Inspectorウィンドウで「Add Component」→「Rigidbody」を追加
      • Rigidbodyの「Use Gravity」をオフに設定。
  • Plane(地面)
    • Transform → Position: (0, 0, 0)

オブジェクトが見やすい設定に変更(任意)

見やすくするために、オブジェクトに簡単な色を設定しておきます。

  1. Materialを作成
    1. Projectウィンドウで右クリック → 「Create」→「Material」を選択。
    2. 名前を「PlayerMaterial」「TargetMaterial」「GroundMaterial」に変更。
  2. 色の設定
    • PlayerMaterial → 色を青に設定。
    • TargetMaterial → 色を赤に設定。
    • GroundMaterial → 色を緑に設定。
  3. ドラッグ&ドロップで適用 各オブジェクトに作成したMaterialをドラッグ&ドロップします。

これで準備完了です!次は、オブジェクトに動きを加えるスクリプトを作成していきましょう。



3. スクリプトの作成

ここからは、Unityで必要なスクリプトを作成していきます。Cube(プレイヤー)の移動、Sphere(ターゲット)の落下、そしてオブジェクト間の距離を測定するスクリプトを順番に作っていきましょう!


1. Cube(プレイヤー)を動かすスクリプト

まずは、Cubeをプレイヤーとして移動できるようにするスクリプトを作成します。

  1. スクリプトを作成
    • Projectウィンドウで右クリック → 「Create」→「C# Script」を選択。
    • スクリプト名を「PlayerMove」にします。
  2. コードを記述 以下のコードを記述してください:

コード全体の説明

このスクリプトは、プレイヤーのオブジェクトを左右(横方向)や前後(縦方向)に移動させるためのものです。プレイヤーは、キーボードの矢印キーや「WASD」キーを使って移動させることができます。

各部分の説明

  1. using文
    • これらは、Unityで必要なライブラリをインポートしています。特にUnityEngineが重要で、ゲームオブジェクトやコンポーネントの操作に必要です。
  2. クラス定義
    • PlayerMoveという名前のクラスを定義しています。このクラスは、MonoBehaviourを継承しています。これにより、このクラスはUnityのコンポーネントとして使うことができます。
  3. Updateメソッド
    • Updateメソッドは、毎フレーム(画面が更新されるたび)呼び出される特別なメソッドです。ここでプレイヤーの移動を処理します。
  4. プレイヤーの移動処理
    • Input.GetAxis("Horizontal"):キーボードの左右キー(または「A」と「D」キー)で得られる入力値を取得します。左に押すと負の値、右に押すと正の値が返ります。
    • Input.GetAxis("Vertical"):キーボードの上下キー(または「W」と「S」キー)で得られる入力値を取得します。下に押すと負の値、上に押すと正の値が返ります。
    • Time.deltaTime:前のフレームからの経過時間を取得します。これを使うことで、移動速度がフレームレートに依存せず一定になります。
    • 3.0f:これは移動速度の係数です。値を変えるとプレイヤーの移動速度が変わります。
    • transform.position:プレイヤーの現在の位置を取得します。
    • new Vector3(...):新しい位置を計算します。横方向の移動(dx)と縦方向の移動(dz)を現在の位置に加えます。高さは0.5に固定しています。

全体の動き

  1. プレイヤーがキーボードの矢印キーや「WASD」キーを押すと、Input.GetAxisでその入力値を取得します。
  2. 入力値に移動速度と経過時間を掛け合わせて、フレームレートに依存しない移動量(dx, dz)を計算します。
  3. 現在のプレイヤーの位置に移動量を加えて、新しい位置を設定します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMove : MonoBehaviour
{
    void Update()
    {
        // キーボード入力で移動
        float dx = Input.GetAxis("Horizontal") * Time.deltaTime * 3.0f;
        float dz = Input.GetAxis("Vertical") * Time.deltaTime * 3.0f;

        // 新しい位置を計算
        transform.position = new Vector3(
            transform.position.x + dx, 0.5f, transform.position.z + dz
        );
    }
}
  • スクリプトをCubeにアタッチ
    • 「PlayerMove」スクリプトをHierarchyウィンドウの**Player(Cube)**にドラッグ&ドロップしてアタッチします。

2. Sphere(ターゲット)を落下させるスクリプト

次に、Sphereが一定条件で落下するスクリプトを作成します。

  1. スクリプトを作成
    • 同じ手順でスクリプトを作成し、名前を「SphereMove」にします。
  2. コードを記述 以下のコードを記述してください:

各部分の説明

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
    • これらは、スクリプトで使う機能やクラスを読み込むためのものです。特に、UnityEngineはUnityの基本的な機能を使うために必要です。
  4. public class SphereMove : MonoBehaviour
    • ここでは新しいクラス(SphereMove)を定義しています。このクラスはMonoBehaviourを継承しています。MonoBehaviourはUnityの基本的なクラスで、これを継承することで、Unityのゲームオブジェクトにアタッチできるスクリプトを作成できます。
  5. public void SphereGravity()
    • これはSphereGravityという名前のメソッド(関数)を定義しています。このメソッドはpublicなので、他のスクリプトからも呼び出すことができます。voidは、このメソッドが何も値を返さないことを意味します。
  6. GetComponent<Rigidbody>().useGravity = true;
    • この行は、スクリプトがアタッチされているオブジェクトにRigidbodyというコンポーネントがあることを前提に、そのRigidbodyuseGravityプロパティをtrueに設定します。つまり、このオブジェクトが重力の影響を受けるようにします。

全体の動き

  1. このスクリプトを球体(Sphere)オブジェクトにアタッチします。
  2. SphereGravityメソッドを呼び出すと、その球体のRigidbodyコンポーネントのuseGravitytrueになり、球体が重力の影響を受けるようになります。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SphereMove : MonoBehaviour
{
    public void SphereGravity()
    {
        // Rigidbodyの重力を有効化
        GetComponent<Rigidbody>().useGravity = true;
    }
}
  • スクリプトをSphereにアタッチ
    • 「SphereMove」スクリプトをHierarchyウィンドウの**Target(Sphere)**にドラッグ&ドロップしてアタッチします。

3. 距離を測定して動作を実行するスクリプト

最後に、CubeとSphereの距離を測定し、一定の距離を超えたらSphereを落下させるスクリプトを作成します。

  1. スクリプトを作成
    • 新しいスクリプトを作成し、名前を「ObjectDistance」にします。
  2. コードを記述 以下のコードを記述してください:

コード全体の説明

このスクリプトは、objAobjBという2つのオブジェクトの距離を計算し、その距離が8.0より大きいときに、objBにアタッチされているSphereMoveというスクリプトのSphereGravityという関数を呼び出します。

各部分の説明

  1. 宣言部分
    ここでは、objAobjBという2つのゲームオブジェクトを宣言しています。これらのオブジェクトはUnityのエディターから設定します。
  2. Update関数
    • Update関数は、毎フレーム呼び出される関数です。この中でオブジェクトの距離をチェックします。
    • Vector3 cube = objA.transform.position; は、objAの位置を取得してcubeという変数に保存します。
    • Vector3 sphere = objB.transform.position; は、objBの位置を取得してsphereという変数に保存します。
    • float dis = Vector3.Distance(cube,sphere); は、cubesphereの位置から距離を計算してdisという変数に保存します。
    • if(dis > 8.0f){...} では、距離が8.0より大きい場合に、objBにアタッチされているSphereMoveスクリプトのSphereGravity関数を呼び出します。

全体の動き

距離が8.0より大きいとき、objBSphereMoveスクリプト内のSphereGravity関数を実行します。れにより、例えば、objBが一定の範囲外に出た場合に特定の動作を開始させることができます。

毎フレーム、objAobjBの位置を取得します。

その2つの位置から距離を計算します。

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

public class ObjectDistance : MonoBehaviour
{
    public GameObject objA; // Cube
    public GameObject objB; // Sphere

    void Update()
    {
        // オブジェクト間の距離を計算
        Vector3 cube = objA.transform.position;
        Vector3 sphere = objB.transform.position;
        float distance = Vector3.Distance(cube, sphere);

        // 距離が8.0fを超えたらSphereを落下
        if (distance > 8.0f)
        {
            objB.GetComponent<SphereMove>().SphereGravity();
        }
    }
}
  1. スクリプトを空のオブジェクトにアタッチ
    • Hierarchyウィンドウで右クリック → 「Create Empty」を選択して空のオブジェクトを作成。
    • 名前を「DistanceController」に変更。
    • 「ObjectDistance」スクリプトをこのオブジェクトにドラッグ&ドロップしてアタッチ。
  2. オブジェクトを設定
    • DistanceControllerのInspectorで、objAPlayer(Cube)objBに**Target(Sphere)**を設定します。

これでスクリプトの作成は完了です!次は、実行して動作を確認してみましょう。



4. 実行と確認

ここでは、Unityで作成した仕組みを実際に動かして確認する手順を説明します。すべての設定が正しく行われていれば、**Cube(プレイヤー)Sphere(ターゲット)**から一定距離離れたときにSphereが落下します。


1. Unityエディタで再確認

実行前に以下をもう一度確認しましょう:

  • Player(Cube)
    • 「PlayerMove」スクリプトがアタッチされている。
  • Target(Sphere)
    • Rigidbodyがアタッチされ、「Use Gravity」がオフになっている。
    • 「SphereMove」スクリプトがアタッチされている。
  • DistanceController
    • ObjectDistanceスクリプトのobjAPlayerが、objBTargetが設定されている。

2. 実行

  1. Unityエディタの上部にある**「Play」ボタン**をクリック。
  2. ゲームが実行されます。

3. 動作を確認

  • Cubeの操作
    • キーボードの矢印キーまたはWASDキーで**Cube(Player)**を動かします。
  • 距離による動作確認
    • CubeをSphereから少しずつ遠ざけ、距離が8.0fを超えたら、Sphereが重力で落下することを確認します。

4. 正常に動作しない場合

以下を確認してトラブルシューティングを行ってください。

Q1: Sphereが落下しない
  • Rigidbodyの「Use Gravity」がスクリプトで有効化されているか。
  • DistanceControllerのobjBに正しいオブジェクト(Sphere)が設定されているか。
Q2: Cubeが動かない
  • 「PlayerMove」スクリプトがPlayerに正しくアタッチされているか。
  • CubeのTransform→PositionのY座標が固定(例: 0.5)されているか。
Q3: 距離が変化しない
  • 「ObjectDistance」スクリプトのdis > 8.0fの値が意図した距離になっているか。
  • CubeやSphereの位置が重なっている場合は初期配置を見直してください。

5. 実行成功の確認

成功すると以下の動作が確認できます:

  • Cubeを動かしてSphereから8.0f以上離れると、Sphereが重力で落下します。
  • 落下後はSphereが地面(Plane)に衝突して静止します。

これで、Unityを使った「オブジェクト同士が一定距離離れたときに動作を実行する仕組み」の実装と確認は完了です!



よくある質問

Q
Sphereが落下しません。
A

Rigidbodyが正しくアタッチされているか確認してください。

Q
距離の値を変えたい場合は?
A

ObjectDistanceスクリプト内のif(dis > 8.0f)の数値を変更してください。

Q
Cubeの動きが遅い/速いです。
A

PlayerMoveスクリプトのTime.deltaTime * 3.0fの部分を調整してください。

おすすめのアセット

「Platformer Project」は、Unityで簡単に2Dプラットフォーマーゲームを作成できるテンプレートです。このアセットは、初心者から経験豊富な開発者まで幅広く利用でき、スムーズなゲーム開発をサポートします。

特徴として、キャラクターの移動、ジャンプ、敵との戦闘など、基本的な動作がすでに組み込まれているため、すぐにゲームの制作に取り掛かれます。また、使いやすいインターフェースと豊富なドキュメントが揃っているので、設定やカスタマイズも簡単です。