팀프로젝트를 마무리 단계는 코드를 분석하여서 정리하기로 하였습니다. 전 플레이어 연출인 카메라 부분 및 낙하 판정을 하는 부분을 분석해보려고 합니다.
협업한 친구가 코드를 잘 정리하여 보내주었습니다.
굿
카메라가 벽에 닿을 시 처리하는 부분
/*초기 값 설정*/
private float defaultPosition;
private float targetPosition;
public Transform cameraTransform;
defaultPosition = cameraTransform.localPosition.z;
cameraTransform.localRotation = Quaternion.identity;
cameraTransform.parent = pivotTransform;
// TPS 카메라 보정
// 카메라와 플레이어 사이에 물체가 있을 때 레이로 충돌판정, z 거리조절
private void CameraCollision()
{
// 카메라 기본위치
// 충돌이 없는경우 이 값으로 이동 될 수 있게 따로 변수 만듦
targetPosition = defaultPosition;
RaycastHit hit;
// 카메라에서 카메라 pivot 으로 향하는 방향벡터
Vector3 direction = cameraTransform.position - pivotTransform.position;
// 정규화(방향만 필요함)
direction.Normalize();
// 스피어캐스트 사용, pivotTransform.position위치에서 direction 방향으로 광선을 쏘고 그 광선을 따라서
// 반지름 0.2크기의 구를 날려서 부딪히는지 체크, 마지막 매개변수는 광선의 사거리로 카메라와 플레이어 사이 기본거리
if (Physics.SphereCast(pivotTransform.position, 0.2f, direction, out hit, Mathf.Abs(targetPosition)))
{
// 플레이어와 카메라 사이 물체가 있는경우
// distance = pivot과 충돌물체 사이의 거리값 저장
float distance = Vector3.Distance(pivotTransform.position, hit.point);
// 카메라 위치값 보정
// 카메라z 위치 = distance - 보정값(카메라 얼마나 플레이어 쪽으로 땡길지 값)
// - 붙은 이유 : 카메라 로컬 좌표, 플레이어 뒤에서 찍기 때문에
targetPosition = -(distance - tps_CameraCollisonDistance);
}
// 위에서 보정 후에
// 카메라와 pivot 사이거리가 보정값보다 짧은경우, 즉 너무 벽에 붙어있어서 벽과 플레이어 사이거리가 보정값 보다 짧은 경우
if (Mathf.Abs(targetPosition) < tps_CameraCollisonDistance)
{
// 최소 플레이어와 카메라 사이 거리를 지정해줌
// 최소값 따로 안만들고 보정값이 적당해서 그대로 사용함
targetPosition = -tps_CameraCollisonDistance;
}
// 보정한 값
// Lerp로 부드럽게 이동시킴
cameraPosition.z = Mathf.Lerp(cameraTransform.localPosition.z, targetPosition, Time.deltaTime / tps_cameraOffsetSpeed);
// 카메라 z위치 최종 보정값 실제 반영
cameraTransform.localPosition = cameraPosition;
// 카메라가 바라보는 기준을 pivot으로 해놓은 이유 : 플레이어에 변동사항이 생겨도 수정이 용이하게 하기위함
// 스피어캐스트 사용이유 : 더 정밀하게 보정할 수 있기 때문에, 그냥 레이캐스트 사용시 체크하지 못하는 부분까지 체크해줌
}
플레이어 낙하 판정 부분
// 플레이어 낙하 판정
// 바닥 거리판정이기 때문에 여기서 플레이어 y위치 처리도 함
private void PlayerFalling()
{
RaycastHit hit;
// 캡슐콜라이더의 높이의 절반 길이
float length = capsuleCollider.height * 0.5f;
// 콜라이더 박스의 중심 점
Vector3 origin = capsuleCollider.bounds.center;
// 레이캐스트, 플레이어의 콜라이더 중심으로 부터 아래 방향으로 콜라이더 절반 길이 + 최소 낙하판정 거리
// 사거리 저렇게 두고 충돌하면 바닥에 닿고 있거나 떨어져도 낙하 동작 나올만큼의 높이가 아닌 경우
if (Physics.Raycast(origin, Vector3.down, out hit, length + minimumDistanceFalling))
{
// 확인용
Debug.DrawRay(origin, Vector3.down * (length + minimumDistanceFalling), Color.red);
// 이 함수 안에 들어왔으면 바닥에 닿고 잇는 상태
inputCtrl.isGround = true;
// hit.distance = 부딪힌 지점까지의 거리
// 이 거리가 콜라이더 절반 길이보다 길면(= 바닥에 서 있는 모든 경우)
if (hit.distance > length)
{
// 플레이어의 위치 저장, 현재 위치에서 y값만 보정해주기 위해서
Vector3 newPos = transform.position;
// 현재 위치의 y값을 충돌지점의 y값으로 바꾸어준다. 즉 바닥의 y좌표랑 플레이어 y좌표랑 똑같이해서 바닥아래 발이 안빠지게 함
newPos.y = hit.point.y;
// 변경한 위치를 실제 플레이어 위치에 반영
transform.position = newPos;
}
'프로그래밍 공부 > 포트폴리오 정리' 카테고리의 다른 글
Day5 셰이더 정리 (0) | 2021.06.02 |
---|---|
Day4 포트폴리오 Enemy 정리 (0) | 2021.05.31 |
유니티 포트폴리오 (1) Enemy 리팩토링 (0) | 2021.05.13 |
유니티 포트폴리오 셰이더 - 툰 셰이더 튜토리얼 (0) | 2021.05.11 |