質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

8106閲覧

UIを画面中央に配置させる方法。

退会済みユーザー

退会済みユーザー

総合スコア0

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2020/02/08 18:53

編集2020/02/15 15:28

前提・実現したいこと

UIをスクリプトで普遍的に画面中央に配置させるには、どのような方法がよいでしょうか?
UIはピボットの位置でUIの座標が変わったり、Canvas Scalerとかで何かしら座標に影響が出そうなので、
それらに影響されず、スクリプトで画面中央に配置する方法を知りたいです。
ご教示お願いします。

試したこと

シーンにUI Textを配置し、UI Textにアタッチしたスクリプトで、それぞれ下記を試してみました。

・試したこと1

C#

1 void Start() 2 { 3 this.transform.localPosition = new Vector2(0.5f, 0.5f); 4 }

 localPositionの基準位置は、ピボットによって設定されると認識しています。
この方法だと、Textのピボットは(0.5, 0.5)に設定しなければならないし、
Textの全ての親オブジェクトのピボットも全て(0.5, 0.5)に設定しておかなければならないので、少し神経を使うかなと思いました。

・試したこと2

C#

1 //キャンバスのRectTransform。 2 [SerializeField] 3 RectTransform canvasRect; 4 5 void Start() 6 { 7 this.transform.position = new Vector2(canvasRect.sizeDelta.x/2, canvasRect.sizeDelta.y/2); 8 }

この方法でやると、なぜかUI Textのテキストがゲーム画面上で薄く表示されているように見えました。
あと、SerializeFieldにインスペクタでキャンバスのRectTransformをセットしているはずなのに、下記警告文が出ます。

Assets\UISample.cs(10,19): warning CS0649: Field 'UISample.canvasRect' is never assigned to, and will always have its default value null

・試したこと3

C#

1 void Start() 2 { 3 this.transform.position = new Vector2(Screen.width/2, Screen.height/2); 4 }

問題なさそうには見えましたが、何に影響されるか理解できていないです。

試したこと1~3において、どちらにしろ、UI Text自体のピボットは(0.5, 0.5)に設定しておかないとずれてしまうことがわかりました。
localPositionだけでなく、positionもピボットの位置によって、基準位置が設定されているということでしょうか?
また、UI Textにアタッチしているスクリプトにおけるthis.transformは、UI TextのRectTransformを参照できていることでしょうか?
リファレンスを見ましたが、transformはゲームオブジェクトにアタッチしているトランスフォームと書かれていて、これがRectTransformを指しているかどうかわかりませんでした。

上記調べていくうちに新たな疑問が出てきました。詳細は追記質問に書きました。

試したこと以外にも、何かおすすめの位置設定方法があれば教えていただきたいです。

追記質問

this.transformはRectTransformを本当に取得できているのかどうかわかりません。
RectTransformを取得できているはずなのに、pivotを取得しようとするとエラーになってしまうのは何故なのでしょうか?

C#

1 [SerializeField] 2 RectTransform rectTransform; 3 4 void Start() 5 { 6 Debug.Log(this.transform); // Text (UnityEngine.RectTransform) 7 Debug.Log(this.rectTransform); // Text (UnityEngine.RectTransform) 8 Debug.Log(this.transform == this.rectTransform); // True 9 Debug.Log(this.transform.pivot); // ※ エラー。 10 Debug.Log(this.rectTransform.pivot); // (0.5, 0.5); 11 }

エラーメッセージ。

Assets\UISample.cs(21,34): error CS1061: 'Transform' does not contain a definition for 'pivot' and no accessible extension method 'pivot' accepting a first argument of type 'Transform' could be found (are you missing a using directive or an assembly reference?)

追記②

・Screenで設定した場合。

C#

1 this.transform.position = new Vector2(Screen.width/2, Screen.height/2);

「Sample」の文字が濃い。
イメージ説明

・TransformPointで設定した場合。

C#

1 this.transform.position = this.transform.root.TransformPoint(Vector2.zero);

「Sample」の文字が薄い、もしくは、ぼやけている。
イメージ説明

両者の違いは上記コードだけです。他の設定は同じままです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

SerializeFieldについて

SerializeFieldの警告はUnityではなくVisualStudio単体の警告であり、
Unityから観る分にはさほど懸念はないという見方が多いようです。

transform.pivotについて

C#

1rectTransform = transform.GetComponent<RectTransform>(); 2or 3rectTransform = this.transform as RectTransform;

TransformとRectTransformは似ているようで違いますので、正確に型を取得してください。

投稿2020/02/11 00:12

cider0318

総合スコア135

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/02/11 05:36

ご回答ありがとうございます。 positionに関してはどうですか? this.transformで設定するpositionと、rectTransformで設定するpositionは同じですか?
cider0318

2020/02/11 06:20

同じフィールドです。 transformの上にRectTransformが被さっているようなもので、 どちらを経由したからといって結果は変わりません。 RectTransformにはanchoredPositionという、アンカー基点で座標を指定できるフィールドもあり、transform.positionに代入するよりも直感的かもしれません。 余談ですが、例えばあるUIの、ImageなどのコンポーネントをRemoveした後に、 RectTransformコンポーネントもRemoveすることができます。 するとこれが剥がれるような形でTransformコンポーネントが出現します。 このとき、RectTransformのインスペクタに表示されていた座標が3D空間ではどこを指していたのかが明確になります。 また、ヒエラルキーにメニューから配置するUI要素ですが、 デフォルトでアンカーが(0.5,0.5)になっていることがややこしく感じる原因かもしれません。 アンカーを(0,0)にすると、インスペクタの座標が、transform.positionに代入した値と一致します。
退会済みユーザー

退会済みユーザー

2020/02/11 09:15

ご回答ありがとうございます。 試してみたのですが、UIのインスペクタのRect TransformのPOSX, POSY, POSZに表示される値は、 そのUIのrectTransform.anchoredPositionで設定された値ということでしょうか? そして、このrectTransform.anchoredPositionの基準位置は、 AnchorsのMinとMaxと親のUI要素によって設定されるということでしょうか? また、下記のサイトの説明なども見つけたのですが、 http://karanokan.info/2019/02/03/post-2213/ なるべく、他の設定値に依存せずに(影響されなく)、UIを画面の中心に配置したい場合、 anchoredPositionはアンカーの位置に依存するので、 this.transform.position = new Vector2(Screen.width/2, Screen.height/2); が最も他の設定に影響されなく、中央に配置できるかと思ったのですが、いかがでしょうか? 上記コードの場合、条件としてUIのpivotさえ(0.5,0.5)に設定してあれば、中央に配置されますか? (親のUIの影響なども受けないはずなので)。 もしくは、上記コードで、UIのpivotを(0.5,0.5)に設定する条件以外にも、 画面中央に配置するのに、Canvas Scalerとか、他に何か影響を及ぼすものはありますか?
cider0318

2020/02/12 13:38

pivotが0.5固定という条件であれば、キャンバスのpivotがデフォルトで0.5とされているため、仰せられたコードは正しいです。 transform.position = new Vector2(Screen.width/2, Screen.height/2); ただし、CanvasのRender ModeをScreen Space CameraやWorld Spaceに変えた場合は影響を及ぼします。World Spaceはそもそも座標系が変わるために本題から外しますが、Screen Space Cameraを利用する設計であれば、スクリーンのサイズではなくキャンバスの座標から計算すべきです。 transform.position = transform.root.TransformPoint(Vector2.zero); Canvas Scalerはキャンバス全体をスケーリングするものですので、中央に配置した後に作用させれば影響が起こり得ますが、作用させた後でしたら影響は無いと言えます。このあたりは設計次第です。
退会済みユーザー

退会済みユーザー

2020/02/15 15:35 編集

ご回答ありがとうございます。 忙しくてコメントが遅くなりました、申し訳ございません。 なるほど、 this.transform.position = new Vector2(Screen.width/2, Screen.height/2); は、Screen Space – Overlayでのみ有効ということで、 this.transform.position = this.transform.root.TransformPoint(Vector2.zero); ならば、Screen Space – CameraとScreen Space – Overlayのどちらでも有効ということですか? であれば、TransformPointで設定する方が、2つのScreen Spaceモードで使えて汎用的なので、こちらで覚えようかなと思いました。 ただ、質問の追記②に追記したのですが、 上記2つのコードでScreen Space – Overlayでそれぞれ設定した場合、 TransformPointで設定したUI Textがぼやけてしまう(?)、もしくは色が薄く表示されてしまうのですが、 この不具合はなぜかおわかりになりますか? 本当にこの1行だけしか変更していなく、他の設定は変えていないので不思議です。 Canvas Scalerは、Canvas Scalerの設定をした後に、中央に配置するのであれば影響は無いということで理解しました。ありがとうございます。
退会済みユーザー

退会済みユーザー

2020/02/29 18:51

不具合に関しては別件のような気がしたので、こちらの質問は閉じますね。 ご教示いただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問