Unity

3D 테스트 프로젝트 14

psb08 2025. 3. 7. 11:51
728x90

저번에 만든 AI를 플레이 해보다가 갑자기 생각나서 만들었습니다.

 

점점 적의 수가 많아지고 소환이 끊이지 않더라고요

 

EnemySpawner.cs

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

public class EnemySpawner : MonoBehaviour
{
    public GameObject[] enemyPrefabs;
    public Transform[] spawnPoints;
    public float spawnInterval = 3.0f;
    public int spawnCount = 3;
    public int currentSpawned = 0;

    private void Start()
    {
        StartCoroutine(SpawnEnemies());
    }

    private IEnumerator SpawnEnemies()
    {
        while (currentSpawned < 20)
        {
            for (int i = 0; i < spawnCount; i++)
            {
                currentSpawned++;
                Transform spawnPoint = spawnPoints[Random.Range(0, spawnPoints.Length)];
                GameObject enemyPrefab = enemyPrefabs[Random.Range(0, enemyPrefabs.Length)];
                Instantiate(enemyPrefab, spawnPoint.position, spawnPoint.rotation);
            }
            yield return new WaitForSeconds(spawnInterval);
            
        }
    }


}

currentSpawned 라는 int형 변수를 만든 뒤에, 소환할 때마다 ++을 해서 최대 20까지 제한을 걸었습니다.

 

그리고 적이 죽을 때 소환 된 수를 줄여야 다시 소환이 되겠죠

 

그래서 EnemyAI로 갑니다.

 

EnemyAI.cs

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

public class EnemyAI : MonoBehaviour
{
    public Transform player;
    public EnemySpawner spawner;
    private NavMeshAgent agent;
    private MeshRenderer mesh;
    private Color startColor;

    private void Awake()
    {
        mesh = gameObject.GetComponent<MeshRenderer>();
        agent = GetComponent<NavMeshAgent>();
        spawner = GameObject.FindGameObjectWithTag("Spawner").GetComponent<EnemySpawner>();
        startColor = mesh.material.color;
    }

    private void Start()
    {
        GameObject playerObj = GameObject.FindWithTag("MainCamera");
        if (playerObj != null)
        {
            player = playerObj.transform;
        }
    }

    private void Update()
    {
        if (player != null)
        {
            agent.SetDestination(player.position);
        }

    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.CompareTag("Player"))
        {
            HpSystem hp = other.gameObject.GetComponent<HpSystem>();
            hp.TakeDamage(20f);
        }
        if (other.gameObject.CompareTag("Bullet"))
        {
            StartCoroutine(Hit());
            HpSystem hp = gameObject.GetComponent<HpSystem>();
            hp.TakeDamage(50f);
            Destroy(other.gameObject);
            Debug.Log("총알 적중");
        }
    }

    private IEnumerator Hit()
    {
        mesh.material.color = Color.red;
        yield return new WaitForSeconds(0.2f);
        mesh.material.color = startColor;
    }

    public void SpawnCountMinus()
    {
        spawner.currentSpawned--;
    }

}

여기서 public으로 SpawnCountMinus라는 메서드를 만든 뒤, spawner에 currentSpawned 수를 감소 시킵니다.

 

근데 이러면 실행이 어디서 되나요 할 수 있는데, 바로 HpSystem에 유니티 이벤트로 OnDeath를 만들었습니다.

 

HpSystem.cs

using System;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;

public class HpSystem : MonoBehaviour
{
    [Header("체력 설정")]
    public float maxHealth = 100f;
    public float currentHealth;

    public event Action<float, float> OnHealthChanged;
    public UnityEvent OnDeath;

    private void Awake()
    {
        currentHealth = maxHealth;
    }

    // 데미지를 받는 메서드
    public void TakeDamage(float amount)
    {
        if (currentHealth <= 0) return;

        currentHealth -= amount;
        currentHealth = Mathf.Clamp(currentHealth, 0, maxHealth);
        OnHealthChanged?.Invoke(currentHealth, maxHealth);

        if (currentHealth <= 0)
        {
            Die();
        }
    }

    public void Heal(float amount)
    {
        if (currentHealth <= 0) return;

        currentHealth += amount;
        currentHealth = Mathf.Clamp(currentHealth, 0, maxHealth);
        OnHealthChanged?.Invoke(currentHealth, maxHealth);
    }

    private void Die()
    {
        if (gameObject.name.Contains("Player"))
        {
            SceneManager.LoadScene(0);
        }
        if (gameObject.name.Contains("Enemy"))
        {
            Destroy(gameObject);
        }
        OnDeath?.Invoke();
    }

    public float GetHealth()
    {
        return currentHealth;
    }

}

별 특별한 건 없고, UnityEvent로 OnDeath를 만들고, 죽을 때 Invoke를 합니다.

 

이제 이렇게 Enemy Prefab에 넣어주면 끝

 

이렇게 6명으로 잘 되어 있고요,

 

적 2명이 다시 소환되고 1명을 죽이니 총 7명으로 적의 수가 하나 줄은 것을 볼 수 있습니다.

 

 

728x90

'Unity' 카테고리의 다른 글

수업 내용 복습 1  (0) 2025.03.09
3D 테스트 프로젝트 15  (0) 2025.03.08
3D 테스트 프로젝트 13  (0) 2025.03.06
3D 테스트 프로젝트 12  (0) 2025.03.05
3D 테스트 프로젝트 11  (0) 2025.03.04