2023. 11. 29. 21:18ㆍUnity
HDRI 적용
적절한 HDRI를 찾아서 적용한다.
적용 전과 적용 후. 해가 지는 느낌을 표현하기 위해 그에 맞는 HDRI를 선정하였다.
HDRI를 적용해도 Game Scene에서는 적용한 HDRI가 보이지 않는데, 이럴 경우 카메라 Inspector를 확인하면 된다.
[Camera] - [Clear Flags] - [Solid Color]를 [Skybox]로 바꾼다.
적 구현하기
적이 생성되고, 2초 뒤에 타워를 향해서 움직이고(AI 사용) 일정 거리 안쪽으로 들어오면 타워를 공격하게 만든다.
AI가 장애물을 알아서 피하가게 만들 예정. 적을 배치할 때 평지에 배치하는 것이 좋다.
적이 될 비행기를 씬에 배치한다.
EnemyAI 스크립트 생성
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyAI : MonoBehaviour
{
//상태 상수 정의
enum EnemyState
{
Idle, Move, Attack, Damage, Die
}
//초기 시작 상태 설정
EnemyState state = EnemyState.Idle;
//대기 지속 시간
public float idleDelayTime = 2f;
//경과 시간
float currentTime = 0;
void Start()
{
}
void Update()
{
switch (state)
{
case EnemyState.Idle:
Idle();
break;
}
}
void Idle()
{
//시간의 경과
currentTime += Time.deltaTime;
if(currentTime > idleDelayTime)
{
//일정 시간 이상 지나면 이동 상태로 전환
state = EnemyState.Move;
print("이동 상태");
}
}
}
AINavMeshAgent 사용
맵 요소를 모두 모아놨던 Environment 그룹을 누르고 우측 상단의 [Static] 적용을 한다.
NavMesh를 사용하기 위해 [Package Manager] - [AI Navigation]을 설치한다.
[Window] - [AI] - [Navigation (Obsolete)] 선택
[Bake]를 하면, 씬에 갈 수 있는 부분이 파랗게 표시된다.
Enemy에 [Nav Mesh Agent] 컴포넌트를 추가한다.
EnemyAI 스크립트 수정
NavMesh 적용하기
네임스페이스 추가
using UnityEngine.AI;
변수 3개 추가
//이동 속도
public float moveSpeed = 5f;
//타워 위치
Transform tower;
//네비게이션 메시 에이전트 가져오기
NavMeshAgent agent;
Start 함수에 변수 초기화 등
void Start()
{
//타워를 이름으로 가져오기
tower = GameObject.Find("TowerObject").transform;
agent = GetComponent<NavMeshAgent>();
//처음 상태에서는 비활성화 되어야한다.
agent.enabled = false;
agent.speed = moveSpeed;
}
EnemyState.Move 상태 추가, Movement() 함수 추가
void Update()
{
switch (state)
{
case EnemyState.Idle:
Idle();
break;
case EnemyState.Move:
Movement();
break;
}
}
void Movement()
{
agent.SetDestination(tower.position);
}
Idle() 함수에서 agent.enabled = true; 활성화
void Idle()
{
//시간의 경과
currentTime += Time.deltaTime;
if(currentTime > idleDelayTime)
{
//일정 시간 이상 지나면 이동 상태로 전환
state = EnemyState.Move;
print("이동 상태");
//에이전트 활성화
agent.enabled = true;
}
}
현재까지 EnemyAI 전체 코드
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class EnemyAI : MonoBehaviour
{
//상태 상수 정의
enum EnemyState
{
Idle, Move, Attack, Damage, Die
}
//초기 시작 상태 설정
EnemyState state = EnemyState.Idle;
//대기 지속 시간
public float idleDelayTime = 2f;
//경과 시간
float currentTime = 0;
//이동 속도
public float moveSpeed = 5f;
//타워 위치
Transform tower;
//네비게이션 메시 에이전트 가져오기
NavMeshAgent agent;
void Start()
{
//타워를 이름으로 가져오기
tower = GameObject.Find("TowerObject").transform;
agent = GetComponent<NavMeshAgent>();
//처음 상태에서는 비활성화 되어야한다.
agent.enabled = false;
agent.speed = moveSpeed;
}
void Update()
{
switch (state)
{
case EnemyState.Idle:
Idle();
break;
case EnemyState.Move:
Movement();
break;
}
}
void Idle()
{
//시간의 경과
currentTime += Time.deltaTime;
if(currentTime > idleDelayTime)
{
//일정 시간 이상 지나면 이동 상태로 전환
state = EnemyState.Move;
print("이동 상태");
//에이전트 활성화
agent.enabled = true;
}
}
void Movement()
{
agent.SetDestination(tower.position);
}
}
타워 쪽으로 자동으로 움직이는 것을 볼 수 있다.(신기방기)
적이 일정 거리 안으로 왔을 때 공격 상태로 전환
EnemyAI 스크립트 수정
변수 선언
//공격 범위
public float attackRange = 30f;
Movement() 함수 수정
void Movement()
{
agent.SetDestination(tower.position);
//공격 범위 안에 들어오면 공격 상태로 전환
if(Vector3.Distance(transform.position, tower.position) < attackRange)
{
state = EnemyState.Attack;
//공격 상태일 때는 NavMesh 비활성화
agent.enabled = false;
}
}
현재까지 EnemyAI 전체 스크립트
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class EnemyAI : MonoBehaviour
{
//상태 상수 정의
enum EnemyState
{
Idle, Move, Attack, Damage, Die
}
//초기 시작 상태 설정
EnemyState state = EnemyState.Idle;
//대기 지속 시간
public float idleDelayTime = 2f;
//경과 시간
float currentTime = 0;
//이동 속도
public float moveSpeed = 5f;
//타워 위치
Transform tower;
//네비게이션 메시 에이전트 가져오기
NavMeshAgent agent;
//공격 범위
public float attackRange = 30f;
void Start()
{
//타워를 이름으로 가져오기
tower = GameObject.Find("TowerObject").transform;
agent = GetComponent<NavMeshAgent>();
//처음 상태에서는 비활성화 되어야한다.
agent.enabled = false;
agent.speed = moveSpeed;
}
void Update()
{
switch (state)
{
case EnemyState.Idle:
Idle();
break;
case EnemyState.Move:
Movement();
break;
}
}
void Idle()
{
//시간의 경과
currentTime += Time.deltaTime;
if(currentTime > idleDelayTime)
{
//일정 시간 이상 지나면 이동 상태로 전환
state = EnemyState.Move;
print("이동 상태");
//에이전트 활성화
agent.enabled = true;
}
}
void Movement()
{
agent.SetDestination(tower.position);
//공격 범위 안에 들어오면 공격 상태로 전환
if(Vector3.Distance(transform.position, tower.position) < attackRange)
{
state = EnemyState.Attack;
//공격 상태일 때는 NavMesh 비활성화
agent.enabled = false;
}
}
}
타워 앞에서 멈춘다.
공격 상태로 전환된 적이 공격
공격에 2초 정도 지연 시간을 준다.
변수 선언
//공격 지연 시간
public float attackDelayTime = 2f;
EnemyState.Attack 공격 상태 추가
void Update()
{
switch (state)
{
case EnemyState.Idle:
Idle();
break;
case EnemyState.Move:
Movement();
break;
case EnemyState.Attack:
Attack();
break;
}
}
Attack() 함수 추가
void Attack()
{
currentTime += Time.deltaTime;
if(currentTime > attackDelayTime)
{
Debug.Log("공격!");
currentTime = 0;
}
}
현재는 적이 공격 범위에 들어오자마자 공격한다. Idle() 함수에서 currentTime을 0으로 초기화 했으면 공격 범위에 들어온 후 2초 뒤에 공격한다.
현재까지 EnemyAI 스크립트 전체 코드
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class EnemyAI : MonoBehaviour
{
//상태 상수 정의
enum EnemyState
{
Idle, Move, Attack, Damage, Die
}
//초기 시작 상태 설정
EnemyState state = EnemyState.Idle;
//대기 지속 시간
public float idleDelayTime = 2f;
//경과 시간
float currentTime = 0;
//이동 속도
public float moveSpeed = 5f;
//타워 위치
Transform tower;
//네비게이션 메시 에이전트 가져오기
NavMeshAgent agent;
//공격 범위
public float attackRange = 30f;
//공격 지연 시간
public float attackDelayTime = 2f;
void Start()
{
//타워를 이름으로 가져오기
tower = GameObject.Find("TowerObject").transform;
agent = GetComponent<NavMeshAgent>();
//처음 상태에서는 비활성화 되어야한다.
agent.enabled = false;
agent.speed = moveSpeed;
}
void Update()
{
switch (state)
{
case EnemyState.Idle:
Idle();
break;
case EnemyState.Move:
Movement();
break;
case EnemyState.Attack:
Attack();
break;
}
}
void Idle()
{
//시간의 경과
currentTime += Time.deltaTime;
if(currentTime > idleDelayTime)
{
//일정 시간 이상 지나면 이동 상태로 전환
state = EnemyState.Move;
print("이동 상태");
//에이전트 활성화
agent.enabled = true;
}
}
void Movement()
{
agent.SetDestination(tower.position);
//공격 범위 안에 들어오면 공격 상태로 전환
if(Vector3.Distance(transform.position, tower.position) < attackRange)
{
state = EnemyState.Attack;
//공격 상태일 때는 NavMesh 비활성화
agent.enabled = false;
}
}
void Attack()
{
currentTime += Time.deltaTime;
if(currentTime > attackDelayTime)
{
Debug.Log("공격!");
currentTime = 0;
}
}
}
'Unity' 카테고리의 다른 글
[XR 전문 인력 과정] 유니티 타워디펜스 만들기(4) -적 공격하기, 적 폭발, 적 생성 (0) | 2023.12.11 |
---|---|
[Unity] 던전앤파이터 API 활용 -진행중 (3) | 2023.12.07 |
[XR 전문 인력 과정] 유니티 타워디펜스 만들기(2) -총쏘기(Raycast), 무기 잡기, 무기 던지기 (0) | 2023.11.23 |
[XR 전문 인력 과정] 유니티 타워디펜스 만들기(1) -XR 세팅, 씬 세팅, 화면 회전, 플레이어 이동 (1) | 2023.11.22 |
[Unity Project] <ShootOut2D> 2D 슈팅 게임 만들기(15) 화면 해상도 고려하기 (0) | 2023.09.25 |