Notice
Recent Posts
Recent Comments
Link
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Archives
Today
Total
관리 메뉴

moonee-e3 님의 블로그

2024-05-28 시야각에 들어오면 죽이는 적 구현 본문

개발 일지 [3D | Dream Forest]

2024-05-28 시야각에 들어오면 죽이는 적 구현

moonee-e3 2024. 6. 21. 00:34

최종 코드 (BlueEnemy)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BlueEnemy : MonoBehaviour
{
    // 참고 링크 https://nicotina04.tistory.com/197

    // 시야 영역의 반지름과 시야 각도 조절하는 코드
    public float viewRadius; // 시야 범위
    [Range(0, 360)]
    public float viewAngle; // 시야 각도
    public GameObject HitCircle; // 범위 나타내는 오브젝트

    // 마스크 2종 //타켓과 오브젝트
    public LayerMask targetMask, obstacleMask; // 타켓과 장애물을 나눔

    // Target mask에 ray hit된 transform을 보관하는 리스트
    public List<Transform> visibleTargets = new List<Transform>();

    void Start()
    {
        StartCoroutine(HitPoint());
        StartCoroutine(HitTimeCheck());
    }

    bool IsHit = true; 

    IEnumerator HitPoint()
    {
        while (true)
        {
            while (IsHit)
            {
                FindVisibleTargets();
                yield return null;
            }
           
            // 비활성화
            HitCircle.gameObject.SetActive(false);

            // 3초 동안 대기
            yield return new WaitForSeconds(3f);
            IsHit = true;
        }
    }

    IEnumerator HitTimeCheck()
    {
        while (true)
        {
            if (IsHit)
            {
                yield return new WaitForSeconds(3f);
                IsHit = false;
            }
            yield return null;
        }
    }

    void FindVisibleTargets()
    {
        HitCircle.gameObject.SetActive(true); // 공격 범위 나타냄
        visibleTargets.Clear(); // 타겟값 초기화
        // viewRadius를 반지름으로 한 원 영역 내 targetMask 레이어인 콜라이더를 모두 가져옴
        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;

            // 플레이어와 forward와 target이 이루는 각이 설정한 각도 내라면
            if (Vector3.Angle(transform.forward, dirToTarget) < viewAngle / 2)
            {
                float dstToTarget = Vector3.Distance(transform.position, target.transform.position);

                // 타겟으로 가는 레이캐스트에 obstacleMask가 걸리지 않으면 visibleTargets에 Add
                if (!Physics.Raycast(transform.position, dirToTarget, dstToTarget, obstacleMask))
                {
                    
                    visibleTargets.Add(target); // 타켓에 추가
                    Player.Die(); // 타켓이 플레이어 밖에 없어서 Player.die() 실행 Player말고 다른 오브제가 있다면 if문 걸어주기
                    StopCoroutine("HitPoint");
                    StopCoroutine("HitTimeCheck");
                }
            }
        }
    }

    // y축 오일러 각을 3차원 방향 벡터로 변환한다.
    // 원본과 구현이 살짝 다름에 주의. 결과는 같다.
    public Vector3 DirFromAngle(float angleDegrees, bool angleIsGlobal)
    {
        if (!angleIsGlobal)
        {
            angleDegrees += transform.eulerAngles.y;
        }

        return new Vector3(Mathf.Cos((-angleDegrees + 90) * Mathf.Deg2Rad), 0, Mathf.Sin((-angleDegrees + 90) * Mathf.Deg2Rad));
    }

    private void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.CompareTag("Player"))
        {
            Player.Die();
        }
    }
}

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(Enemy2))]
public class EnemyView : Editor
{
    void OnSceneGUI()
    {
        Enemy2 fow = (Enemy2)target;
        Handles.color = Color.white;
        Handles.DrawWireArc(fow.transform.position, Vector3.up, Vector3.forward, 360, fow.viewRadius);
        Vector3 viewAngleA = fow.DirFromAngle(-fow.viewAngle / 2, false);
        Vector3 viewAngleB = fow.DirFromAngle(fow.viewAngle / 2, false);

        Handles.DrawLine(fow.transform.position, fow.transform.position + viewAngleA * fow.viewRadius);
        Handles.DrawLine(fow.transform.position, fow.transform.position + viewAngleB * fow.viewRadius);

        Handles.color = Color.red;
        foreach (Transform visible in fow.visibleTargets)
        {
            Handles.DrawLine(fow.transform.position, visible.transform.position);
        }
    }
}

 

Editor를 활용해 유니티에서 범위가 보이게 함

Editor 파일에 넣어야 빌드할 때 오류 안남!


2024-05-28 시야 각에 들어오면 죽이는 적 구현

 

시야 각에 들어오면 죽이는 적

2024-05-29 코루틴을 추가해서 3초마다 감지하게 했지만 켜진 직후에만 감지하고 감지를 못함

켜진 직후에만 감지하는 적

2024-05-30 IsHit과 IsHitTime 코루틴을 추가해서 오류 수정

인게임 속 BlueEnemy

 

참고 코드 : https://nicotina04.tistory.com/197