[내배캠] 최종 프로젝트 #18. 몬스터 - 플레이어 사이 장애물 확인

Sungchan Ahn(안성찬)·2024년 12월 31일

내일배움캠프

목록 보기
92/104

몬스터 - 플레이어 사이에 장애물이 존재하면 플레이어를 인식하지 못하게 하기

  • 수정 전 : Raycast에서 LayerMask를 설정하면 해당 Layer만 검출하고 나머지는 무시하기 때문에 Monster - Player - Obstacle(장애물) 순서로 있어도 몬스터가 플레이어를 인식하지 못함
    • 이렇게 코드를 작성했던 이유 : Raycast의 return값을 검출된 대상이 LayerMask인지 아닌지로 생각했기 때문
    • LayerMask를 설정하면 해당 Layer를 제외한 object는 무시하기 때문에 플레이어가 장애물보다 앞에(가까이) 있어도 플레이어를 무시하고 뒤에 있는 장애물만 검출해서 IsTargetInFieldOfView 메서드의 return 값이 계속 false가 됨
protected bool IsTargetInFieldOfView()
    {
        Vector3 directionToTarget = GetTargetDirection();

        RaycastHit obstacleHit;
        
        // 몬스터 시야 높이. 이 높이에서 플레이어 방향으로 Ray를 쏨
        Vector3 offset = new Vector3(0, 1, 2);
        
        // 플레이어 방향으로 쏜 Ray에서 장애물 Layer가 검출되지 않으면 true 반환
        if (!Physics.Raycast(
        		stateMachine.Monster.transform.position + offset,
                directionToTarget,
                out obstacleHit,
                stateMachine.Monster.data.detectRange,
                stateMachine.Monster.obstacleMask))
        {
            return true;
        }
        
        return false;
    }
  • 수정 후 : 장애물이 검출되면 RaycastHit.distance를 통해 장애물이 검출된 위치까지의 거리를 얻고, 이 거리를 플레이어와의 거리와 비교
    플레이어와의 거리보다 짧으면 장애물이 더 가까이 있는 것 -> 플레이어와 몬스터 사이에 장애물이 있음
    protected bool IsTargetInFieldOfView()
    {
        Vector3 directionToTarget = GetTargetDirection();

        RaycastHit obstacleHit;
        Vector3 offset = new Vector3(0, 1, 2);
        
        // 플레이어 방향으로 쏜 Ray에서 장애물 Layer가 검출되지 않으면 true 반환
        if (!Physics.Raycast(
        		stateMachine.Monster.transform.position + offset,
                directionToTarget,
                out obstacleHit,
                stateMachine.Monster.data.detectRange,
                stateMachine.Monster.obstacleMask))
        {
            return true;
        }
        // 장애물 Layer가 검출되면 검출된 장애물까지의 거리와 플레이어와의 거리를 비교
        else
        {
            // 장애물보다 플레이어가 가까우면 true
            if (DistanceToTarget() < obstacleHit.distance * obstacleHit.distance) return true;
            else return false;
        }
    }
    
    protected Vector3 GetTargetDirection()
    {
        Vector3 directionToTarget = stateMachine.Target.transform.position - stateMachine.Monster.transform.position;
        return directionToTarget;
    }
    
    private float DistanceToTarget()
    {
        return (stateMachine.Target.transform.position - stateMachine.Monster.transform.position).sqrMagnitude;
    }
profile
게임 개발 기록

0개의 댓글