어떤 물체에서 광선을 발사하여 그 광선에 닿는 물체가 있는지 없는지 검사하는 하는 함수이다.
Vector3 Phisics.raycast(position, direction, distance);
유니티 스탠다드 에셋[클릭] 하여서 에셋을 다운받는다. 참고로
(2019.1 unity version 에서 import 가능하였다.
Standard Asset -> Chracters -> FirstPersonChracter -> Prefabs 에서 FPSController 프리팹을 Hierarchy창에 올리고 바닥(Plane) 감지할 대상(Cube)를 만든다.
플레이어 스크립트 컴포넌트를 하나 추가한다.
raycast 광선 상에 있는 오브젝트를 클릭하여,
이 상태로 변하고, 원하는 곳에서 클릭을 해제하면, 물체가 이동한다
DrawRay, ray : 개발자용 광선, ray 객체만들기.
Update(){
Ray ray = new Ray(rayOrigin, rayDir);
Debug.DrawRay(ray.origin, ray.direction * 100f, Color.red);
}
먼저 업데트 함수에 광선의 시작지점과, 방향을 가지는 ray 클래스를 하나 만들어 준다.
개발자용 DrawRay 함수를 통해서, 테스트시 개발자만 볼 수 있는 빨간 광선을 그려준다.
그러면 이렇게 빨간 실선으로 카메라의 방향에 따른 광선의 변화를 볼 수 있다.
layer setting : 바닥이 아닌 큐브만 일치하게 하기
물리적인 효과는 층(layer)를 통해서 감지한다.
큐브에 임의의 layer를 interactable 을 만들어 지정해주고,
public LayerMask whatIsTarget;
을 public 접근제어자로 LayerMask를 선언해준 후에
GUI를 통해 컴포넌트에 감지할 레이어를 interactable만으로 설정한다.
if (Physics.Raycast(ray,out hit, distance, whatIsTarget))
이후 Physics.Raycast의 매개변수에 whatIsTarget이라는 레이어를 전달해주어 Interactable 레이어만을 감지할 수 있도록 한다.
RaycastHit, 레이캐스트로 감지한 객체에 관한 모든 것
RaycastHit hit;
if (Physics.Raycast(ray,out hit, distance, whatIsTarget))
{
...
}
여기서 out hit 은 무엇일까?
RaycastHit클래스를 통해서 레이캐스트의 광선에 맞은 객체를 담는 컨테이너로 hit을 뽑아 낼 수 있다.
GameObject hitTarget = hit.collider.gameObject;
물리적으로 감지된 hit의 콜라이더를 통해 접근한 게임오브젝트를
새로운 hitTarget에 초기화 시키면 비로소 hitTarget은 광선에 맞은 객체이다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RayInterection : MonoBehaviour
{
//카메라의 정중장에서 광선을 쏘아서 일정거리내에 무언가가 있으면 감지해주는 스크립
public LayerMask whatIsTarget;
private Camera playerCam;
// 위치를 감지하기 위해서는 우선 카메라의 위치를 알고 있어야함
public float distance = 100f;
// 카메라로 부터 감지할 거리
private Transform moveTarget;
private float targetDistance;
void Start()
{
playerCam = Camera.main;
// 게임이 시작 되면 현재 활성화된 메인 카메라를 가져온다.
}
void Update()
{
Vector3 rayOrigin = playerCam.ViewportToWorldPoint(new Vector3(0.5f,0.5f,0f));
// rayOrigin : 광선이 날아갈 정중앙위치
// ViewportToWolrdPoint : 카메라의 한 지점의 위치가 게임상에서
// 어느 위치(가로 중앙, 세로 중, 카메라의 깊이(0))를 리턴
Vector3 rayDir = playerCam.transform.forward;
// 광선의 방향 = 카메라의 앞
Ray ray = new Ray(rayOrigin, rayDir);
Debug.DrawRay(ray.origin, ray.direction * 100f, Color.red);
if(Input.GetMouseButtonDown(0))
{
RaycastHit hit; // 레이캐스트 광선에 맞은 객체의 정보르 담는 컨테이너
if (Physics.Raycast(ray,out hit, distance, whatIsTarget))
// 레이캐스트는 물리처리 이므로 Phisics의 함수
// Raycast(광선 시작지점, 방향, 거리)
{
GameObject hitTarget = hit.collider.gameObject;
// hit에 부딪힌 콜라이더의 게임오브젝트를 가져온다.
hitTarget.GetComponent<Renderer>().material.color = Color.red;
moveTarget = hitTarget.transform;
targetDistance = hit.distance;
Debug.Log(hit.collider.gameObject.name);
Debug.Log("무엇인가 광선에 감지되었다.");
}
}
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;
// 무브타겟의 위치는 광선 발사 지점에서 ray 방향으로 targetDistance 앞으로 설정한다.
}
}
}