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

김보근·2024년 7월 4일

Unity

목록 보기
33/113
post-thumbnail

오늘은 기획을 다시만들고 어비스리움의 모작으로 잡고 이전에 만들던 강화 시스템을 가져와서 3D프로젝트에 적용하고 바꾸는 작업을 시작하였다.

Today I Learned (TIL)

Unity 3D 프로젝트 작업
오늘은 Unity 3D 프로젝트에서 싱글톤 패턴을 적용하고, 델리게이트와 이벤트를 사용하여 게임 내 생명력 변화에 따른 UI 업데이트를 구현했습니다. 아래는 오늘 작업한 내용에 대한 자세한 설명입니다.

싱글톤 패턴 적용
LifeManager와 UIManager 클래스를 싱글톤 패턴으로 변환하여 프로젝트 내 어디서든 접근 가능하도록 구현했습니다.

LifeManager 클래스

using UnityEngine;

public class LifeManager : MonoBehaviour
{
    // 싱글톤 인스턴스
    public static LifeManager Instance { get; private set; }

    // 현재 보유하고 있는 생명력의 양
    public int lifeAmount = 0;

    // 현재 레벨
    public int currentLevel = 1;

    // 레벨당 생명력 증가량
    public int lifePerLevel = 10;

    // 생명력 변화 델리게이트
    public delegate void WaterChanged(int newAmount);

    // 생명력 변화 이벤트
    public event WaterChanged OnWaterChanged;

    // 싱글톤 인스턴스 설정 및 중복 생성 방지
    private void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            // 인스턴스가 파괴되지 않도록 설정
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            // 이미 인스턴스가 존재하면 중복 생성된 객체 파괴
            Destroy(gameObject);
        }
    }

    // 생명력 증가 메서드
    public void IncreaseWater(int amount)
    {
        lifeAmount += amount;
        // 생명력 변화 이벤트 호출
        OnWaterChanged?.Invoke(lifeAmount);
    }

    // 생명력 감소 메서드
    public void DecreaseWater(int amount)
    {
        lifeAmount -= amount;
        // 생명력 변화 이벤트 호출
        OnWaterChanged?.Invoke(lifeAmount);
    }

    // 특정 작업을 수행하는 데 필요한 생명력이 충분한지 확인하는 메서드
    public bool HasSufficientWater(int requiredAmount)
    {
        return lifeAmount >= requiredAmount;
    }

    // 업그레이드에 필요한 생명력의 양을 계산하는 메서드
    public int CalculateWaterNeededForUpgrade(int amount)
    {
        return (currentLevel + amount) * lifePerLevel;
    }
}

UIManager 클래스

using TMPro;
using UnityEngine;

public class UIManager : MonoBehaviour
{
    // 싱글톤 인스턴스
    public static UIManager Instance { get; private set; }

    // UI 요소들
    public TextMeshProUGUI waterText;
    public TextMeshProUGUI lifeIncreaseText;
    public TextMeshProUGUI touchLevelText;
    public TextMeshProUGUI touchIncreaseText; // 추가된 텍스트 UI 요소
    public TextMeshProUGUI upgradelifeCostText;
    public TextMeshProUGUI rootLevelText;
    public TextMeshProUGUI rootUpgradeCostText;
    public TextMeshProUGUI spiritLevelText;
    public TextMeshProUGUI spiritUpgradeCostText;
    public MeshFilter outsideTreeMeshFilter; // 3D 오브젝트
    public TextMeshProUGUI upgradeRequirementText;
    public MeshFilter groundMeshFilter; // 3D 오브젝트
    public Mesh[] treeMeshes; // 3D 모델 배열

    // 싱글톤 인스턴스 설정 및 중복 생성 방지
    private void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            // 인스턴스가 파괴되지 않도록 설정
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            // 이미 인스턴스가 존재하면 중복 생성된 객체 파괴
            Destroy(gameObject);
        }
    }

    // 생명력 UI 업데이트 메서드
    public void UpdateLifeUI(int waterAmount, int waterNeededForCurrentLevel)
    {
        waterText.text = $" 생명력 : {waterAmount}";
    }

    // 나무 모델 업데이트 메서드
    public void UpdateTreeMeshes(int currentLevel)
    {
        int currentIndex = (currentLevel / 5) % treeMeshes.Length;
        outsideTreeMeshFilter.sharedMesh = treeMeshes[currentIndex];
    }

    // 초당 생명력 증가량 UI 업데이트 메서드
    public void UpdateLifeIncreaseUI(int totalLifeIncrease)
    {
        lifeIncreaseText.text = "Life Increase Per Second: " + totalLifeIncrease.ToString();
    }

    // 터치 레벨 및 생산량 UI 업데이트 메서드
    public void UpdateTouchUI(int touchIncreaseLevel, int touchIncreaseAmount, int upgradelifeCost)
    {
        touchLevelText.text = $"외로운 나무 레벨: {touchIncreaseLevel}";
        touchIncreaseText.text = $"현재 터치당 얻는 생명력 : {touchIncreaseAmount}";
        upgradelifeCostText.text = $"강화 비용: {upgradelifeCost} 생명력";
    }

    // 뿌리 레벨 및 강화 비용 UI 업데이트 메서드
    public void UpdateRootLevelUI(int rootLevel, int upgradeCost)
    {
        rootLevelText.text = $"뿌리 레벨: {rootLevel}";
        rootUpgradeCostText.text = $"강화 비용: {upgradeCost} 물";
    }

    // 정령 레벨 및 강화 비용 UI 업데이트 메서드
    public void UpdateSpiritLevelUI(int spiritLevel, int upgradeCost)
    {
        spiritLevelText.text = $"정령 레벨: {spiritLevel}";
        spiritUpgradeCostText.text = $"강화 비용: {upgradeCost} 에너지";
    }

    // 터치 생산량 UI 업데이트 메서드
    public void UpdateTouchIncreaseUI(int touchIncreaseAmount)
    {
        touchIncreaseText.text = $"터치 생산량: {touchIncreaseAmount}";
    }
}

델리게이트와 이벤트 사용
LifeManager 클래스에서 델리게이트와 이벤트를 사용하여 생명력 변화 시 UI를 업데이트하도록 구현했습니다. 델리게이트는 특정 메서드를 참조할 수 있는 형식으로, 이벤트는 델리게이트를 기반으로 하여 특정 상황에서 호출되는 메서드를 처리합니다.

WaterChanged 델리게이트와 OnWaterChanged 이벤트를 사용하여 생명력이 변경될 때 이를 UI에 반영하도록 했습니다.

델리게이트와 이벤트 설명
델리게이트: 메서드 참조를 저장할 수 있는 형식으로, 특정 메서드 시그니처를 가지는 메서드를 참조할 수 있습니다.
이벤트: 델리게이트의 특별한 형태로, 클래스 외부에서 델리게이트에 직접 접근하는 것을 막고, 메서드를 안전하게 호출할 수 있도록 합니다.

델리게이트와 이벤트 사용 예시

public delegate void WaterChanged(int newAmount); // 생명력 변화 델리게이트
public event WaterChanged OnWaterChanged; // 생명력 변화 이벤트

생명력이 변경될 때마다 OnWaterChanged 이벤트를 호출하여 UI가 생명력 변화를 반영하도록 했습니다.

오늘 작업을 통해 Unity 3D 프로젝트에서 싱글톤 패턴과 델리게이트/이벤트를 사용하여 효율적으로 생명력을 관리하고, UI를 업데이트하는 방법을 배웠습니다. 이를 통해 프로젝트의 유지보수성과 확장성을 높일 수 있었습니다.

profile
게임개발자꿈나무

0개의 댓글