profile image

L o a d i n g . . .

article thumbnail image
Published 2020. 9. 8. 02:08
반응형

Trigger

docs.unity3d.com/kr/2018.4/Manual/CollidersOverview.html

 

콜라이더 - Unity 매뉴얼

콜라이더(Collider) 컴포넌트는 물리 충돌 처리를 위한 오브젝트의 형태를 정의합니다. 콜라이더는 보이지 않는 요소이므로 오브젝트의 메시와 정확히 동일한 모양일 필요는 없으며, 실제로는 게�

docs.unity3d.com

 

 

OnCollisionEnter처럼 물리적인 충돌이 일어날 경우, 물리적인 연산을 하기 위해서 굉장히 많은 부하가 일어난다.
=> is Trigger

둘 중 하나라도 is Trigger가 켜져 있으면 물리 연산을 진행하지 않고, Trigger가 발생하고 종료하게 된다.

public class TestCollision : MonoBehaviour
{
    // 1) 둘 다 Collider가 있어야 한다.
    // 2) 둘 중 하나는 isTrigger : On
    // 3) 둘 중 하나는 Rigidbody가 있어야 한다.
    private void OnTriggerEnter(Collider other)
    {
        Debug.Log($"Trigger @ {other.gameObject.name} !");
    }
}

 

 

 

Raycasting #1

광선(레이저)을 쏜다. 해당 레이저와 부딪히는 물체가 있는지 없는지를 체크한다.

void Update()
{
    // 플레이어가 바라보고 있는 로컬 forward 계산
    Vector3 look = transform.TransformDirection(Vector3.forward);
    Debug.DrawRay(transform.position + Vector3.up, look * 10.0f, Color.red);
    RaycastHit hit;

    if (Physics.Raycast(transform.position + Vector3.up, look, out hit, 10.0f))
    {
        Debug.Log($"Raycast {hit.collider.gameObject.name} !");
    }
}

 

 

Debug상에서는 두 Cube 모두 관통하는 것으로 보이나, 실제 Raycast는 플레이어와 가까운 Cube(Cube 1)와 하는 것을 확인할 수 있다.

관계없이 모두를 체크하려면 Physics.RaycastAll을 이용한다.

void Update()
{
    // 플레이어가 바라보고 있는 로컬 forward 계산
    Vector3 look = transform.TransformDirection(Vector3.forward);
    Debug.DrawRay(transform.position + Vector3.up, look * 10.0f, Color.red);
    RaycastHit hit;

    if (Physics.Raycast(transform.position + Vector3.up, look, out hit, 10.0f))
    {
        Debug.Log($"Raycast {hit.collider.gameObject.name} !");
    }

    RaycastHit[] hits;
    hits = Physics.RaycastAll(transform.position + Vector3.up, look, 10.0f);

    foreach(RaycastHit h in hits)
    {
        Debug.Log($"Raycast {h.collider.gameObject.name} !");
    }
}

 

카메라와 캐릭터 사이에 지형이 있어서 캐릭터를 비추는 시야가 막혔다고 하자.

이는 Zoom 처리를 해서 플레이어를 크게 보여 주는 식으로 처리할 수 있다. 카메라에서 캐릭터 방향으로 레이저를 쏘고, 해당 레이저에 캐릭터가 아닌 다른 물체가 닿았을 경우 화면을 확대하는 방식으로 구현하면 된다.

 

 

투영의 개념

마우스로 모니터 좌표를 찍을 때는 어떤 좌표로 레이저를 쏴야 하는가?

Local <-> World <-> Viewport <-> Screen (화면)

Debug.Log(Input.mousePosition);     //Screen, 각 픽셀에 대응, 좌측 하단이 (0, 0)
Debug.Log(Camera.main.ScreenToViewportPoint(Input.mousePosition));  // Viewport, 0~1 값을 가짐, 좌측 하단이 (0, 0), Screen과 매우 유사하나 비율에 대해 표시함

 

카메라의 절두체 => 카메라가 현재 찍고 있는 영역이다. 이 범위를 넘어가면 컬링(culling) 때문에 연산을 진행하지 않는다.

카메라 기준으로 봤을 때 가장 앞에 있는 물체가 렌더 된다. 즉, 플레이어가 작은 큐브를 완전히 가리고 있을 때 플레이어만 표시하게 된다.

또한 같은 사이즈이지만, 2D로 넘어왔을 때 멀리 있는 것이 좀 더 작게 보인다. => 2D 화면을 보면서도 원근감을 느껴 3D 화면인 것처럼 느끼게 된다.

3D -> 2D로 넘어올 때 좌표 하나(깊이, Z축)가 없어진다는 것이 중요하다. 사진으로 남게 된다. => 투영

 

 

Raycasting #2

"비율"

Ray를 이용하면 더 간단하게 처리할 수 있다.

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}");
	}
}

 

반응형
복사했습니다!