유니티에서 클릭했을 때 맨 위에 있는 오브젝트를 찾는 대표적인 방법이 레이캐스트(Raycast)를 이용한 방법입니다.
그런데 2D 스프라이트(Sprite) 오즈젝트(object)를 사용하면 레이캐스트가 맞질 않습니다.
스프라이트의 기본 설정에 충돌체(Collider)가 없기 때문입니다.
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 * 10, out hit)))
{//있다!
//있으면 오브젝트를 저장한다.
target = hit.collider.gameObject;
}
return target;
}
} |
cs |
메인 카메라에 위 스크립트를 적용하고 오브젝트를 클릭해 봅시다.
스프라이트는 클릭이 되지 않는 걸 알 수 있습니다.
이건 2D 스프라이트의 디폴트 속성에 충돌체가 들어있지 않기 때문에 발생하는 문제입니다.
스프라이트에 충돌체를 추가해봅시다.
Add Component > Physics > Box Collider
충돌체가 추가되면 스프라이트에 녹색 보더가 생기는 걸 확인할 수 있습니다.
이 상태로 태스트를 해봅시다.
잘 동작합니다.
3D 충돌체인경우 3D오브젝트와 같은 동작을 합니다.
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 |
위에서 만든 스크립트를 스프라이트에 넣고 테스트해봅시다.
게임오브젝트 이벤트는 잘 넘어오는 걸 확인할 수 있습니다.
아래는 테스트용 프로젝트입니다.
결국 용도에 따라 필요한 충돌체를 추가하면 됩니다.
그래도 모르겠으면 3D 충돌체를 넣는게 좋을듯 하네요.