Unity

3D 테스트 프로젝트 9

psb08 2025. 3. 2. 14:15
728x90

GameManager, TeamManager, TurnManager를 설명하겠습니다.

 

TeamManager.cs

public class TeamManager : MonoBehaviour
{
    public GameObject[] playerPrefabs;
    public GameObject[] enemyPrefabs; 
    public List<Player> playerTeam = new List<Player>();
    public List<Enemy> enemyTeam = new List<Enemy>();

    public Transform[] playerTransforms;
    public Transform[] enemyTransforms;

    public TurnManager turnManager;

    private void Update()
    {
        CheckTeams();
    }

    public void InitializeTeams()
    {
        for (int j = 0; j < enemyTransforms.Length; j++)
        {
            GameObject enemyObject = Instantiate(enemyPrefabs[j], 
                enemyTransforms[j].position, enemyTransforms[j].rotation);
            Enemy enemy = enemyObject.GetComponent<Enemy>();
            enemyTeam.Add(enemy);
        }

        for (int i = 0; i < playerTransforms.Length; i++)
        {
            GameObject playerObject = Instantiate(playerPrefabs[i], 
                playerTransforms[i].position, playerTransforms[i].rotation);
            Player player = playerObject.GetComponent<Player>();
            playerTeam.Add(player);
        }
    }

    private void CheckTeams()
    {
        for (int i = playerTeam.Count - 1; i >= 0; i--)
        {
            if (playerTeam[i].Health <= 0)
            {
                turnManager.turnOrder.Remove(playerTeam[i]);
                playerTeam.RemoveAt(i);
            }
        }

        for (int i = enemyTeam.Count - 1; i >= 0; i--)
        {
            if (enemyTeam[i].Health <= 0)
            {
                turnManager.turnOrder.Remove(enemyTeam[i]);
                enemyTeam.RemoveAt(i);
            }
        }
    }

}

TeamManager를 요약하자면 적 프리팹과 우리 팀 프리팹을 받고, 게임이 시작되면 소환을 합니다.

그리고 매번 체력이 0보다 작거나 같은지 확인하고 만약 0보다 작거나 같다면, 리스트에서 삭제합니다.

(게임 오브젝트 파괴는 Enemy, Player 스크립트에서 직접)


TurnManager.cs

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

public class TurnManager : MonoBehaviour
{
    public int currentTurnIndex = -1; 
    public List<object> turnOrder = new List<object>();
    public TurnDisplay turnDisplay;

    public void SetupTurnOrder(List<Player> playerTeam, List<Enemy> enemyTeam)
    {
        turnOrder.Clear();
        turnOrder.AddRange(playerTeam);
        turnOrder.AddRange(enemyTeam);
        turnOrder = turnOrder.OrderByDescending(c => (c is Player player) ? player.Speed : (c as Enemy).Speed).ToList();
    }

    public void NextTurn()
    {
        currentTurnIndex++;

        if (currentTurnIndex >= turnOrder.Count)
        {
            currentTurnIndex = 0;
        }

        object currentCharacter = turnOrder[currentTurnIndex];
        turnDisplay.UpdateCurrentTurn(currentCharacter);
        turnDisplay.UpdateTurnList(turnOrder, currentTurnIndex);

        Debug.Log($"{(currentCharacter is Player ? (currentCharacter as Player).CharacterName : (currentCharacter as Enemy).CharacterName)}의 턴입니다.");

        if (currentCharacter is Enemy enemy)
        {
            enemy.AttackRandomPlayer();
            StartCoroutine(WaitTime());
        }
    }

    private IEnumerator WaitTime()
    {
        yield return new WaitForSeconds(1.5f);
        NextTurn();
    }

}

TurnManager를 요약하면,

속도대로 인덱스를 정하고, 만약 행동을 하면 인덱스를 다음으로 넘겨, 다음 인덱스의 캐릭터가 행동하도록 합니다.

TurnDisplay는 나중에 설명하겠습니다.


GameManager.cs

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

public class GameManager : MonoBehaviour
{
    public TeamManager teamManager;
    public TurnManager turnManager;

    private void Start()
    {
        teamManager.InitializeTeams();
        turnManager.SetupTurnOrder(teamManager.playerTeam, teamManager.enemyTeam);
        turnManager.NextTurn();
    }

    public void PlayerAttack(Enemy target)
    {
        var currentCharacter = turnManager.turnOrder[turnManager.currentTurnIndex];

        if (currentCharacter is Player currentPlayer)
        {
            currentPlayer.Attack(target);
            turnManager.NextTurn();
        }
    }

    private void Update()
    {
        var currentCharacter = turnManager.turnOrder[turnManager.currentTurnIndex];

        if (currentCharacter is Player currentPlayer)
        {
            if (Input.GetMouseButtonDown(0))
            {
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                RaycastHit hit;

                if (Physics.Raycast(ray, out hit))
                {
                    Enemy clickedEnemy = hit.transform.GetComponent<Enemy>();
                    if (clickedEnemy != null && clickedEnemy.Health > 0)
                    {
                        PlayerAttack(clickedEnemy);
                    }
                }
            }
        }
    }

}

GameManager를 요약하면, TeamManager, TurnManager를 받아오고,

프리팹을 소환하고, 턴을 정한 뒤, 게임을 시작합니다.

여기서 마우스 클릭을 하면 플레이어가 공격할 수 있도록 정합니다.

728x90

'Unity' 카테고리의 다른 글

3D 테스트 프로젝트 11  (0) 2025.03.04
3D 테스트 프로젝트 10  (0) 2025.03.03
3D 테스트 프로젝트 8  (0) 2025.03.01
3D 테스트 프로젝트 7  (0) 2025.02.28
3D 테스트 프로젝트 6  (0) 2025.02.27