광선을 쏘다?
레이저를 쏴서 그 레이저랑 부딪히는 물체가 있는지 판단하는 기술
void Update()
{
//레이캐스트 눈에 보이게
Debug.DrawRay(transform.position, Vector3.forward, Color.red);
//플레이어위치, 단방향으로 쏘기
if (Physics.Raycast(transform.position, Vector3.forward);
{
Debug.Log($"Raycast !");
}
}
바닥에서 나가는 이유는 유니티짱의 기준좌표가 발바닥 기준이라서
Vector3.forward(0,0,1) 이라서 짧게 나감
void Update()
{
//레이캐스트 눈에 보이게
Debug.DrawRay(transform.position + Vector3.up, Vector3.forward * 10, Color.red);
//플레이어위치, 단방향으로 쏘기, 최대 위치
if (Physics.Raycast(transform.position + Vector3.up, Vector3.forward, 10))
{
Debug.Log($"Raycast !");
}
}
유니티짱이 움직일때마다 레이캐스팅을 변하게 하고싶다
void Update()
{
//로컬에서 월드로 변환
Vector3 look = transform.TransformDirection(Vector3.forward);
//레이캐스트 눈에 보이게
Debug.DrawRay(transform.position + Vector3.up, look * 10, Color.red);
RaycastHit hit;
//플레이어위치, 단방향으로 쏘기, 최대 위치
if (Physics.Raycast(transform.position + Vector3.up, look, out hit, 10))
{
Debug.Log($"Raycast {hit.collider.gameObject.name}");
}
}
Vector3.up을 더해준 이유는 지금 발바닥에서 나가서 위로 더 올리려고
기존의 레이캐스팅은 앞에 있는것만 확인한다
여러개 레이캐스팅할려면 이걸 쓴다
void Update()
{
//로컬에서 월드로 변환
Vector3 look = transform.TransformDirection(Vector3.forward);
//레이캐스트 눈에 보이게
Debug.DrawRay(transform.position + Vector3.up, look * 10, Color.red);
RaycastHit[] hits;
hits = Physics.RaycastAll(transform.position + Vector3.up, look, 10);
foreach(RaycastHit hit in hits)
{
Debug.Log($"Raycast {hit.collider.gameObject.name}");
}
}
local <-> world <-> Viewport <-> Screen(화면)
픽셀좌표
Debug.Log(Input.mousePosition); //Screen
컴퓨터 해상도 1920 * 1080이라고 하면 그만큼의 픽셀이 있는것처럼 표시함
스크린과 유사한데 비율로 표시해줌
Debug.Log(Camera.main.ScreenToViewportPoint(Input.mousePosition)); //Viewport
카메라는 피라미드 형태로 비춰준다
Near은 피라미드 꼭대기에서 카메라까지의 길이
Far은 피라미드 밑부분까지의 길이
3D화면에서 2D좌표로 넘어올때는 좌표 하나가 없어진다(Z : 깊이가 없어진다)
if (Input.GetMouseButtonDown(0)) //마우스 입력있을때만
{
//마우스 위치 screen 에서 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;
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}");
}
}
카메라에서 Near위치까지 가는 방향벡터가 나오게된다 = 마우스 위치 - 카메라위치
크기는 1이 아니라서 normalized로 맞춰준다(방향유지, 크기를 1로)
위의 코드를 더 간단히 표현
void Update()
{
// Local <-> World <-> Viewport <-> Screen(화면)
if (Input.GetMouseButtonDown(0)) //마우스 입력있을때만
{
Ray ray = Camera.main.ScreenPointToRay( Input.mousePosition );
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}");
}
}
}
어디에 사용할까?
디아블로같은 쿼터뷰 게임 이동 구현 할때?
성능이 무겁기 때문에 잘 사용해야한다.
충돌을 구현할때 충돌전용 메쉬를 하나 더 만들어서 안보이는 상태로 중복배치해서 그 Collider를 사용해서 연산한다 -> 이 방법도 부하가 심하다고 한다
연산하고 싶은 애들만 raycasting하기
총 레이어는 32개 비트 플래그(바이트의 개별 비트)를 사용해서 표현한다
중요하다
void Update()
{
// Local <-> World <-> Viewport <-> Screen(화면)
if (Input.GetMouseButtonDown(0)) //마우스 입력있을때만
{
Ray ray = Camera.main.ScreenPointToRay( Input.mousePosition );
int mask = (1 << 6) | (1 << 7); //Monster + Wall
Debug.DrawRay(Camera.main.transform.position, ray.direction * 100.0f, Color.red, 1.0f);
RaycastHit hit;
//Monster만 걸리는 raycasting
if (Physics.Raycast(ray, out hit, 100.0f, mask))
{
Debug.Log($"RayCast Camera @ {hit.collider.gameObject.name}");
}
}
}
Cube를 Monster로 바닥을 Wall Layer로 설정하고 실행
Layer로 등록된 큐브와 바닥만 찍히고 유니티짱을 찍으면 지나가서 바닥을 찍게된다
int mask = (1 << 6) | (1 << 7); //Monster + Wall
부분을 아래와 같이 표시도 가능하다
LayerMask mask = LayerMask.GetMask("Monster") | LayerMask.GetMask("Wall");
태그를 사용해서도 물체 구분 가능
태그와 레이어의 차이는 비트연산?
Tag는 비트연산이 없다