Skip to content

Unity Raycast

hyj378 edited this page Sep 1, 2018 · 3 revisions

ray

시작점부터 지정한 방향으로 향하는 무한대의 선, 이를 이용해 원하는 방향과 거리에 존재하는 물체를 확인한다.

필요한 변수 : 방향, 시작점

raycast

physics의 메소드로 ray가 충돌체와 충돌하면 True를 아니면 False를 반환한다. 주로 충돌체의 이름과 위치를 얻기위해 사용한다.

필요한 변수 : 시작점, 방향, 충돌체(RaycastHit), 최대거리, 무시할 충돌체, queryTriggerInteraction (위의 변수를 모두 필요로 하지는 않음)

DrawRay

Debug의 메소드로, 지정한 시작점과 벡터만큼 선을 이어 보여준다 이는 확인을 위한것으로 게임화면에는 보이지 않고, 콘솔창이나 씬뷰에서만 확인할 수 있다.

필요한 변수 : 시작점, 벡터, 선의 색, 보여지는 시간, depthTest

duration : How long the line will be visible for (in seconds). depthTest : Should the line be obscured by other objects closer to the camera?

LineRenderer

그래픽효과를 위해 쓰이는 lineRenderer은 선을 그리는데 쓰인다. 이것 말고도 오브젝트가 지나간 길을 잇는 트레일렌더러 등 많은 효과가 있다.

또 lineRenderer.positionCount는 라인렌더러를 이용해 만들어진 선의 세그먼트(꺽여지는 횟수) 수를 지정한다(또한 읽어온다.)

RaycastHit

ray와 충돌한 물체를 읽어올 때 유용하다. 아레 코드 if문에 조건으로 Physics.Raycast(ray.origin, ray.direction, out hit, 100) 가 있는데, out hit 처럼 쓰이고 그 조건문 내부에서 충돌체의 정보를 읽어올 때 유용하게 사용된다.

작성한 코드

using System.Collections.Generic;
using UnityEngine;

public class RayEmitter : MonoBehaviour {

    Transform goTransform;
    LineRenderer lineRenderer;
    Ray ray;
    RaycastHit hit; //충돌체
    Vector3 inDirection;
    int nReflections = 2;
    int nPoints;

	void Start () {
        goTransform = GetComponent<Transform>();
        Debug.Log(goTransform.position);
        lineRenderer = GetComponent<LineRenderer>();
	}
	

	void Update () {
        nReflections =100;
        ray = new Ray(goTransform.position, goTransform.forward);
        Debug.DrawRay(goTransform.position, goTransform.forward * 100, Color.yellow);//예비선이므로 플레이어의 화면에서는 보이지 않음
        nPoints = 2;
        lineRenderer.positionCount = nPoints;
        lineRenderer.SetPosition(0, goTransform.position);

        for (int i = 0; i <= nReflections; i++) //이를 반복문을 통해 반사될 수 있는 횟수를 결정
        {
            if (i == 0)
            {
                if (Physics.Raycast(ray.origin, ray.direction, out hit, 100))
                {
                    inDirection = Vector3.Reflect(ray.direction, hit.normal);
                    ray = new Ray(hit.point, inDirection);
                    Debug.DrawRay(hit.point, inDirection * 100, Color.yellow);//예비선이므로 플레이어의 화면에서는 보이지 않음
                    Debug.Log("Object name: " + hit.transform.name);//Debug이므로 플레이어의 화면에서는 보이지 않음
                    if (hit.transform.name == "Lock")
                    {
                        Debug.Log("Start animation");
                    }
                    if (nReflections == 1)
                    {
                        lineRenderer.positionCount = ++nPoints;//positionCount는 선의 갯수(굽은 갯수)
                    }
                    lineRenderer.SetPosition(i + 1, hit.point);
                 }
                 else
                 {
                      lineRenderer.SetPosition(i + 1, transform.forward * 5000);
                 }
            }

            else
            {
                if (Physics.Raycast(ray.origin, ray.direction, out hit, 100))//충돌 했다면
                {
                    inDirection = Vector3.Reflect(inDirection, hit.normal);
                    ray = new Ray(hit.point, inDirection);
                    Debug.DrawRay(hit.point, inDirection * 100, Color.yellow);//예비선
                    Debug.Log("Object name: " + hit.transform.name);
                    if (hit.transform.name == "Lock")
                    {
                        Debug.Log("Start animation");
                    }
                    lineRenderer.positionCount = ++nPoints;
                    lineRenderer.SetPosition(i + 1, hit.point);
                }
                else
                {
                    lineRenderer.SetPosition(i + 1, transform.forward * 5000);
                }
            }
        }
	}
}```