• ブログTOP
  • AI・ディープラーニング
  • AR
  • VR
  • WEBサイト
  • WEBマーケティング
  • SEO
  • SNS
  • その他
  • お問い合わせ

ALAKI株式会社

COZIKEEいつまでも使えるTech情報発信ブログ

  • ブログTOP
  • AI・ディープラーニング
  • AR
  • VR
  • WEBサイト
  • WEBマーケティング
  • SEO
  • SNS
  • その他
  • お問い合わせ

【Unity】Raycastで2D要素をタップ判定する【RaycastHit2D + BoxCollider2D】

2022年11月16日

  • このエントリーをはてなブックマークに追加

こんにちは!
XRクリエイターの伊東(@ALAKIWebVRAR1)です。

※TwitterでもAR/VRの事を中心に情報発信中です。
よかったらフォローお願いします!
Follow @ALAKIWebVRAR1

今回は、Unityで2Dオブジェクトをタップ判定する方法を備忘録的にまとめていきます。
まずは、この記事を読んで何ができるようになるのかをご覧ください。

実装したいこと

先にゴールからお見せします。

ray_2d_1

シーンに配置したUI Textがマウスでドラッグした時に追従するような動きです!
シンプルなインタラクションですが、さまざまなテクニックが含まれています。

順を追って見ていきましょう。

シーンを見てみる

まずはシーンの構成を見てみます。

スクリーンショット 2022-11-15 20.15.31

カメラと、最低限のライト、キャンバスとTextMeshProで作ったテキストUIが2つというシンプルなシーンです。

ポイントは、CanvasのRenderModeが「World Space」になっているところです。

スクリーンショット 2022-11-15 20.15.45

スクリーン座標ではなく、ワールド座標系に2Dオブジェクトを配置している形になります。

その上で、画面上のタップを検知して、ワールド座標系にある2Dオブジェクトをマウスに追従させるということが今回のゴールになります。

マウスの座標を取得する

まずはマウスクリックを検知して、座標を取得するところからスタートしましょう。

適当な名前でスクリプトを用意して、テキストオブジェクトにアタッチしてください。

スクリーンショット 2022-11-15 20.49.00

今回はスクリプトの名前を「DraggableUI」としました。

そして、Update関数に、マウスクリックを判定するif文と、クリックした場所を取得してコンソールに出してみます。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DraggableUI : MonoBehaviour
{

    // Start is called before the first frame update
    void Start()
    {
    }

    // Update is called once per frame
    void Update()
    {
        /* マウスクリックを検知 */
        if (Input.GetMouseButton(0)) {

            /* クリック座標(スクリーン座標系) */
            Debug.Log(Input.mousePosition);

        }
    }
}

スクリーンショット 2022-11-15 20.54.32

マウス座標がとれました!

ただし、取得できた座標はスクリーン座標になっています。

最終的に操作するテキストオブジェクトはワールド座標になっているので、変換してあげる必要がありますね。

スクリーン座標とワールド座標の変換

クリックした場所の座標を、スクリーン座標からワールド座標に変換するために、「ScreenToWorldPoint」というカメラに備わっている関数を利用します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DraggableUI : MonoBehaviour
{

    // Start is called before the first frame update
    void Start()
    {
    }

    // Update is called once per frame
    void Update()
    {
        /* マウスクリックを検知 */
        if (Input.GetMouseButton(0)) {

            /* クリック座標(スクリーン座標系) */
            Vector3 screenPos = Input.mousePosition;

            /* クリック座標(ワールド座標系) */
            Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos);

        }
    }
}

このように、カメラを基準として、スクリーン座標をワールド座標に変換することができます。

クリック座標にオブジェクトを追従させる

ワールド座標が取れれば、その座標をオブジェクトのトランスフォームに渡してあげれば、マウスに追従する処理がかけそうです。
やってみましょう。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DraggableUI : MonoBehaviour
{

    // Start is called before the first frame update
    void Start()
    {
    }

    // Update is called once per frame
    void Update()
    {
        /* マウスクリックを検知 */
        if (Input.GetMouseButton(0)) {

            /* クリック座標(スクリーン座標系) */
            Vector3 screenPos = Input.mousePosition;
            screenPos.z = 1.0f;

            /* クリック座標(ワールド座標系) */
            Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos);

            /* オブジェクトのポジションからワールド座標系までのアニメーション */
            transform.position = Vector3.Lerp(
                    transform.position,
                    worldPos,
                    3.0f * Time.deltaTime);

        }
    }
}

ポイントが2つあります。

1つ目は、取得したスクリーン座標に奥行きを付与しているところです。
そのままではZの値が0になり、ワールド座標に変換した時に毎回同じVector3の値が返ってきてしまいます。
意図した通りの値を得るために、Zの値に任意の値を入れてから、ワールド座標への変換を行うようにします。

2つ目は、Lerp関数です。Lerp関数は、ある点からある点までの値の変化を補完して、徐々に変化するような表現を可能にします。
今回はLerp関数に3つの引数を渡しています。1つ目の引数が「変化前の値」、2つ目の引数が「変化後の値」、3つ目の引数が「補完値」です。

ここまでの内容で、スクリプトを実行してみましょう。

作成した「DraggableUI」というスクリプトを、シーンにあるテキストオブジェクトにアタッチしてから実行します。

画面収録-2022-11-15-21.06

だいぶゴールに近づいてきました!

が、マウスをドラッグした瞬間、2つのオブジェクトが一緒になって追従してしまっているので、修正していきます。

RaycastHit2Dを実装

オブジェクトの部分をドラッグした場合のみ、オブジェクトがマウスに追従するようにするには、マウスとオブジェクトが衝突していることを判定する必要があります。それを実現するのが「Raycast」と呼ばれるものです。クリックした座標位置から、奥側に向かって伸びる見えない光線を伸ばし、その光線にあたっているオブジェクトを取得するという方法です。

ソースコードは以下のようになります。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DraggableUI : MonoBehaviour
{

    // Start is called before the first frame update
    void Start()
    {
    }

    // Update is called once per frame
    void Update()
    {
        /* マウスクリックを検知 */
        if (Input.GetMouseButton(0)) {

            // タップした場所からRayを作成
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

            // Raycastを作成
            RaycastHit2D hit2d = Physics2D.Raycast((Vector2)ray.origin, (Vector2)ray.direction);

            //Rayが何かに衝突したことを検知 & 衝突した対象が自分自身かを判別
            if(hit2d && hit2d.transform.gameObject == this.gameObject) {

                /* クリック座標(スクリーン座標系) */
                Vector3 screenPos = Input.mousePosition;
                screenPos.z =  1.0f;

                /* クリック座標(ワールド座標系) */
                Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos);

                /* オブジェクトのポジションからワールド座標系までのアニメーション */
                transform.position = Vector3.Lerp(
                        transform.position,
                        worldPos,
                        3.0f * Time.deltaTime);

            }

        }
    }
}

カメラが持つ「ScreenPointToRay」というメソッドに、クリックした場所の座標を渡し、Ray(光線)を作成します。
次に、Physics2D.RaycastというメソッドでRayが当たった物を取得するためのRaycastHit2Dオブジェクトを作成します。
RaycastHit2DはRaycastを2D要素に対して扱うためのクラスになっています。

最後に、if文に2つの条件を&で渡して、ifの中にオブジェクトの座標を書き換える処理を移しました。
条件の1つ目は、RaycastHit2Dオブジェクトが存在するかどうかをみています。
条件の2つ目は、RaycastHit2Dオブジェクト検知した衝突したGameObjectが、自身のGameObjectと一致するかどうかです。

BoxCollider2Dをアタッチする

ここまででスクリプトの記述は完了しました。
しかしこのままで実行しても動作しません。
ドラッグするオブジェクト側に、Rayがぶつかるためのコンポーネントをアタッチする必要があります。
今回は2D用のRaycastHit2Dを使用しているため、「BoxCollider2D」というコンポーネントを使用します。

スクリーンショット 2022-11-16 6.25.44

アタッチできたら、「Size」の部分を実際のオブジェクトと合わせてあげる必要があります。

ここまでで全ての準備が整いました。
実行してみます!

ray_2d_1

できましたね!

最後に

今回ご紹介した基本的なRaycastの実装は、さまざまなアプリケーションで活用できるものかと思います。

弊社では、Unityをはじめさまざまな技術を活用して、これからも世の中に新しい価値をご提供し続けます。

最近では、現実のあらゆる場所からデジタルコンテンツを誰でもAR空間にドロップできる「MUGHEN」というアプリをリリースしました。ぜひインストールしていただき、現実を拡張する感覚を体験してみてください!

■MUGHEN サービス紹介サイト
https://alaki.co.jp/lp/mughen/

また、お客さまからご相談をいただき、日本各地でARを使ったワクワクするプロジェクトをリリースしてまいりました。
ARのパイオニアとして、高い技術力とビジネス提案が可能ですので、以下のサイトよりお気軽にご相談ください!

■WebAR開発 特設サイト
https://alaki.co.jp/lp/webar/

ALAKI株式会社では、「MUGHEN」をはじめとする最先端技術を使って世の中に価値を提供するため、一緒に大きな目標に挑戦する仲間を募集中です!興味のある方は、以下のリンクからご応募ください!

■ALAKI リクルートサイト
https://recruit.alaki.co.jp/

  • ツイート
  • このエントリーをはてなブックマークに追加
ALAKI ロゴ
さよなら過去のAR。
WebARがイベント集客に
革命を起こします。
特設サイトはこちら >

Tags: Unity

You may also like...

  • CLOUD FLAREとIPアドレスの関係を理解しよう

    6 10月, 2017

  • WebARはじめてみませんか?〜第3回 8th Wall WebでAndroidにも対応のマーカーレスWebARを実装する〜

    15 2月, 2019

  • twig30分クッキング-はじめてのtwigインストール編-

    1 7月, 2016

  • Next story 海外向けプレスリリース配信代行サービス7選
  • Previous story 【Luma AI】iPhoneで簡単に3DCGを生成する【フォトグラメトリ × LiDAR × 3D生成AI】

運営会社

ALAKI株式会社 ALAKI株式会社採用サイト

弊社サービス

MUGHEN ALAKI クラウド型受発注システム さよなら過去のAR。WebARがイベント集客に革命を起こします。 広報活動の課題を数字で可視化し、出願者数アップをお手伝いします クリエイティブ業務のコミュニケーションを高速化 Webの知識が無くてもWebサイトの品質をチェックできます。

カテゴリー

  • AI・ディープラーニング
  • AR
  • BtoB
  • CMS
  • Git
  • Google AdWords
  • gulp
  • Javascript
  • Laravel
  • Photoshop
  • Pug
  • pyhotn
  • Sass
  • SEO
  • SNS
  • Twitter広告
  • VR
  • Web3.0
  • WEBサイト
  • WEBマーケティング
  • YouTube
  • コーディング
  • システム開発
  • スマートフォンサイト
  • セキュリティ
  • セミナー
  • その他
  • ツール
  • デザイン
  • ベトナムレポート
  • 仕事術
  • 未分類
  • 業務効率化
  • 色

アーカイブ

  • 2023年2月
  • 2023年1月
  • 2022年12月
  • 2022年11月
  • 2022年10月
  • 2022年9月
  • 2022年2月
  • 2021年12月
  • 2021年9月
  • 2021年7月
  • 2021年6月
  • 2020年10月
  • 2020年9月
  • 2020年8月
  • 2020年6月
  • 2019年6月
  • 2019年5月
  • 2019年4月
  • 2019年3月
  • 2019年2月
  • 2019年1月
  • 2018年12月
  • 2018年11月
  • 2018年9月
  • 2018年8月
  • 2018年7月
  • 2018年6月
  • 2018年5月
  • 2018年4月
  • 2018年3月
  • 2018年2月
  • 2018年1月
  • 2017年12月
  • 2017年11月
  • 2017年10月
  • 2017年9月
  • 2017年8月
  • 2017年7月
  • 2017年6月
  • 2017年4月
  • 2017年3月
  • 2017年2月
  • 2017年1月
  • 2016年12月
  • 2016年11月
  • 2016年10月
  • 2016年9月
  • 2016年8月
  • 2016年7月
  • 2016年6月
  • 2016年5月
  • 2016年4月
  • 2016年3月
  • 2016年2月
  • 2016年1月
  • 2015年12月
  • 2015年11月
  • 2015年10月
  • 2015年9月
  • 2015年7月
  • 2015年3月
  • 2015年2月
  • 2015年1月
  • 2014年12月
  • 2014年11月
  • 2014年10月
  • 2014年9月
  • 2014年8月
  • 2014年7月
  • 2014年6月
  • 2013年10月
  • 2013年9月

Facebook

お問い合わせ

お問い合わせ

人気の記事

  • 「SwinIR」で高画質化した画像を pythonを使用して一括で元のサイズに戻す方法
  • Web制作時に高解像度の元画像がない場合にPythonで高画質化する方法
  • 『考える』が楽しくなる!考えを「広げる」・「深める」12の方法
  • macにpythonの開発環境を作ってみよう!
  • 商品・サービスを圧倒的に成長させる、シリコンバレーで注目の「プロダクト・レッド・グロース」を解説

カテゴリー

  • AI・ディープラーニング
  • AR
  • BtoB
  • CMS
  • Git
  • Google AdWords
  • gulp
  • Javascript
  • Laravel
  • Photoshop
  • Pug
  • pyhotn
  • Sass
  • SEO
  • SNS
  • Twitter広告
  • VR
  • Web3.0
  • WEBサイト
  • WEBマーケティング
  • YouTube
  • コーディング
  • システム開発
  • スマートフォンサイト
  • セキュリティ
  • セミナー
  • その他
  • ツール
  • デザイン
  • ベトナムレポート
  • 仕事術
  • 未分類
  • 業務効率化
  • 色

検索

ALAKI株式会社 © 2026. All Rights Reserved.