오늘은 어제에 이어 3번째 퍼즐을 만들어보았다.
이번에 만들어볼 퍼즐은 LineRenderer와 reflect를 이용한 레이저굴절 로직 퍼즐이다.
아무래도 퍼즐요소는 layer와 collision기능을 많이 사용할 수 밖에 없는건지 내가 많이 쓰는지는 모르겠지만 가보자.
먼저 필요한 것들을 생각해보자.
1. 라인랜더러 = 레이저
2. 레이저 최대 거리(설정 안해줬다가 강제종료 되었었다.._)
3. 레이저가 최종적으로 닿으면 클리어 될 레이어
4. 레이저를 튕겨낼 레이어
이정도가 필수인것 같다.
추가적인 부분들은 코드에서 살펴보자.
레이저 발사
private void FireLaser()
{
lineRenderer.positionCount = 1; // 시작점만 설정
lineRenderer.SetPosition(0, startPos.position);
// 반사 처리
ReflectLaser(transform.position, transform.forward, 0);
}
라인 렌더러는 positioncount로 여러 변곡점?을 줄 수 있는데, 선이 되기 위해서는 점이 두개가 필요하다. 하지만 레이저가 발사되기 전이라면? 점 하나만 생성해도 문제없다.
그래서 먼저 positoincount를 1로 주었고, 위치는 positioncount의 첫 번째 배열 그리고 위치를 넣어준다.
위치는 처음에는 transform.position을 사용했었는데, 퍼즐의 피봇에서 나가는게 아니라 좀 더 아래에서 위치가 되어서 Transform을 만들어주었다.
그리고 반사처리를 해준다.
반사처리
private void ReflectLaser(Vector3 origin, Vector3 direction, int currentReflection)
{
if (currentReflection >= maxReflections)
return;
RaycastHit hit;
// 충돌 체크
if (Physics.Raycast(origin, direction, out hit, maxDistance))
{
lineRenderer.positionCount++;
lineRenderer.SetPosition(currentReflection + 1, hit.point);
// 거울에 닿으면 반사 처리
if (IsCollisionWithLayer(hit.collider.gameObject, mirrorLayer))
{
Vector3 reflectDirection = Vector3.Reflect(direction, hit.normal);
ReflectLaser(hit.point, reflectDirection, currentReflection + 1);
}
// 퍼즐 오브젝트에 닿으면
else if (IsCollisionWithLayer(hit.collider.gameObject, correctLaserLayer)) //추후에 거울, 최종 나누기
{
IsComplete = true; // 완료 체크
Debug.Log("레이저 클리어!");
}
}
else
{
// 충돌하지 않으면 최대 거리로 설정
lineRenderer.positionCount++;
lineRenderer.SetPosition(currentReflection + 1, origin + direction * maxDistance);
}
}
반사를 위해 매개변수로 시작점, 방향, 현재반사횟수를 받아준다.
그리고 위에서 선이 아닌 점 하나를 만들었으니 하나 더 추가해 선을 만들어주기 위해 positioncount를 올려준다. 위치는 이번에는 ray를 쏜 위치로 설정해준다.
이제 거울에 닿으면, 최종적으로 클리어할?물체에 닿으면을 처리해준다.
거울은 반사처리를 위해 Vector3에 Reflect를 이용해 들어온 방향과 맞은 지점을 반사시켜준다.
충돌하지 않으면 최대거리까지 발사되도록 구현했다.
이 클래스도 puzzle을 상속받아 확장성을 고려하였다.
내일은 매니저들을 리펙토링 할 예정이다. 던전에 들어올때만 생성되도 되는 던전 매니저, 퍼즐 매니저, 스폰 매니저(적 생성)은 singleton을 상속받지 않음으로 dontdestroy 되지 않도록 해줄 예정이다. 아마 GameManager에서 던전에 입장하면 생성되도록 그리고 던전에서 나머지 매니저들 만들어주면되지 않을까 생각해본다.