【Unity】【UI】UIまとめ

# シーンとUIの関係性について
・1シーンにつき1つのキャンバスが存在する。
・全てのUI要素はキャンバスの子として配置される。

# UIのサイズについて
・UIのサイズはキャンバスがデフォルトで持つスクリプトで設定できる。

# UIの親子関係
・UIに親子関係を持たせたい場合，空のコンポーネントのオブジェクトの下に子のUIを設置する。
・子のUIのアンカーポイントは親に依存する。

## Canvas
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505426/c6cda462-b6e0-3ede-0d06-0e8c0e82df50.png)
・UIを立体的に表示させるかといった設定

| RenderMode | 説明 |
|:--|:--|
|  Overlay | カメラに依存せず，レンダリング後にUIが配置される。  |
|  Camera |  カメラの状態によって見た目が変わってくる。 |
|  WorldSpace | UIがほかのオブジェクトと同様に扱われる。UIのZ座標が大きければ手前のオブジェクトに隠れる。 |

## Canvas Scaler
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505426/1a4f8f12-4a05-beb7-d102-9ab40f9918e0.png)

・画面の解像度が変更に伴い，UIのサイズをどう変更するかの設定。

| UI Scale Mode | 説明 |
|:--|:--|
| Constant Pixel Size  | 画面サイズが変わっても, UIのサイズが固定。 |
| Scale With Screen Size  | 画面のサイズに追従して,UIのサイズが変わる。  |
| Constant Phisical Size  | 設定した解像度によって,UIのサイズが変わる。  |

## Screen Match Mode (Scale With Screen Sizeの場合)
・参考サイトの動画が非常に参考になる。

| Screen Match Mode | 説明 |
|:--|:--|
| Match Width or Height  | Width = 1の時, 横に縮めるとUIが小さくなるが縦に縮めてもサイズは変わらない。Heightはその逆。  |
| Expand  | 縦に縮めても，横に縮めてもUIは小さくなる。  |
| Shrink  | 縦に縮めても，横に縮めてもUIのサイズは変わらない。  |

## Rect Transform
・UIの座標はUIのローカル座標(Rect Transform.localPosition)を使用する。
  (Transform.positionは使用しない。)
### ローカル座標
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505426/1ff01919-37a8-7134-b770-18e4d6a30315.png)
・ローカル座標は親要素のピボット(点P)を原点とした自身のピボット(点C)の座標

### ピボット
(0.5 , 0.5)
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505426/644bb097-1da4-2da8-4715-8cba58c2f81f.png)
(0.1 , 0.5)
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505426/d08b79ad-db12-2915-7f89-2a74a5e63040.png)
・回転の軸となる座標

### アンカー
<blockquote class="twitter-tweet"><p lang="und" dir="ltr"><a href="https://t.co/vhnD8lIS5g">pic.twitter.com/vhnD8lIS5g</a></p>&mdash; めぞふち (@mezofuchi) <a href="https://twitter.com/mezofuchi/status/1202518893085900800?ref_src=twsrc%5Etfw">December 5, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
・親要素のRect Transformの変動に伴う、子の座標への影響を決める。
・アンカーの決め方は２種類ある。
  - アンカープリセットから決める。基本的にはこちらのみで事足りるはず。
  - Min, Maxの値を設定する。(それぞれ0 ~ 1)
・動画ではアンカーポイントを「Left Top(0:00~)」「Bottom Right(0:28~)」「Center(0:56~)」「Top(1:20~)」の順に設定している。
・「Left Top」: 左と上の変動を100%受ける。(左上に固定される。)　右と下の変動を0%受ける。(子は影響されない。)
・「Right Bottom」 : 左と上の変動を0%受ける。(子は影響されない。)　右と下の変動を100%受ける。(右下に固定される。)
・「Center」 : 上下左右から50%ずつ影響を受ける。(結果として親のCenterからの相対座標が固定される。)
・Inspectorに表示されるPosX,Y,Zはアンカーを原点としたピボットの座標のため、
　アンカーを変えると座標の値も変わる。

## UIを非UIに追従させる。
```csharp
    void Update()
    {
        Vector2 pos;
        // UIのオブジェクトをワールド座標からスクリーン座標に変換する。
        Vector2 screenPos = RectTransformUtility.WorldToScreenPoint(Camera.main, targetTransform.position + offset);
        // スクリーン座標からローカル座標(親UIからのCenterからの相対座標)を取得する。
        RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRectTransform, screenPos, Camera.main, out pos);
        myRectTransform.position = myRectTransform.position;
        // ローカル座標を設定する。
        myRectTransform.localPosition = pos;
    }
```
・上記オブジェクトをUIにアタッチする。
・シャドウバースのカード(イラストにHPやCostを追従)や、アクション(キャラクターの上部にHPを追従)の際に使用する。
・CanvasのRender ModeがCameraである必要がある。

## 非UIをUIオブジェクトに追従させる。
```csharp
  targetTransform.position = myRectTransform.position;
```
・上記オブジェクトをUIにアタッチする。

## まとめ
・UIが位置固定であれば「CanvasのRenderMode 」は「Overlay 」一択
・画面サイズが機種によって異なるスマホでれば「UI Scale Mode」は「Scale With Screen Size」一択
・「Screen Match Mode」は「Match Width or Height」か「Expand」
　「GUIの数が多く、縮小させて表示させる必要があるか」「GUIの数が少なく、縮小させる必要がないか」で
　使い分けるのかという妄想であるが、大抵のスマホゲーは画面狭しとGUIが配置されているため,「Expand」一択でいいかもしれない。

# 参考サイト
Canvasに関して
[【Unity開発】uGUIのCanvas Scalerの使い方【ひよこエッセンス】](https://hiyotama.hatenablog.com/entry/2015/06/30/090000)
[【Unity徹底解説】Canvas Scaler【使い方・スクリプト】](https://dkrevel.com/unity-explain/canvas-scaler/)

Rect Transformに関して
[Rect Transform](https://docs.unity3d.com/ja/current/Manual/class-RectTransform.html)
[基本的なレイアウト](https://docs.unity3d.com/ja/current/Manual/UIBasicLayout.html)

UIを非UIに追従させる
[【Unity】uGUIをキャラクターの上に表示する手っ取り早い方法【RenderMode別】](https://tech.pjin.jp/blog/2017/07/14/unity_ugui_sync_rendermode/)