팀프로젝트를 마무리 단계는 코드를 분석하여서 정리하기로 하였습니다. 전 플레이어 연출인 카메라 부분 및 낙하 판정을 하는 부분을 분석해보려고 합니다.

협업한 친구가 코드를 잘 정리하여 보내주었습니다.

굿

카메라가 벽에 닿을 시 처리하는 부분

카메라 값

    /*초기 값 설정*/
    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;
            }

 

+ Recent posts