Unity

Unityでワイプ画面を表示する方法|サブカメラとクリック判定の実装解説

はじめに

今回は Unityを使ってワイプ画面を表示する方法をご紹介します。

複数の画面を同時に表示することで、ゲーム内の表現の幅を広げることができます。
また、表示位置を分けることで、光源の影響を受けないようにするなど、実用的な工夫にも役立ちます。

ワイプとは?

ワイプとは、メインの画面とは別に表示される小さな画面のことです。
テレビ番組でよく見かける「画面端に映る芸能人のリアクション」などが分かりやすい例です。

ゲーム内では、UIの一部としてカメラ映像を表示したいときに使えます。

ワイプを使うとできること

  • UIとして 自由な位置・大きさに配置できる
  • ゲーム画面の中に 別カメラの映像を表示できる
  • ワイプの中の オブジェクトをクリックして操作できる

作成中のプロジェクトでの課題

現在進めているUnityプロジェクトでは、次のような課題がありました:

  • UI上に選択中のアイテム(3Dオブジェクト)を表示したい
  • しかし、カメラの視点を変えるとライトの位置も変わってしまい、見た目が崩れる

このような場合、ゲーム内の光源に左右されない表示方法が必要です。
そこで、ワイプ機能を使って別カメラで照明を管理し、安定した表示を実現することにしました。

ワイプ機能の作成

実際にUnity上でワイプを表示する手順を解説します。

準備するもの

  • SubCamera
     Hierarchy > Create > Camera
    (名前は「SubCamera」に変更)
  • RenderTexture
     Assets > Create > RenderTexture
  • RawImage
     Hierarchy > Create > UI > RawImage
    (Canvas内に配置される)

手順解説:ワイプの作り方

SubCamera の設定

  • Output Texture」に作成した RenderTexture を設定
  • SubCamera の位置を調整し、表示したいオブジェクトが映るようにする

RawImage の設定

  • Texture」に同じ RenderTexture を指定
  • RawImage のサイズと位置をUI上で自由に調整

実際のプロジェクトで使ってみる

以下は、自分のプロジェクトでワイプを応用した例です。

ワイプ内だけ光源を適用する工夫

  1. 表示するオブジェクトを 遠くのシーン外エリアに配置
  2. ゲーム内の光源(全体照明)を すべてオフ
  3. SubCameraの近くに新たな Directional Light を追加

これにより、UIに表示するオブジェクトだけにライトが当たるようになります。

オブジェクトを遠くに配置
メインシーンの光源をオフ
サブカメラの子にライトを追加

動画でも確認可能

動画でも確認

部屋の光源をオンにした状態でも、UI上のオブジェクトは明るく表示されていることが確認できます。

新たな課題:ワイプ内のオブジェクトをクリックしたい

このプロジェクトでは、UIに表示されたアイテムをクリックして合成する処理があります。
そのため、ワイプの中の3Dオブジェクトをクリック可能にする必要があります。

対応方法:サブカメラからの Raycast

クリックを検知するには、サブカメラの視点から Ray を飛ばして対象を判定する仕組みが必要です。
これにより、RawImage越しに3Dオブジェクトをクリックできるようになります

ワイプの中のオブジェクトをクリックできるようにする

ワイプの中に表示されたオブジェクトも、クリックして操作できたら便利ですよね。
たとえば、アイテムを選択して合成したり、詳細を表示したりといったUI的な操作が可能になります。

ただし、RawImage上に表示されているのはカメラの映像(RenderTexture)であって、実際の3Dオブジェクトではありません。
そのため、普通のクリック判定では反応してくれません。

なぜ特別なRaycastが必要?

通常、カメラから直接見えているオブジェクトには Physics.Raycast() でクリック判定できます。
ですが今回は、

  • UI上のRawImageにRenderTextureが映っている
  • その映像は、SubCameraが映している3D空間の一部

という構造なので、SubCamera の視点から Ray を飛ばす必要があります。

処理の流れ

  1. RawImage をクリック
    → UI上に表示されたワイプをユーザーがクリックします。
  2. クリックした位置を「ワイプ上の座標(UV)」に変換
    → RawImage内での相対位置(0~1の範囲)を取得します。
     ※例:左上が (0,1)、右下が (1,0)
  3. SubCamera にその位置を教えて「Ray(光線)」を作成
    ViewportPointToRay() を使って、UV座標から 3D 空間へ向かう Ray を生成します。
  4. その Ray が何に当たるか調べる(Physics.Raycast)
    → Ray がぶつかったオブジェクトを調べ、クリック対象として扱います。

スクリプト例

WipeRaycaster.cs
using UnityEngine;
using UnityEngine.EventSystems;

public class WipeRaycaster : MonoBehaviour, IPointerClickHandler
{
    public Camera subCamera; // SubCamera(RenderTextureを出力してるカメラ)
    public RectTransform rawImageRectTransform; // RawImageのRectTransform
    public LayerMask raycastLayerMask; // ヒット対象のレイヤー

    public void OnPointerClick(PointerEventData eventData)
    {
        // RawImage上でのクリック座標(スクリーン座標)
        Vector2 localPoint;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(
            rawImageRectTransform, eventData.position, eventData.pressEventCamera, out localPoint
        );

        // RawImage の Rect 内での位置 → UV座標に変換
        Vector2 size = rawImageRectTransform.rect.size;
        Vector2 pivot = rawImageRectTransform.pivot;

        float x = (localPoint.x / size.x) + pivot.x;
        float y = (localPoint.y / size.y) + pivot.y;

        Vector3 viewportPos = new Vector3(x, y, 0);
        Ray ray = subCamera.ViewportPointToRay(viewportPos);

        // Raycast を飛ばす
        if (Physics.Raycast(ray, out RaycastHit hit, 100f, raycastLayerMask))
        {
            Debug.Log("オブジェクトにヒット: " + hit.collider.name);

            // 例:オブジェクトにインターフェースやカスタム処理があれば呼び出す
            var clickable = hit.collider.GetComponent<IClickable>();
            if (clickable != null)
            {
                clickable.OnClick();
            }
        }
    }
}

セットアップ方法(Unity側)

  1. RawImageの GameObject にこのスクリプトをアタッチ
  2. subCamera に RenderTexture 出力用カメラを指定
  3. rawImageRectTransform に対象の RawImage をドラッグ
  4. ヒットさせたいオブジェクトを特定の Layer に設定し、raycastLayerMask に登録
  5. EventSystemGraphicRaycaster(Canvas) がシーンに存在していることを確認

使い方の補足:クリック処理の受け取り方

usingとclassの間に、以下のようなインターフェースの定義を追加する必要があります:

public interface IClickable
{
    void OnClick();
}

このインターフェースを使うことで、「クリックされたときに何らかの処理を実行できるオブジェクト」を共通の仕組みで扱えるようになります。

コード全体
using UnityEngine;

public interface IClickable
{
    void OnClick();
}

public class ZoomItem : MonoBehaviour, IClickable
{
    public void OnClick()
    {
        // 実行したい処理をここに書く
        Debug.Log("Tileをクリック");
        ItemBox.instance.Fusion(Item.Type.BlueTile, Item.Type.RedTile, Item.Type.PurpleTile);
    }
}

このように、OnClick() メソッドの中に処理を書けば、クリックされたときにその内容が実行されます。

インターフェースとは、クラスに「このメソッドは絶対に実装してくださいね」と約束させる仕組みです。

クリック検出処理では、Rayが当たったオブジェクトが IClickable を実装していれば、OnClick() を呼び出すようにします。

動画で確認

おまけ:プレイヤーの顔を常に表示させる

ワイプ画面の使用例です。

プレイヤーキャラクターの顔をワイプを使って常に表示させます。

プレイヤーキャラクターの子にSubCameraを配置し常に追従するようにします。
CanvasにRawImageを追加し位置やサイズを設定します。
RenderTextureを作成しSubCameraとRawImageにセット。

これで常にプレイヤーの正面の映像が左下に表示されるようになりました。

しかし今のままだとHPバーなどのUIも表示されてしまっています。

レイヤーマスクを使う

レイヤーマスクを設定することでワイプに表示させる対象を絞ることができます。

プレイヤーにレイヤーを設定し、SubCameraの「Culling Mask」を設定
表示させたいレイヤーのみを選択します。

動画で確認

持ってる武器とプレイヤーだけ表示されていい感じ

まとめ

今回は、Unityでワイプ機能を作成する方法ワイプ内のオブジェクトをクリックして操作する仕組みを紹介しました。

ワイプを使うことで、UIとして扱えるカメラ映像をゲーム画面に重ねたり、別の視点や状況を表示するなどゲームの表現力やインタラクションの幅を広げることができます。
さらに、Raycastを工夫することで、映像の中のオブジェクトもクリック可能になり、より柔軟なUI設計が可能になります。

ゲームの演出や操作性にこだわりたいときに、ぜひ活用してみてください。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です