본문 바로가기
C#

레이캐스트(Raycast)

by imagineer_jinny 2021. 7. 23.

레이캐스트는 어떤 위치에서 광선을 발사해서 그 광선이 닿는 물체가 있는지 검사하는 방식

 

만들어볼 것:

- FPS 플레이어가 응시하고 있는 눈앞의 사물을 다른 곳으로 옮기는 작업

- 카메라의 정 중앙으로 광선을 쏴서 레이캐스트 통해 눈 앞의 사물 검사

 

1. Cube 광선에 감지

public class RayInteraction : MonoBehaviour
{
    public LayerMask whatIsTarget;
    
    //카메라의 정 중앙에서 앞쪽으로 향하는 광선을 쏠 것임
    private Camera playerCam;
    //광선이 날아가는 거리
    public float distance = 100f;

    void Start()
    {
        //현재 활성화된 메인 카메라를ㅔ playerCam으로 
        playerCam = Camera.main;

    }

    // Update is called once per frame
    void Update()
    {
      //광선이 시작될 지점
      //카메라 내장 함수 중에서 카메라 상 위치 찍어주면
      //그 위치가 실제 게임상에서 어떤 위치인지 알려주는 함수 있음
      // : ViewportToWorldPoint는 화면상의 위치 찍어주면 
      //화면상의 점이 WorldPosition으로 어딘지 알려줌 

      //카메라로 보고 있는 화면상의 정 중앙 지점이 게임 세상 기준으로 어떤 지점인지 나옴
      Vector3 rayOrigin = playerCam.ViewportToWorldPoint(new Vector3 (0.5f,0.5f,0f));

      //광선을 어느 방향으로 날아갈지 정해주기
      //카메라의 앞쪽 방향이 Vector3로 들어옴
      Vector3 rayDir = playerCam.transform.forward;

        //Ray 눈으로 보이게 하기
        Debug.DrawRay(rayOrigin, rayDir * 100f, Color.green);

        if(Input.GetMouseButtonDown(0))
        {
            //광선 시작 지점, 광선 방향, 사전거리, 원하는 타겟
            if(Physics.Raycast(rayOrigin,rayDir,distance, whatIsTarget ))
            {
                Debug.Log("뭔가 광선에 걸렸다.");
            }
        }
    }
}

 

2. 광선에 닿은 친구 가져와서 옮겨주기

-광선에 닿은 친구 정보를 가져와야함

-RaycastHit : Raycast에 의한 정보를 담아줌

out은 입력으로 들어간 값이 내부에서 어떤 값이 생겨서 빠져나온다는 뜻

raycast에 대한 정보를 hit에 챙겨서 넘겨줌

 

hit 안에는 충돌한 상대방 뿐만 아니라, hit.point(충돌한 위치), hit.normal(충돌값 : 충돌한 상대방의 평면을 보고 있는 방향), hit.distance(충돌한 위치까지의 거리) 등이 들어있음.

 

ray 만들어주는 법 다양함

//광선 만들기 (광선 시작점, 광선 방향)
Ray ray = new Ray(rayOrigin, rayDir);

//Ray 눈으로 보이게 하기 1
Debug.DrawRay(rayOrigin, rayDir * 100f, Color.green);

//Ray 눈으로 보이게 하기 2
Debug.DrawRay(ray.origin, ray.direction* 100f, Color.green);

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RayInteraction : MonoBehaviour
{
    public LayerMask whatIsTarget;
    
    //카메라의 정 중앙에서 앞쪽으로 향하는 광선을 쏠 것임
    private Camera playerCam;
    //광선이 날아가는 거리
    public float distance = 100f;

    //충돌한 상대방을 여기 넣기
    private Transform moveTarget;
    
    //상대방과 나 사이의 거리를 기억한 후 간격을 유지한채로 옮겨줄것임
    private float targetDistance;
    void Start()
    {
        //현재 활성화된 메인 카메라를ㅔ playerCam으로 
        playerCam = Camera.main;

    }

    // Update is called once per frame
    void Update()
    {
      
      //광선이 시작될 지점
      //카메라 내장 함수 중에서 카메라 상 위치 찍어주면
      //그 위치가 실제 게임상에서 어떤 위치인지 알려주는 함수 있음
      // : ViewportToWorldPoint는 화면상의 위치 찍어주면 
      //화면상의 점이 WorldPosition으로 어딘지 알려줌 

      //카메라로 보고 있는 화면상의 정 중앙 지점이 게임 세상 기준으로 어떤 지점인지 나옴
      Vector3 rayOrigin = playerCam.ViewportToWorldPoint(new Vector3 (0.5f,0.5f,0f));

      //광선을 어느 방향으로 날아갈지 정해주기
      //카메라의 앞쪽 방향이 Vector3로 들어옴
      Vector3 rayDir = playerCam.transform.forward;

        //광선 만들기 (광선 시작점, 광선 방향)
        Ray ray = new Ray(rayOrigin, rayDir);

        
       //Ray 눈으로 보이게 하기
        //Debug.DrawRay(rayOrigin, rayDir * 100f, Color.green);
        Debug.DrawRay(ray.origin, ray.direction * 100f, Color.green);

        if (Input.GetMouseButtonDown(0))
        {
            RaycastHit hit;

            //광선 시작 지점, 광선 방향, 사전거리, 원하는 타겟
            if(Physics.Raycast(ray,out hit, distance, whatIsTarget ))
            {
                //충돌한 상대방 가져오기
                GameObject hitTarget = hit.collider.gameObject;

                hitTarget.GetComponent<Renderer>().material.color = Color.red;

                moveTarget = hitTarget.transform;
                targetDistance = hit.distance;
            }
        }

        if(Input.GetMouseButtonUp(0))
        {
            if(moveTarget!=null)
            {
                moveTarget.GetComponent<Renderer>().material.color = Color.white;
            }
            moveTarget = null;
        }

        if(moveTarget!=null)
        {
            moveTarget.position = ray.origin + ray.direction * targetDistance;
        }
    }
}

'C#' 카테고리의 다른 글

제네릭  (0) 2021.07.21
액션 + 람다 함수  (0) 2021.07.21
이벤트  (0) 2021.07.21
델리게이트  (0) 2021.07.20
유니티 이벤트  (0) 2021.07.20

댓글