[패스트캠퍼스 수강 후기] 올인원 패키지 : 유니티 포트폴리오 완성 100% 환급 챌린지 11회차 미션 시작합니다.



적 캐릭터 AI 구현의 캐릭터 가시선 시뮬레이션 구현에 대한 내용입니다.

캐릭터 시야 뷰에 대한 FOV 등을 컴포넌트로 따로 구현하여 사용하도록 합니다.

 



대략 위의 그림과 같이 캐릭터의 시야에 대한 처리를 하게 되고, 오른쪽 그림은 실제로는 반지름을 가진 부채꼴 형태로 인지하게 될 것입니다.

별도 컴포넌트로 제작하기 위해서

Project - Scripts - FieldOfView_New 컴포넌트를 추가합니다.


FieldOfView_New.cs

public class FieldOfView_New : MonoBehaviour
{
    public float viewRadius = 5f;
    [Range(0, 360)]
    public float viewAngle = 90f;
    
    public LayerMask targetMask; // 적을 검색하기 위한 레이어마스크
    public LayerMask obstacleMask; // 캐릭터와 적 사이의 장애물 레이어마스크
    
    private List<Transform> visibleTargets = new List<Transform>(); // 탐색된 적들을 리스트로 관리
    
    private Transform nearestTarget; // 가장 가까이 있는 적
    private float distanceToTarget = 0.0f; // 가장 가까운 적까지의 거리
    
    void Start()
    {
    }
   
    void Update()
    {
        FindVisibleTargets();
    }
    
    // 보이는 적 찾기
    void FindVisibleTargets()
    {
        distanceToTarget = 0.0f;
        nearestTarget = null;
        visibleTargets.Clear();
        
        Collider[] targetsInViewRadius = Physics.OverlapSphere(transform.position, viewRadius, targetMask);
        for (int i = 0; i < targetsInViewRadius.Length; ++i)
        {
            Transform target = targetsInViewRadius[i].transform;
            
            Vector3 dirToTarget = (target.position - transform.position).normalized; // 방향 검색
            if (Vector3.Angle(transform.forward, dirToTarget) < viewAngle / 2)
            {
                float dstToTarget = Vector3.Distance(transform.position, target.position);
                // 장애물이 있는지 검사
                if (!Physics.Raycast(transform.position, dirToTarget, dstToTarget, obstacleMask))
                {
                    visibleTargets.Add(target);
                    if (nearestTarget == null || (distanceToTarget > dstToTarget))
                    {
                        nearestTarget = target;
                        distanceToTarget = dstToTarget;
                    }
                }
            }
        }
    }
}

 

 


역시 Physics.OverlapSphere() 함수를 사용하여 특정 거리 내의 충돌 GameObject들을 걸러 냅니다.
자기 시야각에 있는 적들을 지속 검색하고 가장 가까운 적을 찾는 것까지입니다.
사진에 보이는 것 처럼 FOV내 모든 적을 검색하고 장애물에 가리지 않고 시야에 들어오는 적만 찾아내는 것입니다.


여기에다가 FieldOfView Editor의 Debugging을 위해서 Editor 기능을 추가해보도록 합니다.

 

 


위와 같이 FieldOfView_NewEditor 스크립트를 추가해 줍니다.


FieldOfView_NewEditor.cs

[CustomEditor(typeof(FieldOfView_New))]
public class FieldOfView_NewEditor : Editor
{
    private void OnSceneGUI()
    {
        private FieldOfView_New fov = (FieldOfView_New)target;
        
        // 시야거리 그리기
        Handles.color = Color.white;
        Handles.DrawWireArc(fov.transform.position, Vector3.up, Vector3.forward, 360, fov.viewRadius);
        
        Vector3 viewAngleA = fov.DirFromAngle(-fov.viewAngle / 2, false); // 왼쪽 꼭지점
        Vector3 viewAngleB = fov.DirFromAngle(fov.viewAngle / 2, false); // 오른쪽 꼭지점
       
        Handles.DrawLine(fov.transform.position, fov.transform.position + viewAngleA * fov.viewRadius);
        Handles.DrawLine(fov.transform.position, fov.transform.position + viewAngleB * fov.viewRadius);
        
        Handles.color = Color.red;
        foreach (Transform visibleTarget in fov.VisibleTargets)
        {
            Handles.DrawLine(fov.transform.position, visibleTarget.position);
        }
    }
}


 


시야반경과 시야각 등을 그리기 위해서 삼각함수 계산에 대해 설명해주십니다.


FieldOfView_New.cs에 아래의 함수를 추가합니다.

    public Vector3 DirFromAngle(float angleInDegrees, bool angleIsGlobal)
    {
        if (!angleIsGlobal)
        {
            angleInDegrees += transform.eulerAngles.y;
        }
        
        return new Vector3(Mathf.Sin(angleInDegrees * Mathf.Deg2Rad), 0, Mathf.Cos(angleInDegrees * Mathf.Deg2Rad));
    }

    

 

 


컴파일이 잘 되면 이렇게 구현이 되어 나타나고, SearchEnemy 부분을 수정해주어야 최종적으로 시야를 체크하는 부분이 완성될텐데 내일 이어서 보도록 하지요.



패스트캠퍼스 - 올인원 패키지 : 유니티 포트폴리오 완성 bit.ly/2R561g0

 

유니티 게임 포트폴리오 완성 올인원 패키지 Online. | 패스트캠퍼스

게임 콘텐츠 프로그래머로 취업하고 싶다면, 포트폴리오 완성은 필수! '디아블로'와 '배틀그라운드' 게임을 따라 만들어 보며, 프로그래머 면접에 나오는 핵심 개념까지 모두 잡아 보세요!

www.fastcampus.co.kr

 

+ Recent posts