====== 073 タッチしたSpriteを取得する ======
* 2014/07/10 加筆修正
===== 概要 =====
タッチしたSpriteを取得するには当たり判定用のコライダーを追加する必要があります。
タッチした座標はInput.mousePositionで取得できますが、この座標はスクリーン座標になっていて、
そのままでは使えないのでScreenToWorldPointを使ってワールド座標に変換して使います。
==== Inspectorの設定 ====
当たり判定を行いたいゲームオブジェクトにBox Collider 2Dコンポーネントを追加しておきます。
{{:wiki:unity:tips:unity_box_colinspe.png?200|}}
==== ソースコード ====
if( Input.GetMouseButtonDown(0) )
{
Vector2 point = Camera.main.ScreenToWorldPoint( Input.mousePosition );
Collider2D collition2d = Physics2D.OverlapPoint( point );
if( collition2d )
{
Debug.Log( collition2d.gameObject.name.ToString() );
}
}
これを適当なGameObject(MainCameraなど)にアタッチするとタッチしたGameObjectの名前のログが出力されます。
==== コライダーが重なってうまく判定できない場合 ====
ゲームオブジェクトが重なると上手く判定出来ないことがあります。
{{:wiki:unity:tips:unity_touch_sprite_layer_view.png?200|}}
例えばこんな風にSpriteが重なっていて、どちらにもコライダーが追加されている時、
緑のスプライトを取得しようとしても、オレンジのスプライトを取得してしまう場合があります。
これを回避するには、Spriteのレイヤーを分ける必要があります。
{{:wiki:unity:tips:unity_touch_sprite_layer.png?200|}}
SpriteのInspector項目にLayerがあります。
これが初期値ではDefaultになっているので緑のSpriteをUIに変更します。
==== 特定レイヤーのオブジェクトのみ判定する ====
実はPhysics2D.OverlapPointにはMaskLayerを指定することが可能です。
指定すると特定のレイヤーのみを判定できたりします。先ほどUIに変更したレイヤーのみ判定してみます。
if( Input.GetMouseButtonDown(0) )
{
int enablelayer = 1 << LayerMask.NameToLayer("UI");
Vector2 point = Camera.main.ScreenToWorldPoint( Input.mousePosition );
Collider2D collition2d = Physics2D.OverlapPoint( point, enablelayer );
if( collition2d )
{
Debug.Log( collition2d.gameObject.name.ToString() );
}
}
LayerMask.NameToLayer() で取得したレイヤー番号はビットで判定するのがルールなので、1 << でシフトしています。
==== 特定レイヤーのオブジェクトのみ無視する ====
int disablelayer = ~(1 << LayerMask.NameToLayer("UI"));
〜チルダでNOT(否定)していることに注目。
==== Z値でオブジェクトを絞る ====
Vector3 point = Input.mousePosition;
int enablelayer = 1 << LayerMask.NameToLayer("UI");
float minDepth = point.z + 1.0f;
Collider2D collition2d = Physics2D.OverlapPoint(new Vector2(point.x, point.y), enablelayer, minDepth );
minDepth,maxDepthパラメータでZ軸にもとづいてオブジェクトをフィルタリングすることができる。