본문 바로가기
디지털노마드

[챗GPT게임개발24] ChatGPT를 활용하여 적 캐릭터에 생명력(헬스) 추가

by 인텔리노마드라이프 2024. 5. 13.
728x90

안녕하세요. 인텔리원스튜디오(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)을 관리하는 컴포넌트를 정의하고 있습니다. 스크립트의 주요 구성 요소와 기능을 아래와 같이 설명할 수 있습니다:

  1. 네임스페이스 및 사용하는 라이브러리:
    • System, Platformer.Gameplay, UnityEngine, Platformer.Core.Simulation 네임스페이스를 사용합니다. 이는 기본 시스템 기능, 게임 특정 로직, 유니티 엔진 기능, 그리고 게임 시뮬레이션을 위한 코어 기능을 제공합니다.
  2. Health 클래스:
    • MonoBehaviour를 상속받아 유니티의 컴포넌트 시스템과 연동될 수 있게 합니다.
    • 이 클래스는 게임 엔티티의 생명력을 나타내며, 이를 위한 변수와 메소드를 포함합니다.
  3. 변수 설명:
    • maxHP: 엔티티의 최대 생명력을 정의합니다. 기본값은 1입니다.
    • currentHP: 현재 생명력을 나타내며, 게임 내에서 조절됩니다.
    • IsAlive: 현재 생명력(currentHP)이 0보다 클 경우에 true를 반환하여 엔티티가 살아있음을 나타냅니다.
  4. 메소드 설명:
    • Increment(): 생명력을 1 증가시키되, Mathf.Clamp 함수를 사용하여 생명력이 maxHP를 초과하지 않도록 합니다.
    • Decrement(): 생명력을 1 감소시키되, Mathf.Clamp 함수를 사용하여 생명력이 0 이하로 떨어지지 않도록 합니다. 만약 생명력이 0이 되면, HealthIsZero 이벤트를 스케줄링하여 처리합니다.
    • Die(): Decrement() 메소드를 반복 호출하여 생명력이 0이 될 때까지 감소시킵니다.
  5. 이벤트 처리:
    • HealthIsZero 이벤트는 생명력이 0이 되었을 때 발동되며, 이벤트 스케줄링을 통해 게임 내 다른 시스템이 이 상태를 감지하고 반응할 수 있습니다.
  6. 생명력 초기화:
    • 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 플랫포머 게임에서 적 캐릭터에 생명력(헬스) 시스템을 구현했어요.

 

[테니스 연습 중인 인텔리원스튜디오 개발자. 인텔리노마드라이프와 함께 행복하세요 from IntelliOneStudio ]

 

 

지금까지,

언제나 성장하는 인텔리원스튜디오(IntelliOneStudio)입니다.

감사합니다.

728x90