Box Spawner와 Buff Box를 구현 했으니 Buff Box를 먹었을 때 실제로 플레이어한테 Buff를 줘야한다.
1. Buff Box에 플레이어가 닿으면 Buff Box가 PlayerMediator에 있는 SetBuff에 자신의 BuffType을 전달해서 실행한다.
public void SetBuff(BuffBox.BuffType buffType)
{
Buff tempBuff = null;
if (buffType == BuffBox.BuffType.Heal)
{
tempBuff = GetComponent<Heal>();
if (tempBuff == null)
tempBuff = gameObject.AddComponent<Heal>();
}
else if(buffType == BuffBox.BuffType.Bullet)
{
tempBuff = GetComponent<Power>();
if(tempBuff == null)
tempBuff = gameObject.AddComponent<Power>();
}
else if(buffType == BuffBox.BuffType.Skull)
{
tempBuff = GetComponent<Skull>();
if(tempBuff == null)
tempBuff = gameObject.AddComponent<Skull>();
}
if (tempBuff == null)
return;
status.ActiveBuff(tempBuff);
buffList.Add(tempBuff);
}
처음에 buff temp = new Power, Heal, Skull로 갈아 끼울 수 있게 만드려고 했다. 하지만 MonoBehaviour를 상속받으면 new 키워드를 사용할 수 없다. MonoBehaviour를 상속받는 스크립트들은 기본적으로 object에 달라붙어 있는 상태를 가지고 있어야 한다.
그래서 조금 노선을 바꿔서 gamObject.AddComponenet로 추가를 하는 방향으로 했다.
받은 BuffBox의 BuffType에 따라 Buff tempBuff에 들어가는 스크립트가 달라진다.
Heal이면 Buff를 상속받은 Heal, Bullet이면 Buff를 상속받은 Power, Skull이면 Buff를 상속받은 Skull 같은 형식이다.
우선 같은 버프를 여러 번 받을 수 있기 때문에 이전에 동일한 버프를 받았는지 확인하기 위해 tempBuff = Getcomponent<Buff>를 해서 null을 체크한다.
null이면 이전에 동일한 버프를 받지 않아서 해당 스크립트가 없다는 뜻이기 때문에 컴포넌트를 추가한다.
2. 이후 PlayerStatus에서 AddBuff(Buff)를 넣어 Buff를 실행한다.
3. 들어온 Buff에 Active를 실행시킨다 매개 변수로는 자기 자신(PalyerStatus)을 넣는다.
PlayerStatus AddBuff
public void ActiveBuff(Buff buff)
{
buff.Active(this);
}
Abstract class Buff 이다.
4.Buff를 상속받는 자식들은 DurationTime과 Active, InActive를 구현해야 한다.
public abstract class Buff : MonoBehaviour
{
public abstract float myDurationTime { get; protected set; }
public abstract void Active(PlayerStatus status);
public abstract void InActive(PlayerStatus status);
}
Heal Buff: 5초에 걸쳐 체력을 최대체력의 20퍼센트 회복한다.
public class Heal : Buff
{
public override float myDurationTime { get; protected set; } = 5;
public override void Active(PlayerStatus status)
{
print("Heal Start");
StartCoroutine(Healing(status, myDurationTime));
}
public override void InActive(PlayerStatus status = null)
{
print("Heal End");
StopCoroutine(nameof(Healing));
}
IEnumerator Healing(PlayerStatus status, float time)
{
for (int i = 0; i < time; i++)
{
status.CurrentHP += Mathf.Round(status.MaxHP * 0.04f);
yield return new WaitForSeconds(1);
yield return null;
}
InActive();
}
}
Power Buff: 10초동안 공격력이 10 증가한다.
public class Power : Buff
{
public override float myDurationTime { get; protected set; } = 10;
public override void Active(PlayerStatus status)
{
StartCoroutine(PowerUp(status));
print(myDurationTime);
}
public override void InActive(PlayerStatus status)
{
StopCoroutine(nameof(PowerUp));
status.AdditionalPower -= 10;
print($"Power End {status.AdditionalPower}");
}
IEnumerator PowerUp(PlayerStatus status)
{
status.AdditionalPower += 10;
print("powerUpCR");
yield return new WaitForSeconds(myDurationTime);
InActive(status);
}
}
Skull Buff: 5초에 걸쳐 최대체력의 20퍼센트의 피해를 입는다.
public class Skull : Buff
{
public override float myDurationTime { get; protected set; } = 5f;
public override void Active(PlayerStatus status)
{
print("Skull Start");
StartCoroutine(DotDamage(status, myDurationTime));
}
public override void InActive(PlayerStatus statu = null)
{
print("Skull End");
StopCoroutine(nameof(DotDamage));
}
IEnumerator DotDamage(PlayerStatus status, float time)
{
for (int i = 0; i < time; i++)
{
status.CurrentHP -= Mathf.Round(status.MaxHP * 0.04f);
yield return new WaitForSeconds(1);
yield return null;
}
InActive();
}
}
디자인 패턴 중 자주 쓰인다는 상태 패턴으로 구현을 해보았다.
그리고 이번 포스팅이 필자가 가고자 하는 코딩 스타일을 잘 알려주는 것 같다고 생각한다.
필자가 원하는 코딩 스타일은 자연스럽게 읽히고 확장성있는 코드이다.
이번 포스팅에서 소개한 함수들이다.
SetBuff() -> ActiveBuff() -> Buff.Active()
Buff를 설정하고 -> 설정한 Buff의 실행을 누른다 -> 설정한 Buff에 담겨져 있는 기능이 실행 된다.
이처럼 함수의 명을 읽는 것으로 지금 어떤 기능을 수행하는지 다음엔 어떤 기능을 수행하는지 자연스럽게 알 수 있게끔 하는 것이 필자가 추구하는 방식 중 하나이고.
새로운 버프를 추가할 때는 Buff 추상 함수를 상속한 버프와 boxType 만 추가 하면 된다. 이전 코드의 변경 없이 추가만 하면 되는 것이다. 이처럼 변경에는 닫혀있고 수정에는 용이한 코드를 짜는 것이 필자가 가고자 하는 방향이다.
'Unity > Portfolio Daily Log' 카테고리의 다른 글
캐주얼 슈팅 액션 대전 게임 (모바일) - 15 스킬 및 쿨타임 UI (0) | 2022.08.01 |
---|---|
캐주얼 슈팅 액션 대전 게임 (모바일) - 14 포톤 5 Cloud Spawner, Buff Box 그리고 Buff 동기화 하기 (0) | 2022.07.30 |
캐주얼 슈팅 액션 대전 게임 (모바일) - 12 클라우드 스포너와 버프 박스 Cloud Spawner and Buff Box (0) | 2022.07.28 |
캐주얼 슈팅 액션 대전 게임 (모바일) - 11 피격시 카메라 흔들림, Hit Effect 변경 (0) | 2022.07.27 |
캐주얼 슈팅 액션 대전 게임 (모바일) - 10 오브젝트 풀 개선 (0) | 2022.07.26 |