이전 글에서 가장 가까운 적에게 총을 쏘는 것까지 구현을 하였다.
기존 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 UI를 추가하여 게임 중 적의 hp 정보를 확인할 수 있게 한다.
우선 HP 바를 만드는데
많은 수정이 들어갔다.
첫번째는 Image.FillAmount가 아닌 슬라이더로 보내줘서
수정을 요청했다.
두번째는 EnemySpawner가 적을 생성할 때
생성 횟수에 따라 체력이 증가되므로
maxHealth에 관한 부분을 수정하도록 요청했다.
이후 여러번의 수정을 요청한 것인데
체력 바가 화면에 보이지 않거나,
화면 가운데에 고정 되어 있다거나,
매우 작은 크기로 출력 되는 현상이 있었다.
앞의 두개는 해결 되었으나
매우 작은 크기로 출력 되는 현상의 원인은 찾기가 힘들었는데,
돌아가서 그렇게 보이는 것같다.
지우라고 말한건데
지우지를 않는다.
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를 제거하도록 요청한다.
사람이 바꾸는게 나을 것 같다.
어쨌든 바꾸게 되면
이런 결과물을 얻을 수 있다.
'AI > AI활용' 카테고리의 다른 글
[ AI로 게임 만들기 ] GPT3.5 vs Google Gemini 시작 (0) | 2024.03.25 |
---|---|
[NFT] AI 그림으로 NFT 작가 되기 (0) | 2023.05.18 |
[ChatGPT][Unity] 간단한 게임 만들어보기 (3) (0) | 2023.04.06 |
[ChatGPT][Unity] 간단한 게임 만들어보기 (2) (0) | 2023.04.05 |
[ChatGPT][Unity] 간단한 게임 만들어보기 (1) (0) | 2023.04.04 |
댓글