본문 바로가기
개발/Unity

유니티 - UI가 있는 경우 Raycast 제한하기 (Detecting when a touch is over UI element)

by 피로물든딸기 2022. 7. 28.
반응형

Unity 전체 링크

 

Raycast는 오브젝트를 찾을 때 유용하다.

그런데 UI가 가리고 있음에도 Raycast가 동작한다면 기능이 어색할 수 있다.

따라서 UI를 감지한 경우에는 Racast를 제한하도록 해보자.


Ctrl + Shift + N으로 빈 오브젝트를 만든 후에 CameraRaycast.cs를 추가하자.

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

public class CameraRaycast : MonoBehaviour
{
    RaycastHit hit;

    void Update()
    {
        if (Input.GetMouseButton(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            Debug.DrawRay(ray.origin, ray.direction * 1000, Color.blue);

            if(Physics.Raycast(ray, out hit))
            {
                Debug.Log(hit.collider.name);
            }
        }
    }
}

 

그러면 마우스 버튼을 누르고 있으면 Scene에 Ray를 그리게 되고, 레이캐스트로 평면을 검출하게 된다.

 

이제 Canvas를 추가하여 가운데에 버튼을 크게 만들어보자.

 

버튼이 눌러진 상태에서 여전히 평면을 검출하고 있으며, 파란색으로 Ray를 그리고 있음을 알 수 있다.


이제 Raycast가 Button(UI)를 통과하지 않도록 하자.

IsPointerOverGameObject() 메서드를 사용하면 현재 Raycast가 UI를 향하고 있는지를 알 수 있다.

 

Raycast가 작동하는 경우에만 DrawRay를 하도록 코드를 수정하자.

UnityEngine.EventSystems;가 필요하다.

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

public class CameraRaycast : MonoBehaviour
{
    RaycastHit hit;

    void Update()
    {
        if (Input.GetMouseButton(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
  
            if(Physics.Raycast(ray, out hit))
            {
                if (EventSystem.current.IsPointerOverGameObject() == false)
                {
                    Debug.DrawRay(ray.origin, ray.direction * 1000, Color.blue);
                }
            }
        }
    }
}

 

IsPointerOverGameObject()가 false라면 현재 마우스가 UI를 가르키지 않다는 뜻이다.

 

실제 버튼에 마우스가 다가갈 때 ray가 사라지는 것을 알 수 있다.


IsPointerOverGameObject를 보면 pointerId를 파라미터로 받는 것을 알 수 있다.

 

실제 위 코드는 안드로이드, iOS 빌드에서는 작동하지 않는다.

 

pointerId는 에디터 또는 WINDOW에서 -1이다.

또한 pointerId를 지정하지 않은 경우에도 -1로 가정한다.

모바일 환경에서 pointerId는 0이다.

 

따라서 모바일 환경에서도 동작하게 하기 위해서는 아래와 같이 코드를 수정해야 한다.

#if UNITY_EDITOR
    if (EventSystem.current.IsPointerOverGameObject() == false)
    //if (EventSystem.current.IsPointerOverGameObject(-1) == false)
#elif UNITY_ANDROID // or iOS 
    if (EventSystem.current.IsPointerOverGameObject(0) == false)
#endif

 

Unity Plus:

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Unity Pro:

 

Unity Pro

The complete solutions for professionals to create and operate.

unity.com

 

Unity 프리미엄 학습:

 

Unity Learn

Advance your Unity skills with live sessions and over 750 hours of on-demand learning content designed for creators at every skill level.

unity.com

반응형

댓글