UnityUnityメモ

Unity初心者必見!左クリックでオブジェクトリストに追加、右クリックで配置する方法

Unity

はじめに

Unityでのゲーム開発で、プレイヤーの操作に応じてオブジェクトを管理する仕組みを作りたいことってありますよね?この記事では、左クリックでオブジェクトをリストに追加し、右クリックで配置する仕組みを初心者でもわかりやすく解説します!クリックで削除されたオブジェクトがリストに格納され、右クリックで再配置できる便利なシステムを一緒に作ってみましょう!

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



1. 準備するもの

Unityでこの仕組みを作るには、以下のものを用意してください:


1.1 Unityの環境

  • Unity HubUnity Editor がインストールされていること。
  • 記事では Unity 2022.3.45f1 LTS 以上を基準に説明していますが、それ以前のバージョンでもほぼ同じ手順で対応できます。

2. Planeを作成してタグを設定しよう

ゲーム内でオブジェクトを配置する場所となる「Plane」を作り、そのPlaneが削除されないように特別なタグを付けます。手順を一つずつ説明しますので、一緒にやってみましょう!


1. Planeを作成する

  1. Unityの ヒエラルキー(Hierarchy)ウィンドウ を開きます。
  2. ヒエラルキーウィンドウ内で 右クリック → 「3D Object」 → 「Plane」を選択します。
    • すると、大きな平面がシーンに表示されます。これが「Plane」です。
  3. Planeの名前をわかりやすいように「Ground」に変更しておきましょう。

2. タグを作成する

  1. Planeを選択した状態で、インスペクター(Inspector)ウィンドウを確認します。
  2. インスペクター内に「Tag」という項目があります。その右側のプルダウンメニューをクリックして「Add Tag…」を選びます。
  3. 新しいタグを作成するために、右上の「+」ボタンをクリックします。
  4. 「New Tag」の名前を「NotDestroy」と入力して保存します。

3. Planeにタグを付ける

  1. 再びPlane(Ground)を選択します。
  2. インスペクターウィンドウの「Tag」のプルダウンメニューをクリックします。
  3. 先ほど作成した「NotDestroy」を選択します。

これで、このPlaneは「NotDestroy」という特別なタグが付いた状態になりました。スクリプト内でこのタグを使って、削除されないように判別する仕組みを作ります。


確認ポイント

  • ヒエラルキーウィンドウでPlane(Ground)を選択し、インスペクターの「Tag」が「NotDestroy」になっているか確認してください。
  • タグを間違えて設定すると、削除される可能性があるので注意しましょう!

次は、Capsuleを作成して配置する手順を見ていきます!



3. Capsuleを複製して配置

それでは、ゲームの中で操作するためのオブジェクトを作っていきましょう!今回は「Capsule」をいくつか作成し、それぞれ違う色にして配置します。


① Capsuleを作成する

  1. ヒエラルキーウィンドウ右クリック → 「3D Object」 → 「Capsule」を選びます。
    • ヒエラルキーに「Capsule」という名前のオブジェクトが追加されます。
  2. インスペクターウィンドウで位置を調整します。
    • 例えば、Positionの値を (0, 1, 0) に設定しましょう。Capsuleが床(Plane)の上に浮かんで見えるはずです。

② Capsuleを複製する

  1. Capsuleを選択した状態で Ctrl + D(Macの場合は Command + D)を押します。
    • Capsuleが複製され、ヒエラルキーに「Capsule (1)」のように新しいオブジェクトが追加されます。
  2. 同じ操作を繰り返して、複数のCapsuleを作成します。
    • 合計で5個ほど作成してみましょう。

③ Capsuleに色をつける

Capsuleごとに異なる色を設定します。

  1. プロジェクトウィンドウの Assetsフォルダ右クリック → 「Create」 → 「Material」を選択します。
    • 新しいマテリアルを作成し、名前を「RedMaterial」などに変更します。
  2. 作成したマテリアルを選択し、インスペクターウィンドウの「Albedo」欄をクリックします。
    • カラーピッカーが表示されるので、好きな色(例えば赤)を設定します。
  3. 作成したマテリアルをCapsuleにドラッグ&ドロップして適用します。
    • Capsuleが指定した色に変わります!
  4. 同じ手順で、青や緑など別の色のマテリアルを作成し、残りのCapsuleに適用しましょう。

④ Capsuleをランダムに配置

  1. Capsuleを1つ選択し、インスペクターウィンドウで「Transform」の値を変更します。
    • PositionのX、Z軸の値を適当に変更して、平面の上にランダムに配置してください。
    • 例えば、(X: -2, Y: 1, Z: 3) のように設定します。
  2. 他のCapsuleも同じようにPositionをランダムに変更して、全体が散らばるように配置しましょう。

完成イメージ

  • Planeの上に複数のCapsuleが置かれ、それぞれが異なる色を持っています。
  • Capsuleはランダムな位置に配置され、ゲームの準備が整いました!

これで、Capsuleの作成と配置は完了です。次に進んで、これらをクリックして操作する仕組みを作りましょう!



4. 空のオブジェクトを作成

  1. 空のオブジェクトを作成する
    • ヒエラルキーウィンドウで 右クリック → 「Create Empty」を選択します。
    • 作成された空のオブジェクトが「GameObject」として表示されます。
  2. 空のオブジェクトの役割
    • この「GameController」オブジェクトは、ゲーム全体を管理するスクリプト(今回作成する ClickObject.cs)を保持するために使用します。
    • 実際には画面に表示されませんが、重要なコントローラーとして機能します。
    • 名前を「GameController」などに変更するとわかりやすいです。



5. スクリプトを作成

ここではオブジェクトをクリックしてリストに追加し、右クリックで配置するためのスクリプトを作成します。以下の手順に従って進めてください!


スクリプトを作成する手順

  1. プロジェクトウィンドウを表示
    • Unity画面下部にある「プロジェクト」タブを確認します。
  2. 新しいスクリプトを作成
    • プロジェクトウィンドウの任意の場所を 右クリック → 「Create」 → 「C# Script」を選択し、スクリプトの名前を 「ClickObject」 と入力します。
  3. スクリプトをアタッチ
    • 作成した「ClickObject」スクリプトをドラッグ&ドロップして、ヒエラルキーウィンドウの「空のオブジェクト」に追加します。

ClickObjectスクリプトの記述

以下のコードを「ClickObject.cs」に記述します。

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

public class ClickObject : MonoBehaviour
{
    // オブジェクトを格納するリスト
    public List<GameObject> myList = new List<GameObject>();

    void Update()
    {
        // マウス位置からレイを飛ばす
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;

        // 左クリックでオブジェクトをリストに追加して非表示にする
        if (Input.GetMouseButtonDown(0))
        {
            if (Physics.Raycast(ray, out hit))
            {
                // NotDestroyタグが付いていないオブジェクトだけを操作
                if (hit.collider.gameObject.tag != "NotDestroy")
                {
                    myList.Add(hit.collider.gameObject); // リストに追加
                    hit.collider.gameObject.SetActive(false); // 非表示
                }
            }
        }

        // 右クリックでリストからオブジェクトを配置する
        if (Input.GetMouseButtonDown(1))
        {
            if (Physics.Raycast(ray, out hit))
            {
                if (myList.Count > 0) // リストに要素がある場合のみ処理
                {
                    myList[0].gameObject.SetActive(true); // 再表示
                    myList[0].gameObject.transform.position = new Vector3(hit.point.x, 1.0f, hit.point.z); // 配置
                    myList.RemoveAt(0); // リストから削除
                }
            }
        }
    }
}

コードの解説

  • Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    • マウスの位置からレイ(光線)を発射し、どのオブジェクトがクリックされたか調べます。
  • if (Input.GetMouseButtonDown(0))
    • 左クリックが押されたときの処理を記述しています。
    • クリックされたオブジェクトをリストに追加し、SetActive(false) で非表示にします。
  • if (Input.GetMouseButtonDown(1))
    • 右クリックが押されたときの処理です。
    • リストの最初のオブジェクトを再表示し、マウスカーソル位置に配置します。
  • if (myList.Count > 0)
    • リストが空でないことを確認してから処理を実行します。
  • myList.RemoveAt(0);
    • 配置が完了したら、リストの最初の要素を削除します。

1. 必要なコンポーネントや変数を定義

public List<GameObject> myList = new List<GameObject>();
  • 何をしている?
     「myList」という名前のリストを作っています。このリストは、ゲームオブジェクトを保存しておく場所です。
  • リストって何?
     データを順番に並べて管理する箱みたいなものです。ここでは、クリックで選んだオブジェクトを入れます。

2. 毎フレーム確認する Update 関数

void Update()
  • 何をしている?
     ゲーム中に毎フレーム(約0.016秒ごと)で呼ばれます。この中でマウスの動きやクリックをチェックしています。

3. マウスの位置からレイを飛ばす

Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
  • 何をしている?
     マウスの位置から「レイ」という見えない線を飛ばしています。この線が何かに当たったら、それを「hit」という変数に記録します。

4. 左クリックでオブジェクトをリストに追加して非表示

if (Input.GetMouseButtonDown(0))
  • 何をしている?
     左クリックが押された瞬間に動きます。
if (Physics.Raycast(ray, out hit))
  • 何をしている?
     飛ばしたレイが何かに当たったかをチェックしています。何かに当たっていれば、その情報が「hit」に入ります。
if (hit.collider.gameObject.tag != "NotDestroy")
  • 何をしている?
     当たったオブジェクトのタグが「NotDestroy」でないかを確認します。このタグが付いているオブジェクトは無視します。
myList.Add(hit.collider.gameObject);
hit.collider.gameObject.SetActive(false);
  • 何をしている?
     当たったオブジェクトをリストに追加し、そのオブジェクトを非表示(SetActive(false))にします。

5. 右クリックでリストのオブジェクトを配置

if (Input.GetMouseButtonDown(1))
  • 何をしている?
     右クリックが押された瞬間に動きます。
if (myList.Count > 0)
  • 何をしている?
     リストにオブジェクトが入っているかを確認します。空っぽの場合は何もしません。
myList[0].gameObject.SetActive(true);
myList[0].gameObject.transform.position = new Vector3(hit.point.x, 1.0f, hit.point.z);
myList.RemoveAt(0);
  • 何をしている?
     リストの一番最初に入っているオブジェクトを取り出して再表示(SetActive(true))します。そして、それをクリックした場所の近く(高さ1の位置)に配置します。最後にリストからそのオブジェクトを削除します。

全体の動き

  1. 左クリックで選択&非表示
     マウスでオブジェクトをクリックすると、そのオブジェクトが「myList」に追加され、画面から消えます。
  2. 右クリックで配置&再表示
     右クリックすると、リストから1つ目のオブジェクトが再表示されて、クリックした場所に置かれます。

使い方のポイント

  • タグを使った条件分け
     「NotDestroy」タグを付けたオブジェクトは無視されます。これにより、特定のオブジェクトを操作対象から外すことができます。
  • リストの管理
     リストを使うことで、オブジェクトを一時的に保存して順番に操作する仕組みを作っています。

このスクリプトを応用すれば、簡単な「オブジェクト操作ゲーム」や「配置ツール」を作れますよ!


スクリプトを保存

スクリプトの記述が完了したら、Ctrl + S (Macの場合は Command + S)で保存します。これでスクリプトの作成は完了です!

次のステップでは、このスクリプトを使用してゲームをテストしてみましょう!



6. ゲームをテストしてみよう!

さて、スクリプトの準備ができたら、実際に動かしてみましょう!以下の手順で、ゲームをテストして動作を確認します。


1. ゲームを再生する

  • Unityの上部にある「再生ボタン(▶)」をクリックして、ゲームをスタートします。

2. 左クリックでオブジェクトをリストに追加する

  • ゲームビュー上で、Capsuleを左クリックしてみましょう。
  • クリックしたCapsuleが画面から消えます。これは、スクリプト内で SetActive(false) に設定され、リスト(myList)に追加されたためです。
  • Planeは「NotDestroy」タグが付いているので、クリックしても何も起こりません。

3. 右クリックでオブジェクトを再配置する

  • 次に、適当な場所で右クリックしてみましょう。
  • 最初にリストに追加されたCapsuleが、右クリックした場所に再配置されます。再配置されたCapsuleは再び表示され、リストから削除されます。
  • もしCapsuleを複数クリックしてリストに格納していれば、一番古く追加されたCapsuleから順番に再配置されます。

4. 複数回操作して確認する

  • 左クリックで複数のCapsuleを消してみて、リストにどんどん追加していきます。
  • 右クリックを何度か行い、Capsuleが格納された順番に再配置されることを確認してください。
  • リストにオブジェクトがなくなった状態で右クリックしても何も起こらないことも確認しましょう。

5. Planeをクリックしてみる

  • Planeを左クリックしても、削除されないことを確認しましょう。「NotDestroy」タグのおかげで、リストに追加されず、画面上にそのまま残ります。

これで、オブジェクトをリストに追加して再配置する仕組みが動作するかをテストできました!問題がなければ成功です🎉

もしうまく動作しない場合は、以下をチェックしてみてください:

  • Planeに「NotDestroy」タグが正しく設定されているか。
  • スクリプトがGameControllerに正しくアタッチされているか。
  • カメラがシーン内に存在し、プレイヤーがクリックする位置を認識できているか。

ゲームが正しく動作したら、次はこの仕組みをもっと面白くするアレンジを試してみましょう!



まとめ

いかがでしたか?この記事では、Unityで「クリックしてオブジェクトをリストに格納し、あとで再配置する仕組み」を作る方法を解説しました。この仕組みを使えば、アイテム管理やカスタマイズ可能なゲームシステムを実現できます。Planeに「NotDestroy」タグをつけたり、リスト操作のスクリプトを工夫することで、自由度の高いゲームデザインが可能になります。

また、ここで作ったコードや仕組みは応用しやすいので、エフェクトを追加したり、UIを組み合わせたりして、ぜひあなたのゲームに活かしてくださいね!Unityの可能性は無限大なので、少しずつチャレンジしていきましょう!

よくある質問

Q
Planeをクリックしても削除されないのはなぜ?
A

Planeには「NotDestroy」というタグを設定しているため、このタグが付いたオブジェクトはリストに追加されず、削除もされません。

Q
配置するオブジェクトがリストになかったらエラーが出ますか?
A

このスクリプトでは、リストが空の場合には右クリックで何も起こらない仕様になっています。そのためエラーは出ません。

Q
Q3. なぜ「SetActive(false)」を使ってオブジェクトを非表示にしているのですか?
A

非表示にすることでオブジェクトを削除せず、後から再配置できるようにしています。完全に削除する場合は Destroy(gameObject) を使います。