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 |