UnityUnityメモ

Unityで特定のオブジェクトを無視するRayCastの使い方!初心者向け簡単チュートリアル

Unity

はじめに

UnityのRayCast機能を使うと、ゲーム内で光線を飛ばしてオブジェクトに当たり判定を行うことができます。例えば、プレイヤーがクリックした位置にオブジェクトが存在するかを調べたり、特定の範囲内にいる敵キャラクターを検知したりするのに便利です。

しかし、すべてのオブジェクトにRayが当たってしまうと、不要な挙動を引き起こすことがあります。例えば、透明なUI要素や背景オブジェクトまで当たり判定に含まれてしまうと、プレイヤーが意図した操作が正しく反映されないこともあります。

そこで本記事では、RayCastを使いながらも特定のオブジェクトを無視する方法を解説します。今回の例として、Cube、Sphere、Capsuleをシーンに配置し、SphereだけはRayに反応しないように設定する手順をステップバイステップで説明します。

この記事を読むことで、Unity初心者の方でも簡単に「無視したいオブジェクトを設定する」方法が理解できるようになります。それでは、さっそく始めていきましょう!

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



2. シーンの準備

UnityでRayCastを使う準備として、まずはシーンに必要なオブジェクトを配置しましょう。このステップでは、CubeSphereCapsuleの3Dオブジェクトをシーンに追加します。具体的な手順を以下で説明します。


1. 新しいシーンを作成する

Unityを起動して新しいプロジェクトを開きます。まだ作成していない場合は、プロジェクト内で以下の手順を行いましょう。

  1. Unityのメニューバーから「File」→「New Scene」をクリックします。
  2. 作成したシーンを保存する場合は、「File」→「Save As」を選択し、適当な名前を付けて保存します。(例:RayCastExampleScene

2. Cubeを配置する

  1. ヒエラルキー(Hierarchy)ウィンドウ内で右クリックします。
  2. メニューから「3D Object」→「Cube」を選択します。
  3. Cubeがシーン内に追加されるので、移動ツールを使って適当な位置に配置します。(例:(0, 0.5, 0)

3. Sphereを配置する

  1. ヒエラルキーウィンドウ内で再び右クリックします。
  2. メニューから「3D Object」→「Sphere」を選択します。
  3. Sphereがシーン内に追加されるので、Cubeの横に移動します。(例:(2, 0.5, 0)

4. Capsuleを配置する

  1. 同じようにヒエラルキーで右クリックします。
  2. メニューから「3D Object」→「Capsule」を選択します。
  3. CapsuleをCubeの反対側に移動します。(例:(-2, 1, 0)

5. カメラとライトの確認

  • ヒエラルキーにデフォルトで存在する「Main Camera」と「Directional Light」を確認してください。
  • 必要に応じて「Main Camera」を移動し、オブジェクトが画面に表示される位置に調整します。(例:カメラ位置:(0, 3, -6)、回転:(20, 0, 0)

これでシーンの準備は完了です!Cube、Sphere、Capsuleが正しく配置されていることを確認したら、次のステップに進みましょう。Sphereが特定のRayCastを無視するように設定していきます。



3. 「Ignore Raycast」レイヤーの設定

このステップでは、SphereだけRayCastの判定から無視されるように設定します。Unityには、特定のオブジェクトをRayCastから無視するための便利な「Ignore Raycast」というレイヤーが用意されています。このレイヤーを使うと、簡単に特定のオブジェクトを対象外にできます!

手順1:Sphereを選択する

  1. Hierarchy(ヒエラルキー)ウィンドウで「Sphere」という名前のオブジェクトをクリックします。
    • CubeやCapsuleなど、他のオブジェクトと間違えないように注意しましょう。

手順2:「Ignore Raycast」レイヤーを設定する

  1. Inspector(インスペクター)ウィンドウの上部にある「Layer」というドロップダウンメニューを探します。
    • 通常、「Default」などが表示されています。
  2. 「Layer」をクリックすると、いくつかの選択肢が表示されます。
    • その中から「Ignore Raycast」を選択します。
    • 「Ignore Raycast」がリストに見つからない場合は、**Add Layer(レイヤーを追加)**を選び、新しいレイヤーを追加してください。

手順3:変更を適用する

  1. 「Ignore Raycast」を選択したあと、ポップアップで「Do you want to change the layer for all child objects?(子オブジェクトもレイヤーを変更しますか?)」と聞かれます。
    • Yesを選択すれば、Sphereとその子オブジェクトすべてにレイヤー設定が適用されます。
    • 子オブジェクトがない場合でも、ここは「Yes」を選んで大丈夫です。

これで、Sphereオブジェクトに「Ignore Raycast」レイヤーが設定されました!
次にスクリプトでRayCastを飛ばすと、Sphereは無視され、CubeやCapsuleにだけ反応するようになります。

この設定を活用すれば、ゲーム内でクリック不可のオブジェクトを簡単に設定できますね!



4. RayCastを使ったスクリプトの実装

このセクションでは、RayCastを使って特定のオブジェクトに対する当たり判定を行うスクリプトを作成します。今回は、クリックした位置にRayを飛ばし、当たったオブジェクトの名前をコンソールに表示する簡単なスクリプトを実装します。


スクリプトの作成方法

  1. スクリプトを作成する
    • ヒエラルキーウィンドウを右クリックして、「Create」→「C# Script」を選択します。
    • 新しいスクリプトに「RayCastExample」という名前を付けます。
  2. スクリプトを開いて編集する
    • 作成したスクリプトをダブルクリックして開きます。
    • 以下のコードをコピーして貼り付けてください。
using UnityEngine;

public class RayCastExample : MonoBehaviour
{
    void Update()
    {
        // マウスの左クリックを検知
        if (Input.GetMouseButtonDown(0))
        {
            RaycastHit hit; // Rayが当たったオブジェクトの情報を格納する変数
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); // マウス位置からRayを生成

            // RayCastで当たり判定を実行
            if (Physics.Raycast(ray, out hit, Mathf.Infinity))
            {
                // ヒットしたオブジェクトの名前をコンソールに表示
                Debug.Log("Rayが当たったオブジェクト: " + hit.collider.name);
            }
        }
    }
}

スクリプトのポイント解説

  • Input.GetMouseButtonDown(0)
    マウスの左クリックを検知します。0は左クリック、1は右クリック、2は中央クリックを意味します。
  • Camera.main.ScreenPointToRay(Input.mousePosition)
    カメラの視点からマウスの位置に向かってRayを飛ばします。
  • Physics.Raycast
    Rayを飛ばし、オブジェクトに当たった場合に情報を取得します。out hitでヒット情報を格納し、Mathf.InfinityでRayの長さを無限に設定しています。
  • Debug.Log
    当たったオブジェクトの名前をコンソールに表示します。これでどのオブジェクトにRayが当たったか確認できます。

スクリプトをカメラにアタッチ

  1. ヒエラルキーウィンドウで「Main Camera」を選択します。
  2. インスペクターウィンドウの「Add Component」ボタンをクリックします。
  3. 検索バーに「RayCastExample」と入力し、スクリプトを追加します。

これで準備は完了です!Unityエディタでゲームを実行し、オブジェクトをクリックしてみてください。Sphereは「Ignore Raycast」レイヤーに設定されているため、無視されます。CubeやCapsuleをクリックすると、それぞれの名前がコンソールに表示されます。

次のセクションでは、この設定が正しく動作しているか確認する方法を紹介します!



5. 動作確認

それでは、これまでの設定やスクリプトが正しく動作しているかを確認しましょう!以下の手順に沿って進めてください。


1. ゲームを再生する

Unityエディタの上部にある再生ボタン(▶)をクリックしてゲームを実行します。


2. クリックしてRayを飛ばす

ゲームビュー上で任意の場所を左クリックしてみてください。スクリプトが正しく動作していれば、クリックした位置にRayが飛び、次のような結果が得られるはずです。

  • CubeやCapsuleをクリックした場合
    コンソールウィンドウに「Rayが当たったオブジェクト: Cube」や「Rayが当たったオブジェクト: Capsule」と表示されます。
  • Sphereをクリックした場合
    コンソールウィンドウに何も表示されません。Sphereは「Ignore Raycast」レイヤーに設定されているため、Rayが無視されます。

3. エラーや問題がある場合の確認ポイント

もし思った通りに動作しない場合、以下をチェックしてください:

  1. Sphereのレイヤー設定
    • ヒエラルキーでSphereを選択し、インスペクターウィンドウでレイヤーが「Ignore Raycast」になっていることを確認してください。
  2. スクリプトのアタッチ
    • 作成したスクリプト「RayCastExample」がカメラにアタッチされているか確認します。カメラを選択し、インスペクターウィンドウで「RayCastExample」がコンポーネントとして表示されていることを確認しましょう。
  3. スクリプト内のコードに問題がないか
    • スクリプトにタイプミスやエラーがないかチェックします。特に以下のポイントを確認してください:
      • Physics.Raycastの引数が正しい
      • Camera.mainが正しく取得されている

4. 再度テストを行う

上記の修正を行ったら、再度ゲームを再生して動作を確認します。同じ手順でクリックし、コンソールウィンドウの出力をチェックしてください。


無事にSphereを無視してRayが動作していれば成功です!これで、特定のオブジェクトを無視するRayCastの設定が完了しました。お疲れさまでした!🎉次のセクションでは、さらに応用例について触れていきます!



6.応用例

RayCastで特定のオブジェクトを無視する設定は、ゲーム開発において非常に便利です。このセクションでは、さらに応用できるいくつかの例を紹介します。


1. 特定のレイヤーのみを判定対象にする

「Ignore Raycast」レイヤーを使うだけでなく、特定のレイヤーだけを対象にする方法もあります。たとえば、敵キャラクターや重要なアイテムだけをRayCastで検知したい場合には、以下のコードを使用します。

void Update()
{
if (Input.GetMouseButtonDown(0))
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

// レイヤーマスクを設定(例: "Enemy" レイヤーのみ)
int layerMask = LayerMask.GetMask("Enemy");

if (Physics.Raycast(ray, out hit, Mathf.Infinity, layerMask))
{
Debug.Log("敵キャラクターにヒットしました: " + hit.collider.name);
}
}
}

このコードでは、LayerMask.GetMaskを使って「Enemy」レイヤーを設定しています。この方法を使えば、対象をより細かくコントロールできます。


2. カスタムレイヤーを活用した高度な設定

「Ignore Raycast」以外のカスタムレイヤーを作成して、より複雑な状況に対応することも可能です。たとえば、以下のようなレイヤー構成を作成できます:

  • Player:プレイヤーキャラクターに設定
  • Enemy:敵キャラクターに設定
  • Environment:背景オブジェクトに設定
  • Interactable:クリック可能なアイテムに設定

このようにレイヤーを分けておくと、以下のようなカスタム条件でRayCastを使うことができます。

int playerAndEnemyLayerMask = LayerMask.GetMask("Player", "Enemy");

if (Physics.Raycast(ray, out hit, Mathf.Infinity, playerAndEnemyLayerMask))
{
Debug.Log("プレイヤーまたは敵キャラクターにヒットしました: " + hit.collider.name);
}

これにより、プレイヤーと敵キャラクターのみに反応し、それ以外のオブジェクトは無視する設定が簡単に行えます。


3. 透過オブジェクトを無視する

透明なオブジェクト(例: ガラスやUIエフェクト)にRayが当たらないようにすることもできます。これには、透過オブジェクト専用のレイヤーを作成し、「Ignore Raycast」レイヤーのように設定するのがおすすめです。

さらに、透明度を考慮してヒット結果をフィルタリングするスクリプトも可能です。たとえば、オブジェクトのマテリアルやタグを判定することで、柔軟な対応ができます。


4. 非同期RayCastを使った負荷軽減

リアルタイムで多数のRayCastを使用する場合、パフォーマンスが低下することがあります。この問題を解決するために、「Physics.RaycastNonAlloc」を使うと、ヒット結果の配列を再利用できるので、負荷を軽減できます。

RaycastHit[] hits = new RaycastHit[10];
int hitCount = Physics.RaycastNonAlloc(ray, hits, Mathf.Infinity, layerMask);

for (int i = 0; i < hitCount; i++)
{
Debug.Log("ヒットしたオブジェクト: " + hits[i].collider.name);
}

これらの方法を組み合わせることで、RayCastを使ったインタラクションの幅が大きく広がります。例えば、クリック可能なアイテムを動的に制御したり、敵のみに反応するターゲットシステムを構築するなど、多くの場面で活躍します。



7. まとめ

この記事では、UnityのRayCast機能を使いながら、特定のオブジェクトを無視する方法について解説しました。以下が今回のステップの振り返りです:


  1. シーンの準備
    Cube、Sphere、Capsuleをシーンに配置して、基礎となる環境を構築しました。
  2. 「Ignore Raycast」レイヤーの設定
    Sphereを「Ignore Raycast」レイヤーに割り当てることで、RayCastに反応しないように設定しました。このレイヤーを活用することで、不要なオブジェクトを簡単に除外できます。
  3. スクリプトの作成と実装
    RayCastを利用してクリックした位置に光線を飛ばし、ヒットしたオブジェクトを識別するスクリプトを作成しました。これにより、指定したオブジェクト以外が反応する仕組みを構築できました。

この方法を使えば、ゲーム内でクリック可能なオブジェクトを効率よく管理したり、特定のオブジェクトをプレイヤーの操作対象から除外したりすることが可能になります。また、「Ignore Raycast」以外にもカスタムレイヤーを活用することで、さらに複雑な条件分岐や処理を行うことができます。

ぜひこの記事の内容を活用して、より快適で効率的なゲーム開発に挑戦してみてください!UnityのRayCastはとても強力な機能なので、応用次第で可能性は無限大です。楽しみながら試してみてくださいね! 🎮✨



よくある質問

Q
RayCastに特定のレイヤーを含めるにはどうすればいいですか?
A

Unityでは Physics.RaycastLayerMask を指定することで、特定のレイヤーだけを含める、または除外することができます。以下は例です:

LayerMask mask = LayerMask.GetMask("MyLayer");
if (Physics.Raycast(ray, out hit, Mathf.Infinity, mask))
{
Debug.Log("指定したレイヤーにRayが当たりました: " + hit.collider.name);
}

このコードでは、”MyLayer” という名前のレイヤーだけを対象にしています。他のレイヤーにはRayが反応しません。

Q
RayCastの距離を制限する方法は?
A

RayCastの最大距離は、Physics.Raycast の第3引数で指定できます。例えば、10ユニット以内に限定したい場合は以下のようにします:

if (Physics.Raycast(ray, out hit, 10f))
{
Debug.Log("10ユニット以内で当たったオブジェクト: " + hit.collider.name);
}

これにより、Rayは10ユニット以内のオブジェクトにしか当たらなくなります。パフォーマンスを考慮して距離を設定するのがおすすめです。

Q
「Ignore Raycast」以外のレイヤーを使うべき場面は?
A

「Ignore Raycast」レイヤーは便利ですが、複雑な条件に対応するにはカスタムレイヤーを使う方が柔軟です。たとえば、ゲーム内で「敵」「アイテム」「環境」などのカテゴリごとにレイヤーを分けることで、RayCastが特定の対象にのみ反応するように制御できます。

LayerMask enemyLayer = LayerMask.GetMask("Enemy");
LayerMask itemLayer = LayerMask.GetMask("Item");
if (Physics.Raycast(ray, out hit, Mathf.Infinity, enemyLayer | itemLayer))
{
Debug.Log("敵またはアイテムにRayが当たりました: " + hit.collider.name);
}

このようにビット演算子を使うことで、複数のレイヤーを同時に対象にできます。

おすすめのアセット

「Alpha Raycaster」は、透明部分を正確に判別してクリックを反映するためのツールです。これにより、UI要素の透過部分が誤ってクリックされることを防ぎます。通常のRaycastでは難しい、透明部分を無視して画像の形状に沿った正確なクリック検出を実現します。特にカスタムのボタンや画像が多いUIで役立ち、ゲームやアプリの操作性が向上します。導入も簡単で、既存のプロジェクトにすぐに組み込めます。