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

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

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

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

Q&A

解決済

2回答

14546閲覧

Spriteの左上の位置座標の取得方法。

退会済みユーザー

退会済みユーザー

総合スコア0

Unity

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

0グッド

0クリップ

投稿2016/11/06 12:38

編集2016/11/09 12:12

###前提・実現したいこと

Spriteはデフォルトで起点が中央に設定されていますが、
このSpriteの左上の位置座標を取得できるプロパティはありますか?

###試したこと

①マニュアルを見たが、それらしきプロパティが見つからない。 ②Spriteの起点から、Spriteの幅や高さの半分の値を引いたりすれば、左上の位置座標は取得できるかもしれない。

②の方法で左上の座標の取得が実現できそうではありますが、これしか方法はないのでしょうか?
左上の位置のプロパティが存在するのならば、それを使いたいと思っています。

Spriteの左上の位置座標の取得方法のご教授をお願いいたします。

※Spriteの起点はずらさずに中央に配置したままで扱いたいです。

###補足情報(言語/FW/ツール等のバージョンなど)
Unity 3Dで扱っています。(2Dを扱ったことはないですが、たぶん同じと思っています。)

###追記①
下記コードを試してみましたが、ワールド空間の座標は取得できませんでした。

C#

1ゲームオブジェクト.GetComponent<SpriteRenderer> ().sprite.rect.xMin; 2ゲームオブジェクト.GetComponent<SpriteRenderer> ().sprite.rect.yMin;

###追記②

C#

1 //GameObject cube2 = GameObject.Find ("Cube/cube2"); 2 GameObject cube2 = GameObject.FindGameObjectWithTag ("Cube2"); 3 4 Matrix4x4 _m = cube2.transform.localToWorldMatrix; 5 //cube2自身の座標の相対座標を指定。 6 //(親オブジェクトの相対座標ではない(cube2.transform.localPositionを設定するものではない)。 7 Vector3 _vec = new Vector3(0, 0, 0); 8 Vector3 _pos = _m.MultiplyPoint3x4(_vec); 9 10 //MultiplyPoint3x4()の引数に(0, 0, 0)を指定していた場合は、 11 //cube2の現在の位置のワールド座標。 12 Debug.Log (_pos); 13 //引数に(0, 0, 0)を指定していた場合、上記は下記と同じ。 14 Debug.Log (cube2.transform.position);

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

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

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

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

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

guest

回答2

0

ベストアンサー

変数_posSpriteの左上のワールド座標が代入されます。
(もしかするともっとスマートな方法があるかもしれません。)

分かりやすくMonoBehaviourを継承したクラスのStart関数内で実行するようにしていますが、
実際に利用する場合は結果をVector3型を返す関数として定義するべきですね。

また、頻繁に利用する場合は、SpriteRendererを毎回GetComponentせずに変数にキャッシュしておくとよいでしょう。

C#

1using UnityEngine; 2 3public class GetSpriteTopLeftWorldPosition : MonoBehaviour { 4 void Start() { 5 var _spriteRenderer = GetComponent<SpriteRenderer>(); 6 var _m = _spriteRenderer.localToWorldMatrix; 7 var _sprite = _spriteRenderer.sprite; 8 var _halfX = _sprite.bounds.extents.x; 9 var _halfY = _sprite.bounds.extents.y; 10 var _vec = new Vector3(-_halfX, _halfY, 0f); 11 var _pos = _m.MultiplyPoint3x4(_vec); 12 Debug.Log("1 : " + _pos); 13 Debug.Log("2 : " + GetSpriteTopLeftPosition()); 14 } 15 16 // 別解 17 Vector3 GetSpriteTopLeftPosition(){ 18 var _spriteRenderer = GetComponent<SpriteRenderer>(); 19 var _sprite = _spriteRenderer.sprite; 20 var _halfX = _sprite.bounds.extents.x; 21 var _halfY = _sprite.bounds.extents.y; 22 var _vec = new Vector3(-_halfX, _halfY, 0f); 23 var _pos = _spriteRenderer.transform.TransformPoint(_vec); 24 return _pos; 25 } 26}

スクリプトリファレンス : Bounds
スクリプトリファレンス : Transform.TransformPoint

投稿2016/11/08 10:16

編集2016/11/09 14:08
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2016/11/08 15:00

ご回答ありがとうございます。 var _m = _spriteRenderer.localToWorldMatrix; var _pos = _m.MultiplyPoint3x4(_vec); に関して質問させてください。 var (Aのワールド座標の行列オブジェクト) = (ローカル座標のオブジェクトA).localToWorldMatrix; var (Aのワールド座標) = (Aのワールド座標の行列オブジェクト).MultiplyPoint3x4(ワールド座標に変換したいAのローカル座標); というような解釈で大丈夫ですか?
退会済みユーザー

退会済みユーザー

2016/11/08 16:03

大体そのような感じです。
退会済みユーザー

退会済みユーザー

2016/11/09 12:13

すみません、MultiplyPoint3x4()に関してもう少しご教授いただけますか? Cubeの子オブジェクトにcube2を作成して、 cube2のワールド座標を求めるコードを作成してみました。 追記②にそのコードを書いたのですが、 MultiplyPoint3x4の引数には、cube2の親オブジェクトの相対座標ではなく、 cube2自身の座標の相対座標を指定することで、ワールド座標が求められるということで 合っていますか?
退会済みユーザー

退会済みユーザー

2016/11/09 13:52

間違いはありませんが、cube2のワールド座標を取得するだけなら cube2.transform.positionだけで可能です。
退会済みユーザー

退会済みユーザー

2016/11/09 13:59

ご回答ありがとうございます。 とても勉強になりました。 最後までご教授くださりありがとうございました。
退会済みユーザー

退会済みユーザー

2016/11/09 14:12

していることはほとんど変わりませんが、別解を追記しました。
退会済みユーザー

退会済みユーザー

2016/11/09 14:21

ご回答ありがとうございます。 TransformPointという関数もあるのですね。 勉強になりました。 ご丁寧にご教授くださりありがとうございます。
guest

0

中心位置をずらしたくないなら②の方法が簡単で扱いやすいです。私も大抵はそのやり方で済ませます。
どうしてもUnityの機能だけで完結したいなら、Spriteの中のRectプロパティにならその情報があるかもしれません。
(取り出した事がないのでお望みのものが入っているかは保証できません)
Rect

多分このなかのxMinとyMinが左上に相当するはずです。

投稿2016/11/07 01:50

ishi9

総合スコア1294

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

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

退会済みユーザー

退会済みユーザー

2016/11/07 12:30

ご回答ありがとうございます。 ご教授いただいた方法を試してみましたが (詳細は追記に書きましたが、そのコードで合っていますか?)、 ワールド空間の座標は取得できませんでした。
ishi9

2016/11/08 01:21

あぁ、ローカル上での相対位置が取れるのですか。すいません、私の勘違いでした。本来のワールド位置からxMin,yMinを引くとかしないと左上にならなさそうですね。でもそれなら素直にwidthとか使った方が早いですよね。 そうなるとすいません、ちょっとわかりません。 ただ、蛇足で言いますと Unityくらい手厚すぎるフレームワークならもしかしたら探せばあるかもしれませんが、 普通は自分で計算する方が一般的だと思います。 フレームワーク側で用意しない理由 ・使わない場合は無駄な計算になるので勿体無い ・その場で計算するUtil関数を用意しようにも一行で書けるからあまり意味が・・・
退会済みユーザー

退会済みユーザー

2016/11/08 09:45

ご回答ありがとうございます。 自分で計算する方が一般的なんですね。 もしかしたら、フレームワークに関してご教授いただける方がいるかもしれないので、この質問はまだ閉じないでおこうと思います。 ご教授くださりありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問