시야 내 타겟 자동 설정 - Field of VIew

Published: Jul 30, 2021 by BeatChoi

몬스터의 시야를 설정하고 타겟을 자동 설정해보기.

시야 :: Field of View

AI 캐릭터가 필요한 콘텐츠에서는 AI 캐릭터의 시야와 해당 캐릭터가 플레이어를 선택하는 조건등을 고민하게 됩니다.
Field of View를 AI 캐릭터에 설정하여 해당 캐릭터의 시야에 플레이어가 들어오게 되면 자동으로 타겟팅 할수 있도록 해봅니다.

유니티3D 에디터에서

스크립트 생성

먼저 fieldofview.cs 스크립트를 생성하고 다음과 같이 작성합니다.

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class fieldofview : MonoBehaviour
{

    public float viewArea;
    [Range(0,360)]
    public float viewAngle;

    public LayerMask targetMask;

    [HideInInspector]
    public List<Transform> Targets = new List<Transform>();

    // Update is called once per frame
    void Update()
    {
        GetTarget();
    }

    public void GetTarget()
    {
        Targets.Clear();
        Collider[] TargetCollider = Physics.OverlapSphere(transform.position, viewArea, targetMask);

        for(int i = 0; i < TargetCollider.Length; i++)
        {
            Transform target = TargetCollider[i].transform;
            Vector3 direction = target.position - transform.position;
            if(Vector3.Dot(direction.normalized, transform.forward) > GetAngle(viewAngle / 2).z)
            {
                Targets.Add(target);
            }
        }
    }

    public Vector3 GetAngle(float AngleInDegree)
    {
        return new Vector3(Mathf.Sin(AngleInDegree * Mathf.Deg2Rad), 0, Mathf.Cos(AngleInDegree * Mathf.Deg2Rad));
    }


    private void OnDrawGizmos()
    {
        Handles.DrawWireArc(transform.position, Vector3.up, transform.forward, 360, viewArea);
        Handles.DrawLine(transform.position, transform.position + GetAngle(-viewAngle / 2) * viewArea);
        Handles.DrawLine(transform.position, transform.position + GetAngle(viewAngle / 2) * viewArea);

        foreach(Transform Target in Targets)
        {
            Handles.DrawLine(transform.position, Target.position);
        }
    }
}
  • 상단부네임스페이스란에 UnityEditor 네임스페이스를 추가합니다. 씬 창에서 가상의 범위를 나타내주는 메소드를 호출할 수 있습니다.
  • ViewArea는 캐릭터를 중심으로 반지름 거리의 값을 나타냅니다.
  • ViewAngle은 캐릭터 정면의 시야 각도입니다.
    • 캐릭터의 반지름 거리에 있는 플레이어 중 캐릭터의 시야 각 내에 있는 플레이어를 타겟팅 할수 있도록 합니다.
  • GetTarget은 타겟을 선정하는 함수입니다.
    • Collider형의 배열 변수를 하나 선언한 뒤 OverlapSphere메소드로 캐릭터를 중심으로 한 가상의 원 반경 내의 충돌체들을 추출해 냅니다.
    • 반경 내 충돌체들 중 시야 각도 내에 있는 오브젝트들의 Transform값을 Targets리스트에 추가합니다.
  • GetAngle은 설정하는 시야각을 Vector3로 반환하는 역할을 합니다.
    • 해당 함수를 호출할 때 인자들을 2로 나누는 이유는 캐릭터를 중심으로 좌측으로 x도, 우측으로 x도, 두개의 각도의 합이 ViewAngle이기 때문입니다.
  • OnDrawGizmos함수는 기능적으로는 상관이 없는 함수입니다. 다만 씬 창에서 우리의 코드가 제대로 작동하는지 표현하기 위한 함수입니다.
  • UnityEditor를 통해 호출받은 Handles 클래스를 통해 캐릭터 주변 범위 및 시야각도를 선으로 표현합니다.
  • 씬 창에서만 보입니다.

프로젝트 생성 및 세팅

간단하게 Plane으로 바닥을 깔아주고 Capsule로 캐릭터, Cube로 타게팅 될 오브젝트를 생성합니다.


<01. 씬 배치>

먼저 타게팅 될 Cube 오브젝트를 선택합니다.
타게팅이 되기 위해서는 Mask Layer를 설정해줘야합니다.
Cube를 선택하고 인스펙터창 우측 상단 Layer 드롭다운버튼을 눌러서 Add Layer 버튼을 누릅니다.


<02. Mask Layer 설정>

인스펙터 창에서 비어있는 레이어 항목에 Target 레이어를 생성합니다.


<03. Mask Layer 생성>

돌아와서 다시 Cube오브젝트를 선택한 후 레이어를 Target으로 변경합니다.


<04. Mask Layer 변경>

Capsule오브젝트에 fieldofview.cs스크립트를 인스턴스화 시킵니다.
fieldofview컴포넌트에 ViewArea값과 ViewAngle값을 조정합니다.
TargetMask 항목은 아까 생성한 Target으로 설정합니다.


<05. Capsule 오브젝트 설정>

그럼 씬창은 이렇게 변합니다.


<06. 씬 창>

테스트 :: Test

상단 플레이 버튼을 눌러 Capsule 오브젝트를 이동시켜봅니다.
Cube의 범위 안, 밖으로 이동시켜 시야 내에 있을 때 서로를 잇는 흰 선이 생성되는지 확인합니다.


<07. 테스트>

정리

이번 포스팅에서는 하나의 객체의 시야 내에 있는 오브젝트를 타겟팅 하는 방법에 대하여 진행했습니다.
이는 몬스터 AI를 설정할 때 자주 활용되는 기법이며 플레이어의 타겟팅을 예로 들었지만 시야 범위 내에 어떠한 행위를 하기위한
범위 설정을 할수있는 광범위한 기법입니다.

Latest Posts

LightshipAR SDK 활용하기 - Maps SDK의 활용
LightshipAR SDK 활용하기 - Maps SDK의 활용

ARDK Maps SDK

Lightship의 geofencing 기능을 구현할 수 있는 Maps SDK 활용법을 알아봅니다.

콘텐츠 개발

프로젝트 세팅

본 포스팅은 ARDK 3.9 버전, Maps SDK 0.4 버전을 기준으로 작성합니다. 이전 포스팅을 참조하여 SDK를 임포트 합니다.

Top Down Map

  1. 네이버 지도같은 일반적인 탑-다운 맵을 구현해 봅니다.

Unity3D에서의 UI - Rect Transform
Unity3D에서의 UI - Rect Transform

Unity UI RectTransform :: 개요

UI 객체들의 위치, 크기, 기준점 등등을 담당하는 Rect Transform에 대하여 알아봅니다.

Unity3D에서의 UI - UI의 구성
Unity3D에서의 UI - UI의 구성

Unity UI :: 개요

Unity UI는 게임 및 애플리케이션용 사용자 인터페이스를 개발하는 데 쓰이는 간단한 UI 툴킷입니다. Unity UI는 게임 오브젝트 기반 UI 시스템으로, 컴포넌트와 게임 뷰를 사용하여 사용자 인터페이스를 배열하고 위치와 스타일을 지정합니다. Unity UI는 Unity 에디터 내 사용자 인터페이스에 대해 사용할 수 없습니다.https://docs.unity3d.com/kr/2019.1/Manual/UIToolkits.html