【Unity】マルチディスプレイ 実装方法 と 注意点 Mac編 

# はじめに
Mac環境における、Unityのマルチディスプレイについてまとめます。
Windows環境においても、OSに依存しない設定(セカンドディスプレイの接続設定など)以外は基本的に同じです。

ここではシンプルに、Canvasを２つ用意して、各Canvas をメインモニタ(display1)とセカンドモニタ(display2)に表示することを実装します。

基本的な実装を行なった後、MacとUnityを使ったマルチディスプレイ実装の注意点を記載しています。

# 対象読者
- マルチディスプレイの実装について知りたい方
- Macにおける実装の注意点を知りたい方

# 環境
- Unity ver.2021 LTS 
- MacBook Pro M3 Pro (メインモニタ)
- LG HDR 4K (セカンドモニタ)

# 実装手順 
先に実装手順の流れを書きます。それぞれのステップは下記で説明します。

1. Cameraを作成・設定
2. Canvasを作成・設定
3. GameViewを追加し、正しく表示されているか確認
4. マルチディスプレイサポートを有効化するためのクラス実装

前提条件として、セカンドモニタをMacに接続して、システム上で認識しているか確認して下さい。``システム設定 < ディスプレイ``から確認できます。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3786602/a044f1e0-ea9c-4f75-b10a-4105b012434b.png">

:::note warn
注意点にも記載しますが、iPadをセカンドモニタとしている場合、システムのディスプレイ上では認識していても、上手く表示されない可能性があります。
:::

### 1. Cameraを作成・設定
Scene上に、**Cameraを２つ**用意します。
ここでは、「**Camera Display 1**」 と 「**Camera Display 2**」 として作成しました。
各Cameraの``Output < Target Display`` を、``Display 1`` と ``Display 2``に、それぞれ設定します。(Audio Listener が2つあると警告文が出てしまうので、1つは削除してしまって大丈夫です。)

<img width="450" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3786602/e36fd80b-b808-468d-a486-37939ee0c580.png">

:::note info
Display 1 に設定したものが、メインモニタに表示されます。
Display 2 に設定したものが、セカンドモニタに表示されます。
:::

### 2. Canvasを作成・設定
Scene上に、Canvasを２つ作成します。
ここでは、「**Canvas Display 1**」と、「**Canvas Display 2**」として作成しました。各Canvasの子要素には、ImageとTextを追加して、Display1とDisplay2が正しく表示されるか分かりやすくしました。

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3786602/0cfa91d1-a47d-4258-bed9-d763fdb032aa.png">


各Canvasの``Canvas < Render Mode``を ``Screen Space - Camera``に設定し、``Redner Camera``を設定します。
ここでは、「**Canvas Display 1 には Camera Display 1**」、「**Canvas Display 2 には Camera Display 2**」 をそれぞれ割り当てます。

(また、Canavas Scaler の Render Mode 関しては、Scale With Screen Sizeにして、Reference Resolutionは、各モニタの解像度を設定しています。)

<img width="450" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3786602/62cb19ae-7930-435a-bb13-17fc6610b620.png">

### 3. GameViewを追加し、正しく表示されているか確認
UnityEditor上で、各カメラが写しているCanvasがDisplay1とDisplay2に写っているか確認します。デフォルトでDisplay1のGameViewは配置してあるはずなので、Display2のためのGameViewを追加します。

![GameViewを追加.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3786602/ad897fae-304c-49b1-8fc4-3f324b931e2b.png)

`` ⋮ ボタン < Add Tab < Game で GameView`` を追加します。
``Gaem View Control Bar の Display ボタンをクリックして、Display 2``に設定します。

ここで、各GameViewに各Displayの映像が表示されていれば、正しくマルチディスプレイの設定ができています。

### 4. マルチディスプレイサポートを有効化するためのクラス実装

外部モニタを有効化するためのクラス MultiDisplays.cs を実装します。

``Display.displays[0]``は、メインモニタで常に有効化されています。なので、それ以外に接続されているDisplayがあれば有効化する処理を実装しています。

~~~C#:MultiDisplays.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MultiDisplays : MonoBehaviour
{
    void Start ()
    {
        Activate();
    }

    void Activate()
    {
        Debug.Log ("displays connected: " + Display.displays.Length);
        // Display.displays[0] は主要なデフォルトのディスプレイ(メインモニタ)で、常にオン。
        // その他のディスプレイが使用可能かを確認し、それぞれをアクティブにする。
        for (int i = 1; i < Display.displays.Length; i++)
        {
            Display.displays[i].Activate();
        }
    }
}
~~~

ここでは、アプリ起動時実行するために、**空のオブジェクトMultiDisplaysを作成し、この作成したクラスをアタッチ**しました。


これまでの手順を踏むと、Editor上の構成は以下の画像のようになります。
(オブジェクト・クラス名・配置などはご自由に変更して下さい）

![MultiDisplay完成画像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3786602/dfd90b7b-4dd3-4515-8d38-3e44faae9da9.png)

ここまで実装したものをビルドして実行します。実機環境において、セカンドモニタにDisplay2の内容が表示され、マルチディスプレイが実装できていることを確認できるはずです。

# Macにおけるマルチディスプレイ機能の注意点 ⚠️ 

Macでマルチディスプレイアプリケーションを開発する際には、Windowsとは異なる挙動や制限があります。以下に、MacでUnityのマルチディスプレイ機能を使用する際の注意点と対処法をまとめました。

## 1. セカンドモニタのサイズ制御の制限

### 問題点

以下、公式ドキュメント参照です。
> public void Activate(int width, int height, int refreshRate)	Windows のみ。
カスタムの幅と高さの特定のディスプレイをアクティブにします。Linux と macOS X では、補助的なディスプレイは可能な場合は常にディスプレイの現在の解像度を使用します。

ディスプレイの解像度を、上記のメソッドでは制御できません。

### 回避方法
メインディスプレイのサイズは、以下のメソッドで変更できます。
~~~C#:
Screen.SetResolution(width, height, fullscreen, refreshRate); 
~~~
ただし、セカンドディスプレイのサイズは変更できません。

セカンドディスプレイの解像度(サイズ)を変更したい場合は、Macの``システム設定 < ディスプレイ``に表示されているセカンドモニタをクリックして設定します。


<img width="450" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3786602/7694d2f8-dd43-4af1-8bb0-061b0cb19ef7.png">

表示できる解像度は、使用するモニタ・OS設定に依存するので注意が必要です。
また、表示コンテンツをディスプレイサイズに合わせてどのように表示するかなども留意しましょう。

## 2. Mac の Sidecarなど仮想ディスプレイの制限

### 問題点
私の環境だと、macOSのSidecar機能（iPadをセカンドディスプレイとして使用）はUnityから正しく検出することが出来ませんでした。

### 対応
仮想ディスプレイは``Display.displays``の配列に含まれない場合があるので、標準的な物理ディスプレイ接続を優先することを検討しましょう。

## 3. Fullscreen Mode Windowed 設定

### 問題点
``Project Settings < Player < Resolution and Presentation < FullScreen Mode`` で**Windowed**を指定してもフルスクリーンになる場合があります。

### 対応
メソッドで明示的に指定します。
~~~C#:
Screen.SetResolution(width, height, fullscreen, refreshRate); 
~~~
起動時、一度 FullScreen になってから 指定した Window サイズになるという挙動になってしまうが、変更することは可能でした。

(MacOS14以降の機能である[ゲームモード](https://support.apple.com/ja-jp/105118)をOFFにしたりなど、対応しましたが明示的に指定しなければFullスクリーンになってしまいました。他に見落としている設定があるかもしれません。)

## まとめ

Macでマルチディスプレイアプリケーションを開発する際は、セカンドディスプレイのサイズ制御が実装できないなどの制限があります。実装したいマルチディスプレイを、実機環境で実現できるものなのか早い段階で検証することをお勧めします！


# 参考文献

https://docs.unity3d.com/ja/current/Manual/MultiDisplay.html

https://docs.unity3d.com/ja/2022.3/Manual/PlayerSettings-macOS.html

https://support.apple.com/ja-jp/105118

https://light11.hatenadiary.com/entry/2019/04/21/222337

https://light11.hatenadiary.com/entry/2019/04/15/232416