ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 유니티 레이캐스트 Raycast 충돌 / Ray의 모든 것
    유니티(Unity)/유니티 코딩 2019. 2. 20. 13:30

    해당 티스토리 페이지는 필자가 유니티 C# 개발을 하면서 학습한 내용들을 기록하고 공유하는 페이지입니다 !

    - 틀린 부분이 있거나, 수정된 부분이 있다면 댓글로 알려주세요 !

    - 해당 내용을 공유 or 퍼가도 좋으나, 출처를 꼭 명시해주세요 !

    - 해당 글의 모든 저작권은 Chameleon Studio에 있습니다.

    - 방문해주셔서 감사합니다 ^^




    안녕하세요! 카멜레온입니다 ㅎㅎ


    오늘은 Ray와 Raycast / Raycast2D를 알아보려고합니다.


    이 두 놈은 유니티 콜라이더 충돌에서 유용하게 사용됩니다.


    콜라이더를 사용해서 트리거와 콜루젼에 대해서는


    이미 설명해놓은 포스팅이 있으니,


    콜라이더를 잘 모르시는 분들은


    그 글을 먼저 읽고 오시는 것을 추천합니다.


    시작해봅시다.




    RayCast의 요약도 이미지입니다.RayCast의 요약도



    레이캐스트를 그림으로 그려보면 대략 이렇습니다.


    귀여운 젤랑이가 폭죽 레이져를 들고 있습니다.


    젤랑이는 폭탄을 향해서(방향) 폭죽 레이져(레이)를 발사합니다.


     폭죽 레이져가 폭탄까지 나아갑니다. (거리)


    폭죽 레이져가 폭탄에 닿으면 젤랑이한테


    닿았다고 알려줍니다. (충돌감지)


    이러한 일련의 과정이 바로 레이캐스트입니다.


    만약 폭죽(원점)에서 나아가는 레이져(레이)의 방향에


    폭탄이 없다면?


    폭죽 레이져는 아무 것도 충돌하지 않았기 때문에


    충돌 감지를 하지 않습니다.


    당연한 것이겠지요.


    아무 것도 감지를 못했으니 말이죠.



    젤랑이의 빵야빵야 이미지입니다.빵야~빵야~


    이제 우리는 그림을 통해 대략적으로


    레이캐스트(Raycast)를 이해했습니다.


    Raycast는 Raycast 스크립팅을 가진


    게임오브젝트의 원점에서


    내가 설정한 방향으로 Ray를 날려


    내가 설정한 거리 이내


    물체가 있는지 없는지 충돌감지를 해주는 것입니다.


    그렇다면,


    Raycast의 정의에 대해 어느정도 이해를 했으니


    완전히 이해하기 위해서 스크립팅을 해봅시다.


    원점, 내가 설정한 방향, 내가 설정한 거리를 스크립팅하고


    Ray를 쏴서 부딪히는 물체가 있는지 충돌(감지)여부 판단을 해봅시다.



    프로젝트를 연 이미지입니다.프로젝트 열기



    우선, 프로젝트를 열어주세요.


    저는 미리


    개굴랑이, 천사랑이, 야구 젤랑이


    세 놈을 세팅해두었습니다.


    그리고 카메라 뒤에


    3D 게임오브젝트 중 하나인


    캡슐 오브젝트를 만들어두었습니다.


    이 캡슐 오브젝트에


    레이캐스트 스크립트를 넣고


    캡슐이 젤랑이들을 향해서


    레이를 쏴보도록 하겠습니다.


    여러분들도 같이 따라하기 위해서


    먼저 세팅을 도와드리자면,



    하이어라키 창의 게임오브젝트 설정하는 이미지이 입니다.하이어라키 창에서 게임오브젝트 설정하기



    우선 게임오브젝트 3개를 만드세요.


    젤랑이 3명 대신에 여러분들은


    3D 큐브 3개를 만들어주세요.


    하이어라키 창 > 마우스 우클릭 > 3D Object > Cube


    를 누르시면 됩니다.


    그 다음 레이스크립트를 넣을


    캡슐을 하나 만들어주세요.


    캡슐도 똑같은 방법으로


    하이어라키 창 > 마우스 우클릭 > 3D Object > Capsule


    을 만드시면 됩니다.



    캡슐 오브젝트를 세팅하는 이미지입니다.캡슐 오브젝트 세팅하기



    캡슐을 만드시면,


    콜라이더가 씌워져 있을겁니다.


    콜라이더는 Remove Component 해주세요.


    레이 스크립트를 캡슐에 넣을건데,


    캡슐에 콜라이더가 씌워져있으면


    레이가 캡슐의 콜라이더를 인식하여서


    젤랑이들이 맞을 수 없답니다.


    그 후 캡슐의 포지션은


    Y값은 1, Z값은 -15로 설정해둡니다.


    X값은 아무렇게나 두셔도 상관없어요


    그 다음 레이 스크립트를 하나 만들어서


    넣어주세요.


    프로젝트가 다 세팅이 된 후에


    스크립팅을 해봅시다.



    젤랑(큐브) 세팅하는 이미지입니다.젤랑(큐브) 세팅하기



    캡슐 세팅이 다 되었다면


    큐브 세팅을 해야겠죠.


    큐브는 자동으로 콜라이더 설정되어 있으니


    포지션만 설정해주시면 됩니다.


    캡슐 1은


    X값 -4.5, Y값 1, Z값 -3


    캡슐 2는


    X값 0, Y값 1, Z값 -3


    캡슐 3은


    X값 4.5, Y값 1, Z값 -3


    으로 둬봅시다.


    자,, 이제 게임 오브젝트의 세팅이


    끝났습니다.


    스크립팅을 하러 가봅시다.


    RayScript를 열어주세요.



    아래 코드를 캡처한 사진입니다.이미지가 안보이시는 분들은 아래 코드 보기를 누르고 코드를 확인해주세요.




    우선 RaycastHit을 선언해줍니다.


    이 놈이 바로 충돌(감지)가 일어났는지


    일어나지 않았는지 감지하는 놈입니다.


    hit이 되면 감지가 되어 코드를 실행하고


    hit이 되지 않으면 그냥 null값이 되어


    아무 일도 일어나지 않습니다.


    다음은 MaxDistance를 설정해주세요.


    Ray가 나아갈 거리를 설정한 것입니다.


    설정을 하지 않는다면,


    무제한으로 앞으로 나아갑니다.


    맨 끝에 콜라이더 벽이 있는 월드가 아닌 이상


    굳이 그럴 필요는 없겠지요.


    일단 레이의 길이를 15로 두겠습니다.



    아래 코드를 캡처한 사진입니다.이미지가 안보이시는 분들은 아래 코드 보기를 누르고 코드를 확인해주세요.




    다음으로 업데이트 문입니다.


    일단 캡슐에 GetKey를 사용하여 움직임을 주었습니다.


    키코드는 키보드 왼쪽 화살표와 오른쪽 화살표입니다.


    키코드에 더 알고 싶으신 분들은 >여기<를 눌러주세요.


    키보드 왼쪽 화살표를 누르면,


    캡슐이 왼쪽으로,


    키보드 오른쪽 화살표를 누르면


    캡슐이 오른쪽으로 움직이게끔 처리해두었습니다.


    그 다음으로 스페이스바를 누르면


    레이가 발사되는 처리를 하였습니다.


    먼저,


    if (Physics.Raycast(transform.position, transform.forward, out hit, MaxDistance))


    이 코드가 바로 레이캐스트 과정입니다.


    Physics.Raycast를 선언하고


    괄호 안에


    (Ray 원점, Ray 방향, 충돌 감지할 RaycastHit, Ray 거리(길이))


    를 넣어주면 됩니다.


    맨 마지막에 있는 Ray 거리(길이)를 넣지 않아도 되는데,


    넣지 않으면 아까 언급했던 것처럼 무제한으로 나아갑니다.


    그렇다면 지금의 코드는?


    Physics.Raycast(원점: 캡슐 위치, 방향: 캡슐의 앞 방향, 충돌감지: hit, 거리: 15)


    로 설정한 것이죠.


    Debug.DrawRay(transform.position, transform.forward * MaxDistance, Color.blue, 0.3f);


    다음은 이 부분에 대한 설명을 하겠습니다.


    이 코드는 레이를 씬에서 보기 위하여 로그를 찍어보는 코드입니다.


    만약 Debug.DrawRay 부분이 없다면 우리는 씬에서


    레이가 나아가는 것을 볼 수가 없습니다.


    여러분들이 저 부분을 지우고 ▶을 누르면


    바로 무슨 말인지 이해하실 겁니다.


    Debug.DrawRay의 사용법은


    Debug.DrawRay(원점: 캡슐 위치, 방향: 캡슐의 앞 방향 * 15, DrawRay의 색: 블루, DrawRay가 보여질 시간: 0.3초)


    입니다.


    기본적으로 DrawRay의 길이는 1이기 때문에,


    MaxDistance를 곱해줘서


    DrawRay도 Ray의 길이와 같게 해주었고,


    DrawRay의 색은 파란색으로 했는데,


    여러분 임의로 바꾸실 수 있습니다.


    그다음 뒤에 0.3f는


    DrawRay가 보여지는 시간으로


    0.3초만 나타났다가 사라집니다.


    hit.transform.GetComponent<MeshRenderer>().material.color = Color.red; // 큐브 색 변경


    이제 hit이 충돌감지를 한다면


    레이와 충돌한 물체는 빨간색으로 변할 것입니다. 


    자 레이캐스트(Raycast)의 세팅을 끝냈으니,


    스크립트 저장 후, 유니티로 돌아와서 실행해봅시다.





    캡슐이 좌우로 움직이면서 젤랑이들을 치니,


    젤랑이들이 하나 둘 색이 변하는 것을 확인했습니다.


    Ray는 이렇듯 충돌감지를하고


    충돌한 물체에 어떠한 행위를 하도록 할 수 있습니다.


    지금은 그 어떠한 행위가


    "빨간색으로 변해라!" 였구요.


    그렇다면 만약,


    젤랑이들이 일렬로 서있다면 어떠한 지 볼까요?


    레이가 젤랑이 세 명을 다 관통하여


    빨간색으로 변하게 하는지를요.


    우선 젤랑이의 위치를 일렬로 바꿔보겠습니다.


    젤랑이들의 X값을 0으로 두고,


    Z값을 0, -4, -8로 차례대로 세워보겠습니다.


    일렬로 줄을 세웠으니 유니티를 실행해볼게요.





    확인을 해보니,


    레이는 맨 처음 충돌이 일어난 직후인


    딱 1번만 반응을 하고


    그 다음은 반응을 하지 않습니다.


    쉽게 말해 레이캐스트는 관통을 하지 못하는데요.


    싫은데 ㅠ 나는 다 관통시키고 싶은데 ㅠ


    하시는 분들이 분명 있겠지요?


    그.래.서


    유니티가 준비한 것이 바로


    RaycastAll입니다.


    RaycastAll은 Ray와 충돌한 물체를


    전부 찾아줍니다.


    Raycast보다는 좀 심화된 내용이지만


    한 번 확인해보죠.


    코드를 살짝 바꿔봅시다.



    아래 코드를 캡처한 사진입니다.이미지가 안보이시는 분들은 아래 코드 보기를 누르고 코드를 확인해주세요.




    우선 레이가 충돌감지한 오브젝트를 담기 위하여


    RaycastHit의 배열을 선언해줍니다.



    아래 코드를 캡처한 사진입니다.이미지가 안보이시는 분들은 아래 코드 보기를 누르고 코드를 확인해주세요.




    다음으로


    hits = Physics.RaycastAll(transform.position, transform.forward, MaxDistance);


    hits 배열에 담긴 레이의 위치, 방향, 길이를 잡아줍니다.


    for (int i = 0; i < hits.Length; i++)


    for문으로 레이와 충돌한 애들을 모두 찾아줍니다.


    for문이 생소하신 분은 >여기<에서


    익숙해지고 오시면 됩니다.


    다시 돌아와서,


    충돌한 애들을 찾았으면


    RaycastHit hit = hits[i];


    hit에 찾은 애들의 정보를 담습니다.


    SpriteRenderer ChangeColor = hit.transform.GetComponent<SpriteRenderer>();


    그 다음 젤랑이들의 색 변경이 가능한 SpriteRenderer를 찾아서


    ChangeColor 변수에 담고


    hit.transform.GetComponent<SpriteRenderer>().color = Color.red;


    레이에 맞은 젤랑이의 색을 모두 바꿔줍니다.


    이렇게 코드를 살짝 바꿔보았는데요.


    이제 젤랑이 모두가 색이 변하는지 확인해봅시다.





    Ray를 쏘니 젤랑이 모두의 색이 바뀌었습니다.


    이렇게 한 번에 올킬이 되니 참 편하고 좋은데요.


    갑자기 문득 이런 생각이 듭니다.


    가운데에 있는 천사 젤랑이만 레이에 맞게 할 순 없을까?


    여러분들도 그런 생각을 하셨죠?


    그래서 마지막으로 준비한 것이 있습니다.


    가운데 천사 젤랑이만 맞게하는


    LayerMask입니다.


    LayerMask는 엄청 간단합니다.


    우선 스크립트로 가봅시다.



    아래 코드를 캡처한 사진입니다.이미지가 안보이시는 분들은 아래 코드 보기를 누르고 코드를 확인해주세요.




    우선 RaycastHit을 배열로 선언했었는데,


    이전 스크립트로 돌려줍니다.


    RaycastHit hit;


    으로 바꿔주세요.


    그 후로 밑에서 쓸 LayerMask;를


    선언해줍니다.


    그 다음으로,


     

    아래 코드를 캡처한 사진입니다.이미지가 안보이시는 분들은 아래 코드 보기를 누르고 코드를 확인해주세요.




    RaycastAll 스크립트를


    이전에 테스트한 Raycast로 바꿔줍니다.


    그 다음 뭔가 바뀐 게 보이시나요?


    MaxDistance뒤에


    , LayerMask가 붙어있습니다.


    LayerMask를 뒤에 붙여줘야


    '내 Raycast는 LayerMask를 사용할거다.'


    라고 할 수 있습니다.


    이렇게 세팅이 끝입니다.


    간단하죠?



    Layer Mask 설정하는 이미지 입니다.Layer Mask 설정



    그 다음 유니티로 돌아와


    캡슐을 눌러서 LayerMask를 설정해줍니다.


    Layer를 하나 만들고(저는 PickMe 레이어를 만들었습니다.)


    Ray Script에서 PickMe를 체크해줍니다.


    그 다음


    PickMe 레이어를 천사 젤랑이에게 붙혀줍니다.


    여러분들은 가운데 큐브에 붙혀주시면 되겠습니다.


    레이어를 만드는 법을 모르시는 분은 >여기<를 눌러주세요.


    레이어 만드는 법까지 넣으면 글이 너무 길어질 것 같네요 ㅎㅎ


    자 Layer 설정까지 끝났으니,


    레이(Ray)가


    맨 앞에 있는 젤랑이를 통과하고


    뒤에 있는 천사 젤랑이를 맞추는 지 확인해봅시다.





    정확히 Layer가 달린


    가운데에 있는


    천사 젤랑이를 맞추고 있습니다.


    이렇게 LayerMask를 사용해서,


    적과 아군이 나오는 게임에서


    아군의 레이어는 '아군'으로하고


    적군의 레이어는 '적군'으로 한다음


    내가 날린 총알이 적군만 맞는다고 처리를


    할 수도 있겠습니다.



    여기까지 유니티 Raycast 충돌에 대해 알아보았습니다.


    Ray는 참 유용한 기능이기때문에


    기능이 많다보니,


    글이 매우 길어졌습니다.


    그래서 다음 포스팅으로 나누어서


    Raycast2D를 언급하면서


    ScreenPointToRay에 대해 추가적으로


    언급하려고합니다.


    유니티 코딩 카테고리를 확인해주세요.


    이상으로 포스팅을 마치며,


    잘 읽으셨다면 댓글을 달아주세요.


    댓글은 저에게 다음 포스팅을 위한 힘이 됩니다 ㅠ ㅠ


    또, 카멜레온이 다뤘으면 좋겠다하는 포스팅 내용을 달아주시면,


    해당 내용에 관한 포스팅도 해보도록 하겠습니다.


    감사합니다 !


    Chameleon Studio가 만든 게임하러가기


    <젤랑점핑>

    안드로이드- market://details?id=com.Cameleon.TangTangBall

    IOS- itms-apps://itunes.apple.com/app/id1429522379



    <크러쉬팡>

    안드로이드- market://details?id=com.Chameleon.CrushPang 

    IOS- itms-apps://itunes.apple.com/app/id1450109331


    댓글

Designed by Tistory.