본문 바로가기
AI/AI활용

[ChatGPT][Unity] 간단한 게임 만들어보기 (4)

by OhEasy 2023. 4. 9.
728x90
 

[ChatGPT][Unity] 간단한 게임 만들어보기 (3)

[ChatGPT][Unity] 간단한 게임 만들어보기 (2) [ChatGPT][Unity] 간단한 게임 만들어보기 (1) [ChatGPT][연습] ChatGPT만 가지고 Unity 게임 만들어 보기 일단 엄청 오래걸려 만들어본 결과물 배배배뱀 - Google Play

525easy.tistory.com

이전 글에서 가장 가까운 적에게 총을 쏘는 것까지 구현을 하였다.


프롬프트 지니

기존 EnemySpawner의 경우
적이 생성 될 때 캐릭터와 매우 가까운 위치에
생성 되는 경우가 발생하고 있다.
그렇기 때문에 생성 범위를
원이 아닌 도넛형으로 바꿔달라는 요청을 해보았다.

void SpawnEnemy()
{
    float innerRadius = 1f;
    float outerRadius = 5f;
    float distance = Random.Range(innerRadius, outerRadius);
    float angle = Random.Range(0f, Mathf.PI * 2f);
    Vector2 direction = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle));
    Vector2 randomPosition = (Vector2)transform.position + direction * distance;
    GameObject enemy = Instantiate(enemyPrefab, randomPosition, Quaternion.identity);
    EnemyMovement enemyMovement = enemy.GetComponent<EnemyMovement>();
    if (enemyMovement != null)
    {
        enemyMovement.health = 3 + healthIncrement;
    }
}​

이런 코드를 받았다.

위 코드를 보면 in/out 반지름이
SpawnEnemy 함수 안에 들어있어서
범위를 바꾸어가며 테스트 하기 매우 불편하다.

변경 가능하게 요청

inspector에서 변경이 가능하도록 요청한다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemySpawner : MonoBehaviour
{
    public GameObject enemyPrefab;
    public float spawnRate = 2f;
    public float innerRadius = 0f;
    public float outerRadius = 5f;
    public int spawnCount = 1;

    private float nextSpawnTime = 0f;
    private int healthIncrement = 0;

    void Update()
    {
        if (Time.time >= nextSpawnTime)
        {
            for (int i = 0; i < spawnCount; i++)
            {
                SpawnEnemy();
            }
            healthIncrement++;
            nextSpawnTime = Time.time + spawnRate;
        }
    }

    void SpawnEnemy()
    {
        Vector2 randomPosition = (Vector2)transform.position + Random.insideUnitCircle * outerRadius;
        if (innerRadius > 0)
        {
            randomPosition = randomPosition.normalized * Random.Range(innerRadius, outerRadius);
        }
        GameObject enemy = Instantiate(enemyPrefab, randomPosition, Quaternion.identity);
        EnemyMovement enemyMovement = enemy.GetComponent<EnemyMovement>();
        if (enemyMovement != null)
        {
            enemyMovement.health = 3 + healthIncrement;
        }
    }

    void OnDrawGizmos()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(transform.position, outerRadius);
        if (innerRadius > 0)
        {
            Gizmos.DrawWireSphere(transform.position, innerRadius);
        }
    }
}

이런 코드를 받았다.

안쪽 반지름도 확인할 수 있다.

코드를 적용 시키면 Scene 화면에서
내부, 외부 반지름을 붉은 선으로 확인할 수 있다.

스폰 위치를 변경

캐릭터가 고정된 위치에 있는 것이 아니기 때문에
스포너가 캐릭터를 따라다닐 수 있게 요청한다.

팔로우 오브젝트

그러면 이렇게 팔로우 오브젝트라는 것을 설정할 수 있게 해준다.
inspector에서 팔로우 오브젝트를 캐릭터로 설정해주면 된다.

적 hp 바 요청

적의 hp 정보를 확인할 수 없기 때문에
HP UI를 추가하여 게임 중 적의 hp 정보를 확인할 수 있게 한다. 

이런 답변을 받음

우선 HP 바를 만드는데
많은 수정이 들어갔다.

이미지가 아닌 슬라이더로 주었음

첫번째는 Image.FillAmount가 아닌 슬라이더로 보내줘서
수정을 요청했다.

체력 설정

두번째는 EnemySpawner가 적을 생성할 때
생성 횟수에 따라 체력이 증가되므로
maxHealth에 관한 부분을 수정하도록 요청했다.

HP바가 안보인다.

이후 여러번의 수정을 요청한 것인데
체력 바가 화면에 보이지 않거나,
화면 가운데에 고정 되어 있다거나,
매우 작은 크기로 출력 되는 현상이 있었다.

앞의 두개는 해결 되었으나
매우 작은 크기로 출력 되는 현상의 원인은 찾기가 힘들었는데,

돌아가있다.

돌아가서 그렇게 보이는 것같다.

지우라고 말하는 중

지우라고 말한건데
지우지를 않는다.

주석처리 해버린다.

transform.LookAt(Camera.main.transform)으로 인해
카메라쪽으로 돌아가버리는 현상이다.
해당 부분을 날려버린 EnemyMovement의 코드는 다음과 같다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class EnemyMovement : MonoBehaviour
{
    public float speed = 3f;
    public int health = 3;
    public int maxHealth = 3;
    public GameObject hpBarPrefab;

    private Transform player;
    private Image hpBar;
    private RectTransform hpBarRectTransform;

void Start()
{
    player = GameObject.FindGameObjectWithTag("Player").transform;

    // Instantiate health bar prefab and set as child of Canvas object
    if (hpBarPrefab != null)
    {
        GameObject hpBarObject = Instantiate(hpBarPrefab);
        hpBarObject.transform.SetParent(GameObject.Find("Canvas").transform, false);
        hpBarObject.transform.localPosition = new Vector3(0f, 0f, 0f);
        hpBar = hpBarObject.GetComponent<Image>();
        hpBarRectTransform = hpBarObject.GetComponent<RectTransform>();
    }

    maxHealth = health;
}


    void Update()
    {
        transform.position = Vector3.MoveTowards(transform.position, player.position, speed * Time.deltaTime);
    }

    void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.CompareTag("Bullet"))
        {
            BulletMovement bullet = collision.gameObject.GetComponent<BulletMovement>();
            if (bullet != null)
            {
                health -= bullet.damage;
                if (health <= 0)
                {
                    Destroy(gameObject);
                }
            }
            Destroy(collision.gameObject);
        }
    }

    void OnDestroy()
    {
        if (hpBar != null)
        {
            Destroy(hpBar.gameObject);
        }

        PlayerMovement playerMovement = FindObjectOfType<PlayerMovement>();
        if (playerMovement != null)
        {
            playerMovement.RemoveEnemy(transform);
            playerMovement.GetExp(2);
        }

        PlayManager playManager = FindObjectOfType<PlayManager>();
        if (playManager != null)
        {
            playManager.IncrementScore(10);
        }
    }

    void LateUpdate()
    {
        if (hpBar != null)
        {
            hpBar.fillAmount = (float)health / maxHealth;

            // Adjust the position of the health bar so that it stays above the enemy
            Vector3 hpBarScreenPos = Camera.main.WorldToScreenPoint(transform.position + Vector3.up * 1.5f);
            hpBarScreenPos.z = 0;
            hpBarRectTransform.position = hpBarScreenPos;

            hpBarRectTransform.rotation = Quaternion.identity;

            // hpBar.transform.LookAt(Camera.main.transform);
        }
    }
}

여기까지 되면 따라다니는 UI는 되었으나,
체력에 따라 HP바가 감소되지 않는다.

이유는

자식이 게이지다.

자식 오브젝트의 FillAmount를 갱신 시켜야 하는데,
위 코드 상에서는 부모의 FillAmount를 갱신 시키기 때문

수정 요청

수정을 요청했더니

다른것도 바꿈

hpBarRectTransform도 자식으로 바꿔 버렸다.
해당 부분은 hpBarObject로 다시 설정해 달라 하고,
Destroy함수 부분에서 hpBar를 제거하는 부분을
hpBarObject를 제거하도록 요청한다.

말을 안듣는다.

사람이 바꾸는게 나을 것 같다.

어쨌든 바꾸게 되면

잘 파괴된다.

이런 결과물을 얻을 수 있다.

728x90

댓글