게임 개발에서 적 AI(인공지능)는 게임의 도전성과 몰입감을 높이는 중요한 요소입니다. 이 강좌에서는 유니티 2D 게임에서 적 캐릭터의 간단한 AI를 구현하고, 이를 통해 추적 및 공격 행동을 설정하는 방법에 대해 자세히 설명하겠습니다. 이 강좌는 초보자부터 중급 개발자에게 유용하며, 실습을 통해 이해를 돕고자 합니다.
1. 프로젝트 설정하기
먼저, Unity에서 2D 프로젝트를 새로 생성합니다. 프로젝트 이름을 “EnemyAIExample”로 정하고 설정을 완료합니다. 기본적으로 필요한 2D 템플릿을 선택하십시오.
1.1 초기 설정
프로젝트가 생성되면, 2D 스프라이트를 이용해 맵과 플레이어 캐릭터, 적 캐릭터를 생성합니다. 사용할 스프라이트를 적절히 임포트하여 Assets 폴더에 저장합니다.
1.2 플레이어와 적 캐릭터 배치
씬에 간단한 맵을 만들고, 플레이어와 적 캐릭터의 스프라이트를 배치합니다. 이때, 플레이어는 “Player”, 적 캐릭터는 “Enemy”라는 이름으로 설정합니다.
2. 적 AI 기초 이해하기
적 AI는 크게 두 가지 행동으로 나눌 수 있습니다: 추적(Chasing)과 공격(Attacking)입니다. 추적은 적이 플레이어를 감지하고 따라가는 동작을 포함하며, 공격은 가까이 다가온 플레이어에게 공격하는 동작을 포함합니다.
2.1 AI 상태 관리
AI 행동을 관리하기 위해 상태를 정의하는 것이 중요합니다. 다음과 같은 상태를 정의합니다:
- Idle: 대기 상태
- Chase: 플레이어를 추적하는 상태
- Attack: 플레이어에게 공격하는 상태
3. 적 캐릭터 스크립트 작성하기
우리는 C# 스크립트를 생성하여 적 캐릭터에 대한 AI 논리를 구현합니다. EnemyAI.cs라는 이름의 스크립트를 생성하여 다음과 같은 코드를 작성합니다.
using UnityEngine;
public class EnemyAI : MonoBehaviour {
public float moveSpeed = 2f; // 적의 이동 속도
public float chaseRange = 5f; // 추적 범위
public float attackRange = 1f; // 공격 범위
private Transform player; // 플레이어의 Transform
private Rigidbody2D rb; // 적 캐릭터의 Rigidbody2D
private enum State { Idle, Chase, Attack } // 적 AI의 상태
private State currentState = State.Idle; // 초기 상태
void Start() {
player = GameObject.FindWithTag("Player").transform; // 플레이어 찾기
rb = GetComponent<Rigidbody2D>(); // Rigidbody2D 컴포넌트 가져오기
}
void Update() {
// 상태에 따라 행동
switch (currentState) {
case State.Idle:
IdleBehavior();
break;
case State.Chase:
ChaseBehavior();
break;
case State.Attack:
AttackBehavior();
break;
}
}
private void IdleBehavior() {
// 플레이어와의 거리를 계산
float distance = Vector2.Distance(transform.position, player.position);
if (distance < chaseRange) {
currentState = State.Chase; // 추적 상태로 전환
}
}
private void ChaseBehavior() {
float distance = Vector2.Distance(transform.position, player.position);
// 플레이어에게 접근
if (distance > attackRange) {
Vector2 direction = (player.position - transform.position).normalized;
rb.MovePosition(rb.position + direction * moveSpeed * Time.deltaTime);
} else {
currentState = State.Attack; // 공격 상태로 전환
}
if (distance > chaseRange) {
currentState = State.Idle; // 대기 상태로 전환
}
}
private void AttackBehavior() {
// 공격 로직 구현
// 여기에 플레이어에게 피해를 주는 코드를 추가할 수 있습니다
Debug.Log("Attacking the player!");
currentState = State.Idle; // 기본적으로 대기 상태로 돌아가기
}
}
4. 적 캐릭터의 AI 논리 설명
위 코드에서 주요 기능들을 하나씩 설명하겠습니다.
4.1 상태 관리
상태는 enum State
를 사용하여 관리하며, 현재 상태는 currentState
변수로 정의됩니다. 유니티의 Update
메소드에서 현재 상태에 따른 행동을 결정합니다.
4.2 플레이어 추적하기
플레이어와의 거리 계산을 통해 상태를 전환합니다. IdleBehavior()
에서 플레이어와의 거리를 측정하고, ChaseBehavior()
로 상태 전환을 결정합니다.
4.3 공격 구현
적이 플레이어에게 접근하면 공격 상태로 전환되어 AttackBehavior()
가 실행됩니다. 이 상태에서 플레이어에게 데미지를 주는 로직을 추가할 수 있습니다. 통상적으로 최근에 추가된 공격 애니메이션이나 이펙트를 실행합니다.
5. 적 캐릭터 위치 설정
적 캐릭터가 씬에 배치된 후, 적의 Rigidbody2D
컴포넌트의 Gravity Scale
값을 0으로 설정하여 중력의 영향을 받지 않도록 합니다. 적이 이동할 수 있으며, 레이어를 설정하여 플레이어와 충돌하지 않도록 조정할 수 있습니다.
6. 코드 최적화 및 확장
위의 기본 코드에서 더 많은 기능을 추가하고 싶을 경우, 여러 방법으로 가능하지만 기본적인 AI 패턴 및 행동 로직을 더욱 발전시킬 수 있습니다. 예를 들어, 공격 주기를 설정하여 지속적으로 공격하지 않도록 하거나, 각 상태에 대한 애니메이션을 적용할 수 있습니다.
6.1 공격 주기 설정
private float attackCooldown = 1f; // 공격 쿨다운 타이머
private float lastAttackTime = 0f;
private void AttackBehavior() {
float distance = Vector2.Distance(transform.position, player.position);
if (distance < attackRange && Time.time - lastAttackTime > attackCooldown) {
Debug.Log("Attacking the player!");
// 여기에 플레이어에게 피해를 주는 코드를 추가할 수 있습니다
lastAttackTime = Time.time; // 마지막 공격 시간 업데이트
} else {
currentState = State.Idle; // 기본적으로 대기 상태로 돌아가기
}
}
6.2 애니메이션 추가
유니티의 애니메이션 시스템을 사용하여 적이 추적하고 공격할 때 적절한 애니메이션을 재생할 수 있습니다. 애니메이터 컴포넌트를 적 캐릭터에 추가하고, 각 상태에 대한 애니메이션을 만들어 설정합니다. 상태 전환에 따라 알맞은 애니메이션 트리거를 호출할 수 있는 코드를 추가합니다.
7. 결론
이번 강좌에서는 유니티를 사용하여 간단한 적 AI를 구현하는 방법에 대해 알아보았습니다. 적 캐릭터가 플레이어를 추적하고 공격하는 기본 동작을 만들었습니다. 이 기초를 바탕으로 더 다양한 AI 행동을 설계하고 게임에 적용할 수 있습니다. AI를 통해 더 많은 도전과 흥미를 더하는 것이 가능하므로 여러분의 창의력을 발휘해 보시기 바랍니다!
8. 추가 자료
감사합니다! 이 강좌가 도움이 되기를 바라며, 여러분의 게임 개발 여정에 많은 성공이 있기를 기원합니다.