Unity/Project

[Unity] 내배캠 최종프로젝트 : 루시퍼 서바이벌 22일차,

JEE_YA 2025. 5. 8. 22:21

오늘은 정말 집중해서 코드만 작성한다 했는데 같은길을 빙글빙들 돌아서 그런지

RewardManager의 자원 부분은 금요일, 그러니까 내일까지는 끝내고 싶은데 가능하면서도 어렵나 생각이 들기 시작했다.

 

일단 구글시트에 자원에 대해 IDX같은 부분을 제외하면 

displayName(성공~실패 등), probability(확률), gain(보상 갯수) 이며 확률은 총합 100으로 되어있다.

리스트에 있는걸 받아와서 결과에 따라 보상량이 정해지고 그 보상량을 획득할 수 있게 하는게 내가 지금 하고자 하는 흐름인데 

어느정도는 구현해 두었다.

 

일단 ResourceTile을 만들어 자원 프리펩에 붙여주었다.

public class ResourceTile : BaseInteractable
{
    public override void Interact(PlayerEntity player)
    {
        GatherTile();
    }

    public void GatherTile()
    {
        RewardManager.Instance.TryGatherResource();
    }
}

플레이어가 상호작용을 할 수 있게 BaseInteractable을 플레이어 담당 조원분께서 만들어주셔서 위와 같이 상호작용 메서드를 추가해주었다.

 

public class RewardManager : Singleton<RewardManager>
{
    [SerializeField] private List<FarmingDataSO> resultTable;
    private bool hasInteracted = false; // 상호작용 횟수 체크용


    // 채집시도 상호작용
    public void TryGatherResource()
    {
        // 이미 상호작용이 이루어졌다면 더 이상 처리하지 않음
        if (hasInteracted)
        {
            Debug.Log("횟수초과");
            return;
        }

        var result = GetRandomFarmingResult();
        Debug.Log($"결과: {result.displayName}, 보상: {result.gain}");

        GiveReward(result.gain);

        hasInteracted = true;
    }

    // 확률에 따른 결과 선택 (총 확률 100 기준)
    private FarmingDataSO GetRandomFarmingResult()
    {
        // 0-100 사이의 난수 생성
        float rand = UnityEngine.Random.Range(0f, 100f);
        float current = 0f;

        foreach (var entry in resultTable)
        {
            if (entry == null)
            {
                Debug.LogError("resultTable에 null이 들어있어요!");
                continue;
            }

            current += entry.probability;

            // 현재 누적확률보다 작을경우
            if (rand <= current)
            {
                return entry;
            }
        }

        return resultTable.Last(); // 어떤 항목도 선택되지 않았을 경우 방지, 리턴
    }

    // 보상
    private void GiveReward(int amount)
    {
        // 게임 내 보상처리
    }
}

일단 확률이 담긴 FarmingDataSO 리스트를 resultTable로 인스펙터에서 넣어주고 hasInteracted 를 통해 자원 하나당 한번만 상호작용 가능하게 제한했다.

 

TryGatherResource()는 자원을 캘때 호출되는 함수다. 이미 채집한 자원이라면 hasInteracted를 통해 중복 채취를 막고, 랜덤한 결과를 얻어 그에따른 보상을 지급해준다.

 

GetRandomFarmingResult()는 리스트를 순회하며 랜덤값이 해당 누적 확률 이하일때 결과를 리턴하며 혹시라도 모든 조건을 못지나칠 경우를 대비해 마지막 항목을 리턴하는 안전장치도 해두었다.

 

그리고 아직 보상에 대한 것은 어디로 가야하는지 몰라 GiveReward는 비워두었다......

 

 

이제 여기서 수정해야 할 부분은

1. foreach를 사용하기 보다 다른 방법을 찾아서 리팩토링 할것,

2. 상호작용한 자원의 프리펩 색을 변경할것

 

이 두가지이며 foreach를 사용하지 않는 이유는 GetRandomFarmingResult()에선 리스트를 전체 순회(foreach)하면서 누적 확률을 계산하고 있는데 항목 수가 많아질 경우 성능에 영향을 줄 수 있어 이부분은 다른방식으로 개선하고자 한다.

딕셔너리나 리스트 등을 이용하여 개선하려고 하는데 이부분은 조금 더 고민해봐야 할듯 하다..

 

자원 프리펩 색은 TileManager에서 관리하고 있기에 RewardManager보단 TileManager에서 처리하는게 맞다고 생각되는데 어떤식으로 연결하고 작성해야 할지 생각중인데 이부분도 생각보다 쉬울줄 알았으나 한 스크립트 안에서 처리하는게 아니라 살짝 헤메는 기분이다.. 

 

이렇게 하고 전체적으로 작성햇던 코드들을 리팩토링 하면 지금까지 작성했던 부분에 대해서는 어느정도 마무리 될듯 하며

이걸 이번주 안으로 해내는게 목표인데 파이팅하자, 할수있따!

 

- 이후 자동파밍에 대해서도 기획자분과 상의하여 어떤식으로 해야할지 구상하고 작성해볼 예정