[Unity] Project. DayLight_10

Lingtea_luv·2025년 6월 29일

Project

목록 보기
36/38
post-thumbnail

Project. DayLight


저녁 시간에 이야기를 하다가 다른 팀은 회고록을 작성하고 있다는 사실을 알게 되었다. 그 외에도 개발 문서, 버그 리포트 등 다양한 문서 작업을 하고 있는 팀을 보며 우리도 해야할 것 같은 생각이 들었지만, 막상 TIL 말고도 다른 문서 작업을 하려니 엄두가 나질 않는다.

그래서 회고록은 TIl로 대체하기로 하고 대신 TIL을 쓸 때 버그 리포트와 비슷한 형식을 추가로 작성해보려고 한다. 사실 프로젝트 기간에 버그가 없는 날은 존재하지않기 때문에 매일 작성해야하지않을까.

남은 Build Issue

  1. 맵뚫 버그 → physics - Layer Collision Matrix 설정
    • 무기를 들었을 때
    • 공격하면서 이동
    • 퀵슬롯 바꾸면서 이동
    • 백점프 이동(뒤로 점프)
  2. 무한 점프 현상
  3. 캐릭터 끼임 현상(점프 lock)
  4. 플레이어 앞 뒤로 미끄러지는 현상 수정
  5. Ctrl 웅크리기 / shift 달리기 기능 추가
  6. 문열기 키 변경 KeyCode E -> F
  7. 빌드 파일에서 외곽선 출력이 안되는 현상
  8. 아이템 공격시 퀵슬롯 전환 불가능하도록 막기
  9. 총,방패 생성 위치, 방향 조정
  10. 제작 탭에서 특정 레시피 클릭시 결과 아이템 설명 텍스트 아래에 출력

작업 완료 기능

  1. 빌드 이슈 해결
  2. 몬스터 공격 로직 수정, 빌드 버그 수정
  3. 사용 아이템 구현(포션, 음식, 음료)
  4. 랜덤 아이템 루트 테이블 생성 기능 구현
  5. 사용 아이템 -> 플레이어 파라미터 연동

작업 중 기능

  1. 근접 무기 플레이어 공격속도 반영
  2. 아이템 드랍 테이블 로직 연동, 루팅 시스템 마무리
  3. 파라미터 자연 회복 로직 연동
  4. 몬스터 프리팹 생성

공유 코드

이번에 공유하려는 코드는 랜덤 드랍 테이블 생성 기능으로, 몬스터에 드랍테이블을 설정할 때 고정된 아이템만 나오는 것이 아니라, 후보 아이템 중에 랜덤으로 드랍되는 기능이다.

RandomLootTable class

랜덤 드랍 테이블을 설정하기 위한 필드와 메서드를 가지는 클래스로, CSV 파일을 바탕으로 만든 아이템과 루트 테이블 데이터를 참조하며, 루트 테이블의 id를 입력하여 개별적인 랜덤 드랍 테이블을 설정하는 것이 가능하다.

public class RandomLootTable : MonoBehaviour
{
	// 생성에 사용될 Dictionary 데이터
    [SerializeField] private LootDictionary _lootDic;
    [SerializeField] private ItemDictionary _itemDic;
    
    // 인스펙터 상에서 입력할 테이블 ID
    [SerializeField] private string _id; 
    
    // 루트 테이블 데이터를 세분화하여 저장
    private List<int> _itemId;
    private List<int> _itemStack;
    private List<int> _itemWeight;

    private int _itemCount;

    public List<ItemBase> _resultItems;
    public List<int> _resultItemAmount;
    
    private void Start()
    {
        Init();
        int gridNum = SetGridAmount();
        SetItem(gridNum);
    }
    
    private void Init(){}
    
    private int SetGridAmount(){}
    
    private void SetItem(){}
}

Init Method

루트 테이블을 세분화하는 작업과 루트 테이블에 포함된 아이템의 수를 저장한다.

private void Init()
{
    _itemId = new List<int>();
    _itemStack = new List<int>();
    _itemWeight = new List<int>();

    for (int i = 0; i < _lootDic.LootTable[_id].Count; i+=3)
    {
    	// 테이블에 포함된 아이템 별 ID
        _itemId.Add(_lootDic.LootTable[_id][i]);
        // 테이블에 포함된 아이템 별 드랍 수량
        _itemStack.Add(_lootDic.LootTable[_id][i+1]);
        // 테이블에 포함된 아이템 별 가중치
        _itemWeight.Add(_lootDic.LootTable[_id][i+2]);
    }
    
	// 테이블에 포함된 아이템 수
    _itemCount = _itemId.Count;
}

SetGridAmount Method

드랍될 아이템의 수를 결정하는 메서드로 가중치에 따라 0~6 사이의 숫자를 반환한다.

private int SetGridAmount()
{
	// 아이템 수에 대한 가중치를 저장한 데이터
    int volume = _lootDic.LootGridTable[_id].Count;
    
    // 난수와 비교하기 위한 가중치 합을 저장할 배열 
    int[] weightSums = new int[volume];
    for (int i = 0; i < volume; i++)
    {
        for (int j = 0; j < i + 1; j++)
        {
            weightSums[i] += _lootDic.LootGridTable[_id][j];
        }
    }
    
    // 모든 가중치를 더한 값을 최대로 한 난수 생성
    int rndNum = Random.Range(0, weightSums[volume - 1]);
        
    // 루트 테이블에 포함된 아이템 숫자와 비교하여 드랍될 아이템 수 결정 
    for (int i = 0; i < volume; i++)
    {
        if (rndNum < weightSums[i]) return i < _itemCount ? i : _itemCount;
    }

    return -1;
}

SetItem Method

드랍될 아이템의 수가 결정되면, 어떤 아이템을 드랍할 것인지 정해주는 메서드

private void SetItem(int volume)
{
	// 드랍할 아이템을 저장하는 List
    _resultItems = new List<ItemBase>();
    // 드랍할 아이템의 수량을 저장하는 List
    _resultItemAmount = new List<int>();
    
    // 추가할 아이템의 수
    int remaining = _itemCount;
    
    // 추가할 아이템이 남아있으면
    while (remaining > 0)
    {
    	// 남은 아이템이 없으면 반복문 종료
        if (_itemId.Count == 0) break;
        
        // 가중치 합 저장
        int[] weightSums = new int[remaining];
            
        for (int i = 0; i < remaining; i++)
        {
            for (int j = 0; j < i + 1; j++)
            {
                weightSums[i] += _itemWeight[j];
            }
        }
        
        // 0과 모든 가중치를 더한 값 사이의 난수 생성
        int rndNum = Random.Range(0, weightSums[remaining - 1]);
            
        for (int i = 0; i < remaining; i++)
        {	
        	// 가중치에 따라 아이템이 정해지면
            if (rndNum < weightSums[i])
            {
            	// 드랍할 아이템 저장
                _resultItems.Add(_itemDic.ItemDic[_itemId[i]]);
                // 드랍할 아이템 수량 저장
                _resultItemAmount.Add(_itemStack[i]);
                
                // 해당 아이템 제거
                _itemId.Remove(_itemId[i]);
                _itemStack.Remove(_itemStack[i]);
                _itemWeight.Remove(_itemWeight[i]);
                
                // 남은 수량 -1
                remaining--;
                break;
            }
        }
    }
}
profile
뚠뚠뚠뚠

0개의 댓글