2017. 1. 27. 16:00

유니티에서 클릭했을 때 맨 위에 있는 오브젝트를 찾는 대표적인 방법이 레이캐스트(Raycast)를 이용한 방법입니다.

그런데 2D 스프라이트(Sprite) 오즈젝트(object)를 사용하면 레이캐스트가 맞질 않습니다.

 

스프라이트의 기본 설정에 충돌체(Collider)가 없기 때문입니다.

 

1. 증상 확인하기

2D프로젝트를 생성하고 '2D Object > Sprite'와 '3D Object > Plane2'를 추가하고 두 오브젝트를 어느 정도 겹쳐 둡니다.

상태를 확인할 텍스트오브젝트도 하나 올려줍니다.

 

 

 

스크립트를 생성하고 아래 코드를 넣습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
public class CRaycast : MonoBehaviour
{
 
    /// <summary>
    /// 3d 텍스트 오브젝트
    /// </summary>
    TextMesh m_textMeshDisplayText;
 
 
    // Use this for initialization
    void Start ()
    {
        //텍스트 오브젝트를 찾는다.
        this.m_textMeshDisplayText
            = (GameObject.Find("DisplayText"as GameObject).GetComponent<TextMesh>();
    }
 
    // Update is called once per frame
    void Update ()
    {
        if (true == Input.GetMouseButton(0))
        {//마우스가 내려갔다!
            GameObject aaaa = this.GetClickedObject();
            this.m_textMeshDisplayText.text = string.Format("'{0}'가 클릭됨", aaaa.name);
        }
        else
        {
            this.m_textMeshDisplayText.text = "클릭된게 없다!";
        }
    }
 
    /// <summary>
    /// 마우스가 내려간 오브젝트를 가지고 옵니다.
    /// </summary>
    /// <returns>선택된 오브젝트</returns>
    private GameObject GetClickedObject()
    {
        //충돌이 감지된 영역
        RaycastHit hit;
        //찾은 오브젝트
        GameObject target = null;
 
        //마우스 포이트 근처 좌표를 만든다.
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
 
        //마우스 근처에 오브젝트가 있는지 확인
        if (true == (Physics.Raycast(ray.origin, ray.direction * 10out hit)))
        {//있다!
         //있으면 오브젝트를 저장한다.
            target = hit.collider.gameObject;
        }
 
        return target;
    }
}
cs

 

 

메인 카메라에 위 스크립트를 적용하고 오브젝트를 클릭해 봅시다.

 

 

 

스프라이트는 클릭이 되지 않는 걸 알 수 있습니다.

 

 

2. 해결 방법

이건 2D 스프라이트의 디폴트 속성에 충돌체가 들어있지 않기 때문에 발생하는 문제입니다.

 

 

 

2-1. 3D 충돌체 추가하기

스프라이트에 충돌체를 추가해봅시다.

 

 

Add Component > Physics > Box Collider

 

 

 

충돌체가 추가되면 스프라이트에 녹색 보더가 생기는 걸 확인할 수 있습니다.

 

 

 

이 상태로 태스트를 해봅시다.

 

 

잘 동작합니다.

3D 충돌체인경우 3D오브젝트와 같은 동작을 합니다.

 

2-2. 2D 충돌체 추가하기

2D 충돌체를 넣어도 됩니다.

 

Add Component > Physics 2D > Box Collider 2D

 

그런데 2D 충돌체를 넣으면 동작하지 않습니다.

2D 충돌체는 레이캐스트를 검사하지 않기 때문입니다.

레이캐스트로 처리하고 싶다면 3D 충돌체를 넣어야 합니다.

 

2D 충돌체를 꼭 쓰고 싶다면 게임오브젝트의 이벤트를 이용해야 합니다.

마우스 다운(OnMouseDown) 이벤트를 추가하여 처리해 봅시다.

 

새 스크립트를 생성하고 아래 코드를 넣습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class CMouse : MonoBehaviour
{
    /// <summary>
    /// 3d 텍스트 오브젝트
    /// </summary>
    TextMesh m_textMeshDisplayText;
 
    // Use this for initialization
    void Start ()
    {
        //텍스트 오브젝트를 찾는다.
        this.m_textMeshDisplayText
            = (GameObject.Find("DisplayText"as GameObject).GetComponent<TextMesh>();
    }
    
    // Update is called once per frame
    void Update ()
    {    
    }
 
 
    void OnMouseUp()
    {
        //this.m_textMeshDisplayText.text = "클릭된게 없다!";
    }
 
    void OnMouseDown()
    {
        this.m_textMeshDisplayText.text = string.Format("'{0}'가 클릭됨(Mouse)"this.name);
    }
}
cs

 

 

위에서 만든 스크립트를 스프라이트에 넣고 테스트해봅시다.

 

 

 

게임오브젝트 이벤트는 잘 넘어오는 걸 확인할 수 있습니다.

 

 

마무리

아래는 테스트용 프로젝트입니다.

 

SpriteRaycast_Test.zip

 

 

결국 용도에 따라 필요한 충돌체를 추가하면 됩니다.

그래도 모르겠으면 3D 충돌체를 넣는게 좋을듯 하네요.