안녕하세요. 인텔리원스튜디오(IntelliOneStudio)입니다.
오늘은 ChatGPT를 활용하여 Unity 플랫포머 게임에서 적 캐릭터에 생명력(헬스) 시스템을 구현해볼께요.
[오늘의 목표] Unity 플랫포머 게임에서 적 캐릭터에 생명력(헬스) 시스템을 구현
1. Health 스크립트 살펴보기
2. 적 캐릭터에 생명력(헬스) 스크립트 적용
3. 실행 결과 살펴 보기
※ ChatGPT 답변 내용 중 제가 별도로 표시한 파란색 내용을 기준으로 읽으시면 좀 더 이해가 쉽게 될거예요.
Health 스크립트 살펴보기
적 캐릭터에 생명력(헬스)를 추가하기 전에 Health 스크립트를 살펴봐요.
[질문] 안녕 ChatGPT, 다음의 코드를 설명해줄래?
using System; using Platformer.Gameplay; using UnityEngine; using static Platformer.Core.Simulation; namespace Platformer.Mechanics { /// <summary> /// Represebts the current vital statistics of some game entity. /// </summary> public class Health : MonoBehaviour { /// <summary> /// The maximum hit points for the entity. /// </summary> public int maxHP = 1; /// <summary> /// Indicates if the entity should be considered 'alive'. /// </summary> public bool IsAlive => currentHP > 0; int currentHP; /// <summary> /// Increment the HP of the entity. /// </summary> public void Increment() { currentHP = Mathf.Clamp(currentHP + 1, 0, maxHP); } /// <summary> /// Decrement the HP of the entity. Will trigger a HealthIsZero event when /// current HP reaches 0. /// </summary> public void Decrement() { currentHP = Mathf.Clamp(currentHP - 1, 0, maxHP); if (currentHP == 0) { var ev = Schedule<HealthIsZero>(); ev.health = this; } } /// <summary> /// Decrement the HP of the entitiy until HP reaches 0. /// </summary> public void Die() { while (currentHP > 0) Decrement(); } void Awake() { currentHP = maxHP; } } }
[답변]
이 스크립트는 게임 개발을 위한 C# 코드로 Unity 엔진에서 사용됩니다. 여기서는 특정 게임 엔티티(캐릭터 또는 오브젝트)의 생명력(Health)을 관리하는 컴포넌트를 정의하고 있습니다. 스크립트의 주요 구성 요소와 기능을 아래와 같이 설명할 수 있습니다:
- 네임스페이스 및 사용하는 라이브러리:
- System, Platformer.Gameplay, UnityEngine, Platformer.Core.Simulation 네임스페이스를 사용합니다. 이는 기본 시스템 기능, 게임 특정 로직, 유니티 엔진 기능, 그리고 게임 시뮬레이션을 위한 코어 기능을 제공합니다.
- Health 클래스:
- MonoBehaviour를 상속받아 유니티의 컴포넌트 시스템과 연동될 수 있게 합니다.
- 이 클래스는 게임 엔티티의 생명력을 나타내며, 이를 위한 변수와 메소드를 포함합니다.
- 변수 설명:
- maxHP: 엔티티의 최대 생명력을 정의합니다. 기본값은 1입니다.
- currentHP: 현재 생명력을 나타내며, 게임 내에서 조절됩니다.
- IsAlive: 현재 생명력(currentHP)이 0보다 클 경우에 true를 반환하여 엔티티가 살아있음을 나타냅니다.
- 메소드 설명:
- Increment(): 생명력을 1 증가시키되, Mathf.Clamp 함수를 사용하여 생명력이 maxHP를 초과하지 않도록 합니다.
- Decrement(): 생명력을 1 감소시키되, Mathf.Clamp 함수를 사용하여 생명력이 0 이하로 떨어지지 않도록 합니다. 만약 생명력이 0이 되면, HealthIsZero 이벤트를 스케줄링하여 처리합니다.
- Die(): Decrement() 메소드를 반복 호출하여 생명력이 0이 될 때까지 감소시킵니다.
- 이벤트 처리:
- HealthIsZero 이벤트는 생명력이 0이 되었을 때 발동되며, 이벤트 스케줄링을 통해 게임 내 다른 시스템이 이 상태를 감지하고 반응할 수 있습니다.
- 생명력 초기화:
- Awake() 메소드에서 게임 오브젝트가 생성될 때 currentHP를 maxHP로 초기화합니다. 이는 유니티 생명주기의 일부로, 오브젝트가 활성화되기 전에 호출됩니다.
이 클래스는 게임 내에서 엔티티의 생명력을 효과적으로 관리하고, 상태 변화에 따른 이벤트를 처리할 수 있도록 설계되어 게임의 다이내믹한 상호작용과 규칙을 지원합니다.
스크립트 내에서 HealthIsZero 일 경우 이벤트가 추가로 발생하는데,
이 부분도 확인이 필요해요.
using Platformer.Core;
using Platformer.Mechanics;
using static Platformer.Core.Simulation;
namespace Platformer.Gameplay
{
/// <summary>
/// Fired when the player health reaches 0. This usually would result in a
/// PlayerDeath event.
/// </summary>
/// <typeparam name="HealthIsZero"></typeparam>
public class HealthIsZero : Simulation.Event<HealthIsZero>
{
public Health health;
public override void Execute()
{
Schedule<PlayerDeath>();
}
}
}
HealthIsZero 일 경우 PlayerDeath 처리만 해요
제공된 소스 코드는 플레이어만 처리를 하고 있어서 적 캐릭터도 처리할 수 있도록 수정해요.
using Platformer.Core;
using Platformer.Mechanics;
using static Platformer.Core.Simulation;
namespace Platformer.Gameplay
{
/// <summary>
/// Fired when the player health reaches 0. This usually would result in a
/// PlayerDeath event.
/// </summary>
/// <typeparam name="HealthIsZero"></typeparam>
public class HealthIsZero : Simulation.Event<HealthIsZero>
{
public Health health;
public override void Execute()
{
// 플레이어의 경우
if (health.gameObject.CompareTag("Player"))
{
Schedule<PlayerDeath>();
}
// 적의 경우
else if (health.gameObject.CompareTag("Enemy"))
{
Schedule<EnemyDeath>().enemy = health.GetComponent<EnemyController>();
}
}
}
}
적 캐릭터에 헬스 적용에 필요한 스크립트 개발은 끝났어요.
위 스크립트는 아래와 같이 챗GPT가 만들었어요.
[질문] 안녕 ChatGPT, HealthIsZero 는 현재 Player 에 대해서만 작용을 하는구나.적 캐릭터에게도 적용될 수 있게 수정해줘
[답변]
네, 맞습니다. 현재 HealthIsZero 이벤트가 주로 플레이어에 대해서만 반응하도록 구성된 것 같습니다. 이 이벤트가 플레이어의 체력이 0이 되었을 때 실행되어 플레이어의 사망 처리를 담당하고 있습니다. 만약 이 로직이 적에게도 똑같이 적용되어서는 안 되는 경우, 이벤트가 특정 엔티티의 체력 상태에 따라 다르게 작동하도록 구분해 주어야 합니다.
즉, HealthIsZero 이벤트를 다시 살펴보면, 이 이벤트는 플레이어 뿐만 아니라 다른 엔티티(예: 적)의 체력이 0이 될 때도 호출되고 있어서 의도하지 않은 플레이어 사망 이벤트가 발생할 수 있습니다. 따라서, 이 이벤트를 수정하여 엔티티가 플레이어인지 적인지를 구분하여 각각 다르게 처리하도록 변경할 필요가 있습니다.
수정 제안
HealthIsZero 이벤트 내에서 발생한 엔티티가 플레이어인지 적인지에 따라 다른 이벤트를 스케줄링하도록 로직을 추가할 수 있습니다. 예를 들어:
public override void Execute() { // 플레이어의 경우 if (health.gameObject.CompareTag("Player")) { Schedule<PlayerDeath>(); } // 적의 경우 else if (health.gameObject.CompareTag("Enemy")) { Schedule<EnemyDeath>().enemy = health.GetComponent<EnemyController>(); } }
이와 같이 수정하면 각 엔티티의 체력이 0이 될 때 적절한 처리를 할 수 있게 되어, 적이 죽었을 때 플레이어도 함께 죽는 문제를 방지할 수 있습니다. 이러한 구분은 게임의 로직을 더 명확하게 하고, 버그 발생 가능성을 줄이는 데 도움이 됩니다.
앗 그리고 EnemyController 에 Health 변수를 꼭 추가해야해요.
using System.Collections;
using System.Collections.Generic;
using Platformer.Gameplay;
using UnityEngine;
using static Platformer.Core.Simulation;
namespace Platformer.Mechanics
{
/// <summary>
/// A simple controller for enemies. Provides movement control over a patrol path.
/// </summary>
[RequireComponent(typeof(AnimationController), typeof(Collider2D))]
public class EnemyController : MonoBehaviour
{
public PatrolPath path;
public AudioClip ouch;
internal PatrolPath.Mover mover;
internal AnimationController control;
internal Collider2D _collider;
internal AudioSource _audio;
SpriteRenderer spriteRenderer;
public Bounds Bounds => _collider.bounds;
public Health health;
void Awake()
{
health = GetComponent<Health>();
control = GetComponent<AnimationController>();
_collider = GetComponent<Collider2D>();
_audio = GetComponent<AudioSource>();
spriteRenderer = GetComponent<SpriteRenderer>();
}
void OnCollisionEnter2D(Collision2D collision)
{
var player = collision.gameObject.GetComponent<PlayerController>();
if (player != null)
{
var ev = Schedule<PlayerEnemyCollision>();
ev.player = player;
ev.enemy = this;
}
}
void Update()
{
if (path != null)
{
if (mover == null) mover = path.CreateMover(control.maxSpeed * 0.5f);
control.move.x = Mathf.Clamp(mover.Position.x - transform.position.x, -1, 1);
}
}
}
}
적 캐릭터에 헬스 적용하기
아래 그림처럼 적 캐릭터에 스크립트를 적용하고 적의 Max HP를 4로 조정을 해요.
이제 실행 결과를 살펴볼께요.
영상을 보면 플레이어가 4번 공격을 하면 적 캐릭터가 죽는 걸 볼 수 있어요.
오늘은 ChatGPT를 활용하여 Unity 플랫포머 게임에서 적 캐릭터에 생명력(헬스) 시스템을 구현했어요.
지금까지,
언제나 성장하는 인텔리원스튜디오(IntelliOneStudio)입니다.
감사합니다.
'디지털노마드' 카테고리의 다른 글
[문제해결] 구조화된 데이터 문제 'query-input' 입력란 누락 문제 해결 (69) | 2024.05.14 |
---|---|
[챗GPT 업데이트] 새로운 다재다능 AI, GPT-4o (“o”는 “omni”) (72) | 2024.05.14 |
[챗GPT게임개발23] ChatGPT를 활용하여 적 공격 처리 추가하기(3) (55) | 2024.05.12 |
[챗GPT게임개발22] ChatGPT를 활용하여 적 공격 처리 추가하기(2) (63) | 2024.05.12 |
[챗GPT게임개발21] ChatGPT를 활용하여 적 공격 처리 추가하기(1) (71) | 2024.05.11 |