UnityUnityメモ

Unityで触れたオブジェクトを配列に格納!Cubeを使った簡単なスクリプト

Unity

1. はじめに

Unityでゲームを作るとき、オブジェクト同士がぶつかったり、プレイヤーが何かを収集したりする場面はよくありますよね。そのような機能を実現するには、「触れたオブジェクトを記録する」という仕組みがとても役立ちます。本記事では、Cubeを使って他のオブジェクト(SphereやCylinderなど)にぶつかったときに、それらを配列に格納する方法を解説します。


この記事では、初心者でも簡単に実践できるように、Unityの基本的な操作からスクリプトの記述までをステップバイステップで説明します。最終的には、以下のような動作を実現します:

  • プレイヤーがCubeを操作して動かす。
  • Cubeがオブジェクトに触れると、そのオブジェクトが配列に保存される。
  • 保存されたオブジェクトが非表示になる。

これを学ぶことで、収集アイテムや衝突イベントの管理といったゲームの基礎的な機能を作るスキルを身に付けることができます。ぜひ一緒に楽しく挑戦してみましょう!

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




2. プロジェクトの準備

この記事では、Cubeを操作し、特定のオブジェクトに触れた際にその情報を配列に格納するシステムを作成します。まずはプロジェクトの準備から始めましょう!


1. 必要なオブジェクトの作成

  1. Cubeの作成
    • ヒエラルキーウィンドウで右クリックし、3D Object > Cubeを選択します。
    • Cubeが作成されるので、名前を「PlayerCube」に変更してわかりやすくしておきましょう。
  2. CubeにRigidbodyを追加
    • インスペクターウィンドウで、Add Componentボタンをクリックします。
    • 「Rigidbody」と入力し、コンポーネントを追加します。
    • Use Gravityのチェックを外し、重力の影響を受けないように設定します。
  3. Cubeの色を変更
    • プロジェクトウィンドウで右クリックし、Create > Materialを選択します。
    • 作成されたマテリアルの名前を「PlayerMaterial」に変更します。
    • マテリアルの色を好きな色に設定し、PlayerCubeにドラッグ&ドロップして適用します。

2. 触れるオブジェクトの作成

  1. Sphere、Cylinder、Capsuleを作成
    • ヒエラルキーウィンドウで右クリックし、それぞれ3D Object > Sphere3D Object > Cylinder3D Object > Capsuleを選択して作成します。
    • 作成された各オブジェクトの名前を「TargetSphere」、「TargetCylinder」、「TargetCapsule」と変更します。
  2. タグの設定
    • インスペクターウィンドウで「Tag」ドロップダウンを開き、**Add Tag…**を選択します。
    • 新しいタグ「Target」を作成します。
    • 各オブジェクトに戻り、Tagを「Target」に設定します。
  3. Colliderのトリガー設定
    • 各オブジェクトのColliderコンポーネントにあるIs Triggerのチェックボックスをオンにします。
    • これにより、トリガーイベントを受け取れるようになります。

3. シーンの配置

  1. オブジェクトの位置を調整
    • PlayerCubeはシーン中央(例: X=0, Y=0, Z=0)に配置します。
    • TargetSphereTargetCylinderTargetCapsuleをCubeから少し離れた場所に配置します。
      • 例:
        • TargetSphere: X=3, Z=3
        • TargetCylinder: X=-3, Z=-3
        • TargetCapsule: X=0, Z=5

これで、プレイヤーが操作するCubeと、触れる対象となるオブジェクトの準備が整いました。次はスクリプトを作成して、これらを動かす仕組みを構築していきましょう!



3. スクリプトの作成

このセクションでは、プレイヤーが操作するCubeに触れたオブジェクトを配列に格納するスクリプトを作成します。手順に沿って進めることで、スクリプト作成と適用方法を学べます。


スクリプトファイル「CubeMove.cs」の作成

  1. プロジェクトウィンドウを開きます。
    • Unityエディター下部の「Project」タブをクリックします。
  2. 新しいスクリプトを作成します。
    • プロジェクトウィンドウを右クリックして「Create > C# Script」を選択します。
    • 作成したスクリプトに「CubeMove」という名前を付けます。
  3. CubeMove.csをCubeにアタッチします。
    • ヒエラルキーウィンドウでCubeを選択します。
    • 作成したスクリプトをCubeにドラッグ&ドロップします。

コードの記述と解説

次に、CubeMove.csを開いて以下のコードを記述します。

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

public class CubeMove : MonoBehaviour
{
    public GameObject[] myArray = new GameObject[3]; // 配列を定義
    public int count;

    void Start()
    {
        count = 0; // 初期化
    }

    void Update()
    {
        // キーボード入力でCubeを移動
        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, transform.position.z + dz
        );
    }

    void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.tag == "Target")
        {
            if (count < myArray.Length)
            {
                myArray[count] = other.gameObject; // 配列に格納
                other.gameObject.SetActive(false); // オブジェクトを非表示
                count++; // カウントを増やす
            }
        }
    }
}

コードのポイント解説

1. 配列の定義

public GameObject[] myArray = new GameObject[3];
  • この配列 myArray は、Cubeがぶつかったオブジェクトを格納するためのものです。
  • 配列の長さを3に設定していますが、必要に応じて変更可能です。

2. プレイヤーの操作

float dx = Input.GetAxis("Horizontal") * Time.deltaTime * 3.0f;
float dz = Input.GetAxis("Vertical") * Time.deltaTime * 3.0f;
  • キーボード操作でCubeを移動できる仕組みです。
  • HorizontalVertical は、UnityのInput設定でデフォルトで用意されている入力軸です。
  • Time.deltaTime を掛けることでフレームレートに依存しない動作を実現します。

3. トリガーでオブジェクトを配列に格納

void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Target")
{
if (count < myArray.Length)
{
myArray[count] = other.gameObject;
other.gameObject.SetActive(false);
count++;
}
}
}
  • Cubeが他のオブジェクトに触れた際の処理を行います。
  • 触れたオブジェクトのタグが「Target」であれば配列に追加します。
  • 配列に格納したオブジェクトは SetActive(false) を使い非表示にします。
  • 配列が満杯でない場合のみカウントを進めます。

これでスクリプトの作成は完了です!次のセクションでは、テストプレイをして実際の動作を確認します。



4. 動作確認

ここでは、作成したスクリプトと設定したオブジェクトを使用して、実際に配列にオブジェクトを格納する仕組みを動作確認していきます。

シーンの配置を確認

まずは、シーン内に配置したオブジェクトをもう一度確認してください。

  • Cube は画面中央に置き、適切に操作できるようにします。
  • Sphere, Cylinder, Capsule はCubeから少し離れた位置に配置してください(例:X=3, Z=3など)。
  • 各オブジェクトにTargetタグが正しく設定されているか確認しましょう。
  • 各オブジェクトのColliderのIs Triggerがチェックされていることを確認します。

テストプレイの準備

  1. Unityの上部メニューから 再生ボタン をクリックしてシーンを実行します。
  2. キーボードの矢印キーまたは W, A, S, D キーを使ってCubeを操作します。
  3. Cubeを移動させ、配置したSphereやCylinderなどにぶつけてみましょう。

動作の確認ポイント

  • Cubeが他のオブジェクトに触れると、そのオブジェクトが消える(非表示になる)ことを確認します。
  • 非表示になったオブジェクトが配列に格納されているか確認するには、Debug.Logを使うと便利です。 以下のコードを OnTriggerEnter メソッド内に追加してください:
Debug.Log("Added to array: " + other.gameObject.name);

これにより、Unityのコンソールに「Added to array: オブジェクト名」が表示され、配列への格納が確認できます。

配列の状態を確認する方法

配列に格納されたデータをさらに確認する場合、以下のコードを Update メソッド内に追加してみましょう:

if (Input.GetKeyDown(KeyCode.P))
{
foreach (var obj in myArray)
{
if (obj != null)
{
Debug.Log("Array contains: " + obj.name);
}
}
}

再生中に Pキー を押すと、現在の配列の状態がコンソールに表示されます。

テストが成功する条件

  • Cubeが触れたオブジェクトが myArray に格納され、SetActive(false) で非表示になっている。
  • コンソールにデバッグログが正しく表示される。
  • 配列の順序が触れた順番通りになっている。

動作確認が問題なくできたら、さらに応用例を試してみましょう。たとえば、配列内のオブジェクトを利用してスコアをカウントする仕組みを追加すると、ゲーム性を向上させられます!



5. 応用アイデア

Cubeが触れたオブジェクトを配列に格納する仕組みは、ゲーム開発でさまざまな場面に応用できます。このセクションでは、さらに面白いアイデアをいくつか紹介します。これらを参考にして、自分のプロジェクトで活用してみましょう!


① スコアシステムを追加

配列に格納されたオブジェクトの数に応じてスコアを増加させる仕組みを追加できます。たとえば、以下のような手順で実装できます:

  1. スコア変数を用意
    CubeMove.csにスコア用の変数を追加します。csharpコピーする編集するpublic int score = 0;
  2. スコアを更新
    オブジェクトに触れたときにスコアを増加させます。OnTriggerEnterメソッドに以下のコードを追加しましょう:csharpコピーする編集するscore += 10; // 触れるごとに10点追加
  3. UIで表示
    UnityのCanvasを使用して画面上にスコアを表示すると、よりインタラクティブなゲームになります。

② 制限時間付きのチャレンジ

一定時間内にできるだけ多くのオブジェクトを集めるゲームに応用できます。タイマーを追加して制限時間を設け、時間内に格納したオブジェクトの数で勝敗を決めることができます。

実装例

  1. タイマーのカウントダウンを実装:
    public float timeRemaining = 60.0f; void Update() { if (timeRemaining > 0) { timeRemaining -= Time.deltaTime; } else { Debug.Log("ゲーム終了"); } }
  2. 時間切れ後にゲームの結果を表示:
    • 配列に格納されたオブジェクトの数を画面に表示する仕組みを追加します。

③ 配列のデータを活用して特殊効果を追加

触れたオブジェクトに応じて特殊なイベントを発生させる仕組みを組み込むこともできます。

  • 異なるオブジェクトで効果を変える
    配列に格納されたオブジェクトの種類によって異なるエフェクトを発生させます。
    if (other.gameObject.name.Contains("Sphere")) { // 特定のエフェクトを発生 Instantiate(sphereEffect, transform.position, Quaternion.identity); }
  • リアルタイムで配列の内容を監視
    配列の内容をもとに、プレイヤーのステータスを変化させる仕組みも面白いです。

④ ステージクリアの条件に使用

配列のデータが一定条件を満たすとステージをクリアする仕組みを作れます。たとえば、全てのターゲットオブジェクトを配列に格納することで、次のステージに進めるように設定します。

サンプルコード

if (count == myArray.Length)
{
Debug.Log("ステージクリア!");
// 次のステージをロードする処理
UnityEngine.SceneManagement.SceneManager.LoadScene("NextStage");
}

これらのアイデアを使えば、配列を活用したシステムをさらに進化させることができます。Unityの機能を組み合わせて、自分だけのゲームを作り上げてください!



よくある質問(FAQ)

Q
配列のサイズを増やしたい場合、どうすればいいですか?
A

スクリプト内で定義されている配列のサイズを変更するだけです。以下のコードの new GameObject[3] の部分を好きなサイズに変更してください。

public GameObject[] myArray = new GameObject[5]; // 配列のサイズを5に変更

変更後は、Unityエディター上で配列サイズが増えていることを確認してください。

Q
配列に格納されたオブジェクトを再び表示させる方法は?
A

配列内のオブジェクトの SetActive(true) を呼び出すことで再表示させることができます。例えば、以下のようなコードを追加して試してみてください:

void ReactivateObjects()
{
foreach (GameObject obj in myArray)
{
if (obj != null)
{
obj.SetActive(true);
}
}
}

この関数を任意のタイミングで呼び出すと、配列内のすべてのオブジェクトが再表示されます。

Q
特定のタグだけでなく、複数のタグのオブジェクトを格納するにはどうすればいいですか?
A

OnTriggerEnter 内で条件分岐を追加して、複数のタグをチェックすることができます。例えば、以下のように ||(または)演算子を使用します:

if (other.gameObject.tag == "Target" || other.gameObject.tag == "Enemy")
{
// 格納処理
}

このようにすることで、「Target」タグと「Enemy」タグを持つオブジェクトを配列に格納できます。

おすすめのアセット

「Better UI」は、Unityの標準UIシステム(uGUI)を拡張し、より柔軟で使いやすいユーザーインターフェースを構築するためのツールです。このアセットを利用することで、解像度やデバイスに応じたレスポンシブなUIデザインが可能となり、開発効率を向上させます。

主な特徴:

  • 解像度依存のサイズ調整: 画面サイズやDPIに応じて、フォントサイズやUI要素のスケーリングを自動的に調整します。
  • 複数のトランジション対応: ボタンなどのUI要素に対して、複数の状態変化(ホバー、クリックなど)を柔軟に設定できます。
  • レスポンシブデザインのサポート: 画面の向きやサイズに応じて、UIレイアウトや要素の表示・非表示を簡単に制御できます。

おすすめポイント:

  • 初心者にも優しい設計: 既存のuGUIプロジェクトに簡単に統合でき、直感的な操作が可能です。
  • 多様なレンダーパイプラインとの互換性: ビルトイン、URP、HDRPなど、主要なレンダーパイプラインに対応しています。
  • 豊富なカスタマイズオプション: UI要素の見た目や動作を細かく調整でき、プロジェクトのニーズに合わせたデザインが実現します。