2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Unity UI設定:RenderModeについて Screen Space Overlay , Screen Space Camera , Screen Space World

Last updated at Posted at 2021-07-21

3DゲームにおけるUIの使い道

  • プレイ画面とは別にして、表示するUI。(上に出てる制限時間とか)
  • ワールド座標上に表示されるUI。(右側に白文字で書いてある”中央ウィンドウ”とか)
  • プレイヤーの上や下に表示されるUI。(キャラの緑のHPバーとか)
    image.png
    引用 : https://valorant-5chnews.com/archives/3698

見た感じの動きはこのサイト参考
https://light11.hatenadiary.com/entry/2019/04/15/232416

Screen Space Overlay

まずUIと言われると思い浮かぶのがこれ。
画像のMAPの表示や制限時間表示などはUIっぽいUIの使い方。
image.pngimage.png
CanvasにTextやImageを追加してみる
Canvasの設定のRenderModeをScreenSpace-Overlayにする
カメラで映している画像をDisplay1に映し、その映像の上からOverlay(被せる)する形でUIを表示する。

Screen Space Camera

これは Screen Space - Overlay に似ていますが、このレンダーモードでは、キャンバスは指定されたカメラの前に一定の距離で置かれます。
引用 : https://docs.unity3d.com/ja/2018.4/Manual/UICanvas.html
見た目Overlayとほとんど変わらない。カメラの指定距離先に表示なんでカメラを移動しても見た目変わらん。
変わるのは3D空間に配置されるから手前にObjectがあるとさえぎられること。
image.pngimage.pngimage.png
引用 : https://tech.pjin.jp/blog/2017/03/02/unity_ugui_canvas_rendermode/

Screen Space World

これはCanvasをワールド上に設置するタイプ
image.png
引用 : オーバーウォッチ
イメージこんな感じ、何層にもなってる円形の重なりが作れる。
もちろんオブジェクトの影に隠れる。

あれ?この3つだと壁越しのUI表示できなくない???

それはWorld SpaceをScreen Space Overlayへするから
参考: https://tsubakit1.hateblo.jp/entry/2016/03/01/020510
Updateで
position = RectTransformUtility.WorldToScreenPoint (Camera.main, target.position);
でWorld SpaceだったUIのCanvasの座標をCameraの映像にOverlayするCanvasに対しての座標に変換するといける。
つまりワールド座標を元に、UI座標に表示が可能なのである。

参考資料もう一つ
https://gametukurikata.com/ui/damagepointui
ゲームに実装するときに画像がフェードアウトするようにする方法の紹介

実際の手順

考え方がわかっても手順がわからないUnityあるある

工程
ターゲットの設置
UIのプレハブ作成
ターゲットについてるスクリプトでUIのプレハブ生成
動的にUIの座標を変化させる

ターゲットの設置

ターゲットとは、例えばダメージを受けたプレイヤーオブジェクトのこと
ダメージUIとかはそのプレイヤーオブジェクトによって生成されるのがいいよね?(ここは使い方によっては別の手法もあり)
今回は適当にCubeとかでよい

UIのプレハブ作成

UIのプレハブを作成する。
image.png
大事なのはCanvasごとプレハブにしないこと。UIとして表示する中身のTextだけでよい。また、座標は自動で変更なので操作しなくていいのと、文字サイズについても後で変更するべき。
image.png
ただし自分はTextのParagraphだけは真ん中真ん中の設定にしてる。これのほうが個人的にわかりやすい。

動的にUIの座標を変化させる

UI自身にワールド座標からUIの座標に来てもらえるようにScriptを追加する。
Targetによって生成された時点ではどこにいるかわからない状態なので、Targetの座標を参考にUI座標に移動しよう。

UIFollowTarget.cs
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class UIFollowTarget : MonoBehaviour {
	RectTransform rectTransform = null;
	[SerializeField] Transform target = null;
	public Vector2 offset;
	void Awake() {
		rectTransform = GetComponent<RectTransform>();
	}
	void Update() {
		if (target != null) {
			rectTransform.position = RectTransformUtility.WorldToScreenPoint(Camera.main, target.position) + offset;
        } else {
			Debug.LogError("だめ");
        }
	}
	public void SetTarget(Transform targetTransform) {
		target = targetTransform;
    }
}

AwakeでUI自身が自分のUI座標にアクセスできるようにする(GetComponent())
AwakeじゃなくてもStartでもいい。
必要な情報はRectTransformUtility.WorldToScreenPointでTargetのワールド座標とMainCamera。Targetのワールド座標を取るために、TargetがUIプレハブを生成したときにTargetが情報を入れるようにする。それ用のSetTarget()を準備。
MainCameraはCamera.mainで取得できるのでそのまんま入れればOK。
ということでUpdateでUIのUI座標をTargetのワールド座標を元に算出し続ければ解決。

ターゲットについてるスクリプトでUIのプレハブ生成

次はTargetにUIを生成する機能を付ける。ここでは特定のCanvasに対して特定のUIを表示する機能を追加する。ダメージを食らったら、とかの条件はIfとかでなんとでもできるのでStartで表示するようにする。
UIInstantate.cs作成(名前は何でもいい)

UIInstantate.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UIInstantate : MonoBehaviour{
    public GameObject textUI;
    public Canvas canvas;
    void Start(){
        GameObject UIObj = Instantiate(textUI,canvas.transform);
        UIObj.GetComponent<UIFollowTarget>().SetTarget(transform);
    }
}

Inspector上で表示するプレハブとCanvasをセットしておく
StartでセットしたUIプレハブをInstantiateして、それのTargetを自分に設定

表示の大きさを見てプレハブの文字サイズを変更することで調整するといい

終わりに

UI難しい。
このメモを数か月後に自分が見て、果たして理解できるのだろうか心配になる。

end

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?