광선을 쏴서 충돌 되는 물체가 있는지 없는지를 검사
Raycast와 관련있는 함수들
1. Draw ray
public static void DrawRay(Vector3 start, Vector3 dir, Color color = Color.white, float duration = 0.0f, bool depthTest = true);
파라미터
start : ray 시작 지점
dir : ray 방향
color : ray 색깔
duration : ray 길이
반환
Draws a line from start to start _ dir in world coordinates
ex)
Debug.DrawRay(transform.position, Vector3.forward, Color.red);
ex)
Debug(transform.position + Vector3.up, Vector3.forward*10, Color.red);
2. Physsics.Raycast
public static bool Raycast (Vector3 origin, Vector3 direction, float maxDistance= Mathf.Infinity, int layerMask= DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction= QueryTriggerInteraction.UseGlobal);
파라미터
origin : ray 위치
direction : ray 방향
maxDistance : ray 최대 길이
int lyaerMask : 레이어 번호
반환
bool True if the ray intersects with a Collider, otherwise false.
ex)
Raycasthit hit; // 레이캐스트에 닿았을때 hit에 저장
Physics.Raycast( gameObject.transform.position, gameObject.transform.forward, out hit, 10);
if(hit.collider.name == "Cube")
3. RaycastHit[] hits;
위 처럼 Raycasthit hit 에는 하나만 충돌되기 때문에 충돌되는 모든 오브젝트를 입력시키고 하면 RaycastAll 함수를 써야한다.
void Update()
{
Vector3 look = transform.TransformDirection(Vector3.forward); // local에서 world로 변환
Debug.DrawRay(transform.position + Vector3.up, look * 10, Color.red);
RaycastHit[] hits;
hits = Physics.RaycastAll(transform.position, look , 10);
foreach(RaycastHit hit in hits)
{
Debug.Log($"Raycast !{hit.collider.gameObject.name}");
}
}
2. 좌표계
Local <-> World <-> [ViewPort <-> Screen(화면)]
Local : gameObject의 자체 좌표 공간World : 게임 세계 전체의 좌표 공간이다. 게임 오브젝트의 world position은 게임 세계의 원점에 해당 오브젝트까지의 거리이다.Viewport Space : 카메라 시점에서 볼 수 있는 화면의 상대적인 좌표 공간이다.Screen : 실제 화면의 필셀 좌표이다.
01 Screen 좌표 = 현재 마우스 좌표를 픽셀 좌표
Debug.Log(Input.mousePosition);
2D 좌표이므로 Z는 항상 0이 나온다.
게임 화면의 해상도가 100 x 100 이면 오른쪽 끝 상단이 (100,100,0) 으로 나온다.
02 ViewPort
Debug.Log(Camera.main.ScreenToViewportPoint(Input.mousePosition));
화면 비율 0~1 사이로 표시 (0,0,0) ~ (1,1,0)
3. 게임 화면에 마우스를 클릭하면 그 위치를 월드 좌표계로 변환하기
01 마우스 커서의 Screen 좌표를 구하고 World 좌표로 바꾸기
public Vector3 ScreenToWorldPoint(Vector3 position);
파라미터
position : A screen space position (often mouse x, y), plus a z position for depth (for example, a camera clipping plane).
Vector3 mousePos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y,Camera.main.nearClipPlane));
Z축에서는 world좌표로 향하는 방향을 구해서 그 방향으로 Raycast를 쏘는 것이므로 값이 중요하지 않다.
02 카메라의 현재 위치로부터 01에서 구한 마우스 위치와 World 좌표로 향하는 방향을 구하기
Vector3 mousePos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y,Camera.main.nearClipPlane));
Vector3 dir = mousePos - Camera.main.transform.position;
dir = dir.normalized;
dir는 마우스 위치에서 카메라의 위치를 빼므로 near에 해당하는 방향벡터이다.
03 dir 방향으로 Raycast 를 쏘면 마우스가 클릭했던 그 오브젝트와 충돌
Debug.DrawRay(Camera.main.transform.position, dir * 100.0F, Color.red, 1.0f);
RaycastHit hit;
if (Physics.Raycast(Camera.main.transform.position, dir, out hit, 100.0F))
{
Debug.Log($"Raycast Camera @ {hit.collider.gameObject.name}");
}
Physics.Raycast
메인 카메라의 현재 위치로부터 / dir 방향으로 메인 카메라의 현재 위치로부터 마우스 클릭한 화면상의 좌표를 월드 좌표로 변환한 곳을 향하는 방향 / 100.0f 길이의 광선을 쏘고 / 충돌한 오브젝트가 있다면 그 정보를 hit에 담은 후 true를 리턴한다.
4. 마우스 버튼 입력 처리
01 마우스 왼쪽 버튼을 눌렀을 때의 처리
if(Input.GetMouseButtonDown(0))
02 마우스 왼쪽 버튼을 누르고 있는 도중의 처리
if(Input.GetMouseButton(0))
03 마우스 왼쪽 버튼을 뗄 때의 처리
if(Input.GetMouseButtonUp(0))
0 : 마우스 왼쪽 버튼
1 : 마우스 오른쪽 버튼
2 : 마우스 휠 버튼
4. ScreenPointToRay
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
호출한 카메라 위치로부터 픽셀 단위의 화면상 좌표의 실제 월드 좌표로 향하는 방향의 Ray(광선)을 리턴한다.
위와 같은 과정이다.
Vector3 mousePos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.nearClipPlane));
Vector3 dir = mousePos - Camera.main.transform.position; // 마우스 위치에서 카메라 포지션을 뺀거니까 카메라위치에서 near향하는 방향벡터
dir = dir.normalized;
Debug.DrawRay(Camera.main.transform.position, ray.direction * 100.0F, Color.red, 1.0f);
RaycastHit hit;
if(Physics.Raycast(ray, out hit, 100.0f))
{
Debug.Log($"Raycast Camera @ {hit.collider.gameObject.name}");
}
Raycast에 시작 위치와 방향을 넘기는 대신 광선 자체의 ray를 넘겨준다.
5. LayerMask
오브젝트에게 해당 Layer를 붙이면 그 Layer에 해당하는 오브젝트들을 대상으로만 Raycastring 할 수 있다.
LayerMask mask = LayerMask.GetMask("Monster")| LayerMask.GetMask("Wall");
6. Tag
옷에 태그를 붙이는 것 처럼 추가적인 정보를 남기는 것
GameObject.FindGameObjectsWithTag("Monster");
Debug.Log($"Raycast Camera @ {hit.collider.gameObject.tag}");
참고 : 본 내용은 MMORPG PART3 강의를 수강하여 작성하였습니다.
https://www.inflearn.com/course/mmorpg-%EC%9C%A0%EB%8B%88%ED%8B%B0/dashboard
'유니티 공부 > Unity' 카테고리의 다른 글
Unity - UI 자동화(Bind, Get) (0) | 2023.02.21 |
---|---|
Unity - 플레이어가 이동할때 카메라가 플레이어 쳐다보게 하기 (0) | 2023.02.21 |
Unity - UI 기초, UI Rect Transform, Anchor Presets 설명 (0) | 2023.02.15 |
Unity - KeyFrame Animation(Key, Dope Sheet, Curves),Animation Event (0) | 2023.02.15 |
Unity - Animation State 패턴, State Machine (0) | 2023.02.14 |
댓글