public class DataManager : MonoBehaviour
{
// 게임 데이터를 로드하고 저장하는 역할
// 플레이어 정보, 아이템 데이터, 게임 설정 등의 데이터를 관리
// 데이터의 변경 및 업데이트가 필요한 경우 이벤트 시스템을 활용(구독)
#region Player Global Variable
private GameObject player;
public GameObject Player
{
get { return player; }
set { player = value; }
}
// baseStats.AttackSO (attackSpeed, power, range, target)
[SerializeField] private CharacterStats PlayerBaseStats;
// CharacterStats.PlayerCurrentStats (maxHealth, maxStamina, speed, invincibilityTime)
public CharacterStats PlayerCurrentStats { get; private set; }
#endregion
private void Start()
{
// if (PlayerBaseStats == null) PlayerBaseStats.attackSO = Resources.Load("Prefabs/DefaultAttackData", typeof(ScriptableObject)) as AttackSO;
}
#region Player Data
public void InitializePlayerData()
{
AttackSO attackSO = null;
if (PlayerBaseStats != null)
attackSO = Instantiate(PlayerBaseStats.attackSO);
PlayerCurrentStats = new CharacterStats { attackSO = attackSO };
PlayerCurrentStats.maxHealth = PlayerBaseStats.maxHealth;
PlayerCurrentStats.currentHealth = PlayerBaseStats.currentHealth;
PlayerCurrentStats.speed = PlayerBaseStats.speed;
PlayerCurrentStats.maxStamina = PlayerBaseStats.maxStamina;
PlayerCurrentStats.invincibilityTime = PlayerBaseStats.invincibilityTime;
}
// 1번 방법 (AttackSO를 통째로 넘겨줘서 교체)
public void UpdatePlayerAttackSOData(AttackSO attackSO)
{
CharacterStats PlayerChangeStats = new CharacterStats { attackSO = attackSO };
PlayerCurrentStats.attackSO.attackSpeed += PlayerChangeStats.attackSO.attackSpeed;
PlayerCurrentStats.attackSO.power += PlayerChangeStats.attackSO.power;
PlayerCurrentStats.attackSO.range += PlayerChangeStats.attackSO.range;
}
// 2번 방법 (각 값을 받아서 교체)
public void UpdatePlayerAttckSOData(float atkSpeed, float power, float range)
{
PlayerCurrentStats.attackSO.attackSpeed += atkSpeed;
PlayerCurrentStats.attackSO.power += power;
PlayerCurrentStats.attackSO.range += range;
}
public void UpdatePlayerStatsData(int health, int speed)
{
PlayerCurrentStats.maxHealth += health;
PlayerCurrentStats.currentHealth += health;
PlayerCurrentStats.speed += speed;
}
public void ChangeHealth(float value)
{
PlayerCurrentStats.currentHealth = Mathf.Clamp(PlayerCurrentStats.currentHealth - (int)value, 0, PlayerCurrentStats.maxHealth);
Debug.Log("데미지를 입었습니다 " + PlayerCurrentStats.currentHealth);
Debug.Log("현재체력 " + PlayerCurrentStats.currentHealth);
}
#endregion
--------------------------------- 이하 생략
Player의 데이터에 접근할 때는 읽기로는 직업 GameManager의 DataManger로 접근하여 값을 읽거나 복사할 수 있다.
Player의 데이터를 변경하기 위해서는 직접적인 접근은 프로퍼티의 private set;으로 막고 DataManager내에서 메서드로 변경하는 메서드를 만들어 GameManager에서 그 메서드에 간접적으로 접근할 수 있도록 보호했다.
public class GameManager : MonoBehaviour
{
public static GameManager instance = null;
#region Global Variable
[HideInInspector]
public DataManager DataManager { get; private set; }
[HideInInspector]
public StageManager StageManager { get; private set; }
[HideInInspector]
public AudioManager AudioManager { get; private set; }
[HideInInspector]
public UIManager UiManager { get; private set; }
#endregion
#region Data Variable
// Player Data
// Monster, Item 등등
#endregion
private void Awake()
{
if (instance == null)
{
instance = this;
}
else if (instance != this)
{
Destroy(gameObject);
}
DontDestroyOnLoad(gameObject);
InitializSetting();
}
#region Initialize
private void InitializSetting()
{
InitializeManager();
InitializeData();
InitializeStage();
InitializeUI();
InitializeAudio();
}
private void InitializeManager()
{
DataManager = GetComponentInChildren<DataManager>();
StageManager = GetComponentInChildren<StageManager>();
AudioManager = GetComponentInChildren<AudioManager>();
UiManager = GetComponentInChildren<UIManager>();
}
private void InitializeData()
{
// 데이터 초기화
// 플레이어 데이터 초기화
PlayerDataInitialiez();
}
private void InitializeStage()
{
// 스테이지 초기화
}
private void InitializeUI()
{
// UI 초기화
}
private void InitializeAudio()
{
// 오디오 초기화
AudioManager.InitalizeAudios();
}
#endregion
#region Data
public void PlayerDataInitialiez()
{
DataManager.InitializePlayerData();
}
public void UpdatePlayerAttackSODatas(AttackSO attackSO)
{
DataManager.UpdatePlayerAttackSOData(attackSO);
}
public void UpdatePlayerAttckSODatas(float atkSpeed, float power, float range)
{
DataManager.UpdatePlayerAttckSOData(atkSpeed, power, range);
}
public void UpdatePlayerStatsDatas(int health, int speed)
{
DataManager.UpdatePlayerStatsData(health, speed);
}
#endregion
--------------------------------------------------------------- 이하 생략
InitializSetting();를 통해 최초에 한번 초기화 작업을 진행해준다. 필요에 따라 메서드를 사용하면 초기화가 가능하다.
GameManger에서는 다른 매니저들의 데이터를 간접적으로 접근하도록 제한한다.
AudioManager에서 BGM, SFX 각각 Audio Source 생성
각각 필요한 효과음을 AudioClip으로 만들고 Resources.Load로 Awake에서 불러올 예정.
각 Manager들의 MonoBehaviour의 상속 해제를 위한 구상.
플레이어 데이터 변경 때 Event로 UI에 전달로 바꾸기위한 구상.