내일배움캠프 TIL 33일차 - Ai navigation

권태하·2024년 5월 31일
post-thumbnail

Ai Navigation 강의 코드 정리

    void AttackingUpdate()
    {
        if (playerDistance < attackDistance && IsPlayerInFieldOfView())
        {
            agent.isStopped = true;
            if (Time.time - lastAttackTime > attackRate)
            {
                lastAttackTime = Time.time;
                CharacterManager.Instance.Player.condition.GetComponent<IDamagable>().TakePhysicalDamage(damage);
                animator.speed = 1;
                animator.SetTrigger("Attack");
            }
        }
        else
        {
            if (playerDistance < detectDistance)
            {
                agent.isStopped = false;
                NavMeshPath path = new NavMeshPath();
                if (agent.CalculatePath(CharacterManager.Instance.Player.transform.position, path))
                // agent.CalculatePath(CharacterManager.Instance.Player.transform.position, path) : 주어진 위치까지의 경로를 계산하고 반환
                // path : 계산된 경로를 저장할 NavMeshPath 위쪽에서 변수 선언
                {
                    agent.SetDestination(CharacterManager.Instance.Player.transform.position);
                }
                else
                {
                    agent.SetDestination(transform.position);
                    agent.isStopped = true;
                    SetState(AIState.Wandering);
                }
            }
            else
            {
                agent.SetDestination(transform.position);
                agent.isStopped = true;
                SetState(AIState.Wandering);
            }
        }
    }


    void WanderToNewLocation()
    {
        if (aiState != AIState.Idle)
        {
            return;
        }
        SetState(AIState.Wandering);
        agent.SetDestination(GetWanderLocation());     // 목적지 설정(Vector3)를 이용
    }

    bool IsPlayerInFieldOfView()
    {
        Vector3 directionToPlayer = CharacterManager.Instance.Player.transform.position - transform.position;
        float angle = Vector3.Angle(transform.forward, directionToPlayer);
        //Vector3.Angle : 두 벡터 사이의 각도를 반환
        return angle < fieldOfView * 0.5f;
    }


    Vector3 GetWanderLocation()
    {
        NavMeshHit hit;

        NavMesh.SamplePosition(transform.position + (Random.onUnitSphere * Random.Range(minWanderDistance, maxWanderDistance)), out hit, maxWanderDistance, NavMesh.AllAreas);
        //아래와 같다
        //================================================================================================
        //public static bool SamplePosition(Vector3 sourcePosition, out NavMeshHit hit, float maxDistance, int areaMask)
        //{
        //    return SamplePosition_Injected(ref sourcePosition, out hit, maxDistance, areaMask);
        //}
        // sourcePosition : 샘플링을 시작할 위치, out hit : 샘플링된 위치, maxDistance : 샘플링할 최대 거리, areaMask : 샘플링할 영역
        //================================================================================================
        //Random.onUnitSphere : 반지름이 1인 구체의 표면 위의 임의의 점을 반환
        //navMesh.AllAreas : 모든 영역을 나타내는 상수
        //===

        int i = 0;
        while (Vector3.Distance(transform.position, hit.position) < detectDistance)
        {
            NavMesh.SamplePosition(transform.position + (Random.onUnitSphere * Random.Range(minWanderDistance, maxWanderDistance)), out hit, maxWanderDistance, NavMesh.AllAreas);
            i++;
            if (i == 30)
                break;
        }

        return hit.position;
    }
profile
스터디 로그

0개의 댓글