1. Condition.cs - 체력, 허기, 스태미나 등의 상태를 관리하는 클래스 (플레이어뿐만 아니라 몬스터, NPC에도 적용 가능)
2. UIConditions.cs - UI와 상태를 연결하는 클래스 (UI를 따로 관리해서 재사용 가능)
3. PlayerCondition.cs - 플레이어의 상태와 관련된 로직을 담당 (플레이어의 상태를 별도로 관리)
4. Player.cs - 플레이어의 기본 속성
수정 시 다른 코드에 영향을 덜 주고 유지보수가 쉬워지도록 모듈화
-> 컴포넌트 기반 설계 (Component-Based Design)
public Condition mana;
UI를 수정하고 싶을 때, UIConditions.cs만 수정
게임 로직을 수정하고 싶을 때, Condition.cs나 PlayerCondition.cs만 수정
MVC 패턴(Model-View-Controller) 과도 비슷하다
1)Model (데이터, 상태)
Condition.cs → 체력, 허기, 스태미나 데이터를 관리하는 모델 역할
2)View (UI)
UIConditions.cs → UI 상태바를 업데이트하는 역할
3)Controller (로직)
PlayerCondition.cs → 상태 변화를 관리하는 역할
캡슐화(Encapsulation) → Condition 클래스가 자신의 데이터(curValue, maxValue)를 보호하고, Add()나 Substract() 메서드를 통해서만 수정 가능
public float curValue;
public float maxValue;
public float startValue;
public float passiveValue; // 계속 차오르는
public Image uiBar; // 상태바
public void Start()
{
curValue = startValue;
}
private void Add(float amount)
{
curValue = Mathf.Min(curValue + amount, maxValue);
}
private void Substract(float amount)
{
curValue = Mathf.Max(curValue - amount, 0f);
}
public float GetPercentage()
{
return curValue / maxValue;
}
private void Update()
{
uiBar.fillAmount = GetPercentage();
}
a. 나타낼 상태 선언
public Condition health;
public Condition hunger;
public Condition Stamina;
b.
private void Start()
{
CharacterManager.Instance.Player.condition.uiCondition = this;
}
public PlayerCondition condition;
private void Awake()
{
condition = GetComponent<PlayerCondition>();
}
a. 선언
public UIConditions uiCondition;
Condition health { get { return uiCondition.health; } }
Condition hunger { get { return uiCondition.hunger; } }
Condition stamina { get { return uiCondition.stamina; } }
public float noHungerHealthDecay; // 허기가 0일 때 사용할 값
b. 조건 추가
private void Update()
{
// 시간이 흐르면서 허기가 감소 (패시브)
hunger.Substract(hunger.passiveValue * Time.deltaTime);
// 시간이 흐르면서 스태미나 증가 (패시브)
stamina.Add(stamina.passiveValue * Time.deltaTime);
// 허기가 0이면 시간이 지나면서 체력 감소
if (hunger.curValue <= 0f)
{
health.Substract(noHungerHealthDecay * Time.deltaTime);
}
// 체력이 0이면 사망
if (health.curValue <= 0f) { Die(); }
}
❓ 여기서 health.curvalue < 0인 이유
부동소수점 연산을 거치면서 0을 딱 맞추기 어렵다.
예를 들어 체력이 0.1이 남은 상태에서 0.2의 데미지를 입으면 -0.1이 되고, 죽어야 한다.
그러나 health.curvalue == 0이라고 조건을 달면, 죽어야 함에도 죽지 않는다.
체력이 0 이하가 되는 순간을 감지하는 것이 목적이라면, health.curValue <= 0이 더 안전하며
앞서 curValue = Mathf.Max(curValue - amount, 0f);가 있기 때문에, 어차피 0 밑으로 안 내려간다.
c. 회복
public void Heal(float amount)
{
health.Add(amount);
}
d. 섭취
public void Eat(float amount)
{
hunger.Add(amount);
}
e. 죽음
public void Die()
{
Debug.Log("플레이어가 죽었다.");
}
