TIL(2024,07,03)최종 프로젝트 1차구현 하나씩 만들기

김보근·2024년 7월 3일

Unity

목록 보기
31/113
post-thumbnail

오늘은 코드리팩토링과 자동재화를 추가했지만 멘토님께 계획서를 피드백받은 결과 이 게임은 포트폴리오에 쓸수없을것같다 해서 모작 게임으로 계획을 바꾸기로 하였다.

오늘 배운 것 (TIL): Unity 프로젝트에서 디자인 패턴과 객체지향 설계 적용

오늘은 Unity 프로젝트에 여러 디자인 패턴과 객체지향 설계를 적용하여 구조를 개선했습니다. 특히 자동 재화 시스템과 레벨 및 강화 시스템을 구현했습니다. 주요 변경 사항과 적용된 디자인 패턴은 다음과 같습니다.

1. 옵저버 패턴 (Observer Pattern)

목적: 객체 간의 느슨한 결합을 유지하면서 한 객체의 상태 변화를 다른 객체들에게 통지합니다.

적용된 부분:
WaterManager 클래스: 물의 양이 변경될 때 OnWaterChanged 이벤트를 통해 통지합니다.
Root 클래스: 물이 생성될 때 OnWaterGenerated 이벤트를 통해 통지합니다.
EnergyManager 클래스: 에너지가 변경될 때 OnEnergyChanged 이벤트를 통해 통지합니다.

public class WaterManager : MonoBehaviour
{
    public delegate void WaterChanged(int newAmount);
    public event WaterChanged OnWaterChanged;

    public void IncreaseWater(int amount)
    {
        waterAmount += amount;
        OnWaterChanged?.Invoke(waterAmount);
    }
}

2. 단일 책임 원칙 (Single Responsibility Principle, SRP)

목적: 클래스는 하나의 책임만 가져야 하며, 그 책임을 완전히 캡슐화해야 합니다.

적용된 부분:
WaterManager 클래스: 물의 양을 관리합니다.
UIManagerBG 클래스: UI 업데이트를 담당합니다.
TouchInputManager 클래스: 터치 입력을 처리하고 물의 양을 증가시킵니다.
PlayerMovement 클래스: 플레이어의 이동과 관련된 로직을 처리합니다.
UpgradeButton 클래스: 모든 종류의 업그레이드 로직을 처리합니다.

public class UIManagerBG : MonoBehaviour
{
    public void UpdateWaterUI(int waterAmount, int waterNeededForCurrentLevel)
    {
        waterText.text = $"물 : {waterAmount}";
        levelFillImage.fillAmount = (float)waterAmount / waterNeededForCurrentLevel;
    }
}

3. 전략 패턴 (Strategy Pattern)

목적: 전략 패턴은 객체의 행위를 런타임에 바꿀 수 있도록 하는 패턴입니다.

적용된 부분:
UpgradeButton 클래스: 다양한 업그레이드 로직을 처리할 수 있도록 업그레이드 유형에 따라 다른 전략을 사용합니다.

public class UpgradeButton : MonoBehaviour
{
    public enum UpgradeType
    {
        Root,
        Spirit,
        Touch,
        Tree,
        MoveSpeed,
        WaterIncrease
    }

    private void OnUpgradeButtonClicked()
    {
        switch (upgradeType)
        {
            case UpgradeType.Root:
                HandleRootUpgrade();
                break;
            case UpgradeType.Spirit:
                HandleSpiritUpgrade();
                break;
            // 다른 케이스들...
        }
    }
}

4. 의존성 주입 (Dependency Injection)

목적: 클래스가 자신의 의존성을 외부에서 주입받아 유연성과 테스트 용이성을 높입니다.

적용된 부분:
UpgradeButton 클래스: WaterManager, UIManagerBG, ResourceManager, Root, Spirit, TouchInputManager, PlayerMovement 등 필요한 의존성을 외부에서 주입받아 사용합니다.

public class UpgradeButton : MonoBehaviour
{
    public WaterManager waterManager;
    public UIManagerBG uiManager;
    // 기타
}

5. 캡슐화 (Encapsulation)

목적: 데이터와 데이터를 처리하는 메서드를 하나로 묶어, 데이터에 직접 접근하지 못하게 하고 메서드를 통해 접근하게 합니다.

적용된 부분:
모든 클래스에서 필드를 private로 선언하고, 필요한 경우 public 메서드를 통해 접근하게 합니다.

public class Root : MonoBehaviour
{
    private int rootLevel = 1;
    private int baseWaterGeneration = 1;

    public int CalculateUpgradeCost()
    {
        return rootLevel * 20;
    }
}

이러한 디자인 패턴과 객체지향 설계를 통해 프로젝트의 구조를 개선하고, 코드의 재사용성과 유지보수성을 높일 수 있었습니다. 다양한 패턴을 조합하여 각 클래스가 명확한 역할을 갖도록 하였고, 이를 통해 코드의 일관성과 확장성을 확보했습니다.

고찰

오늘 이렇게 작업을 해봤지만 어비스리움을 토대로 게임을 만들려고 했지만 큰틀만 어비스리움이고 다른요소들은 아예 다른게임이라고 피드백을 받았다. 이러한 게임은 포트폴리오 제출시에 별로인 게임이거나 쓸수없다고 하였다. 그래서 이번 계획에서는 어비스리움의 모작게임을 만들고 컨텐츠를 추가하는방식으로 계획을 하게 될것같다.
나의 일주일은 어디에.. 중간점검까지 20일남았다.

profile
게임개발자꿈나무

0개의 댓글