[Toy][Unity] 아이템 드롭 시스템

0시0분·2023년 11월 22일
0

Toy

목록 보기
4/18

나무가 다 자라면 상호작용을 통해 열매와 씨앗을 드랍할수 있도록 했다.
(🌜❗ 다른 더 좋은 방법이 있을수도 있다 ❗🌜)


1. 나무 오브젝트

1-1. 오브젝트 데이터

ScriptableObject를 사용해 GrowItemData 클래스를 만들었다.
나무 오브젝트(GrowingItem)는 공통적으로 GrowItemData 를 가진다.

🎈 Drop Item List : 드롭할 아이템의 목록
🎈 Drop Item Cnt : 드롭할 아이템의 개수
🎈 Grow Up Sprites : 자라나는 각 단계의 이미지

1-2. 아이템 드롭

아이템 드랍은 나무를 중심으로 1칸 이내에서 발생하기 때문에
미리 드롭 가능 개수만큼 아이템의 오브젝트 풀을 생성했다.

void SetDropItems()
{
	for (int i = 0; i < itemData.DropItemList.Count; ++i)
    {
    	GameObject item = Resources.Load<GameObject>(ClientUtil.PrefabPath + itemData.DropItemList[i]);
        item.GetComponent<DroppableItem>().m_parent = this;
        CreateObjectPool(item, itemData.DropItemCnt[i]);
    }
}

현재는 아이템의 최대 드롭 개수를 DropItemCnt 만큼으로 제한을 해뒀기에 위 코드처럼 사용했지만,
추가 드롭(이미 드롭된 아이템이 존재하는 상황에서 새로 드롭이 가능하게 하는 경우)이 가능하도록 수정할 경우에는 변경해야한다.

이전에 올렸던 <타일맵 랜덤 좌표에 아이템 생성>을 조금 수정해서 나무 위치를 중심으로 반경 1칸 이내에 아이템이 생성될 수 있도록 했다.

🔽 랜덤 좌표 생성 코드

/// <summary>
/// 기준점 (basePos) 을 중심으로 주변 1칸 이내 랜덤 좌표 생성
/// </summary>
/// <param name="coords"> 배치 된(될) 타일 좌표 </param>
/// <param name="basePos"> 아이템 스폰할 오브젝트의 위치 </param>
/// <param name="cnt"> 생성할 좌표의 총 개수 : 새로 생성한 좌표 (newCoords) + 생성되어있는 좌표 (coords) </param>
/// <returns></returns>
public List<Vector2> CalcRandomCoords(List<Vector2> coords, Vector3 basePos, int cnt)
{
    int range = 1;

    List<Vector2> newCoords = new List<Vector2>();

    int minX = Mathf.FloorToInt(basePos.x) - range;
    int maxX = Mathf.CeilToInt(basePos.x) + range;
    int minY = Mathf.FloorToInt(basePos.y) - range + (int)m_tileSize;
    int maxY = Mathf.CeilToInt(basePos.y) + range + (int)m_tileSize;

    while (newCoords.Count + coords.Count < cnt)
    {
        int x = Random.Range(minX, maxX);
        int y = Random.Range(minY, maxY);

        Vector2 newPos = new Vector2(x, y);

        Vector2 baseCoord = new Vector2(Mathf.FloorToInt(basePos.x), Mathf.FloorToInt(basePos.y) + (int)m_tileSize);
        if (newPos.Equals(baseCoord))	//  나무 위치에 생성되는것 방지
            continue;

        if (coords.Contains(newPos) || newCoords.Contains(newPos))
            continue;

        newCoords.Add(newPos);
    }

    return newCoords;
}

🔽 아이템 드롭 코드

public void SpawnDropItems()
{
    List<Vector2> newPos = MapManager.Inst.CalcRandomCoords(m_dropPosList, transform.position, m_dropCnt);

    for (int i = 0; i < newPos.Count; ++i)
    {
        for (int j = 0; j < m_dropObjPool.Count; ++j)
        {
            if (m_dropObjPool[j].activeSelf)    continue;

            m_dropObjPool[j].transform.position = newPos[i];
            m_dropObjPool[j].SetActive(true);
            break;
        }
    }

    m_dropPosList.AddRange(newPos);
}

드롭된 아이템의 좌표는 중복된 위치에 생성하는것을 방지하기 위해 리스트로 저장한다.

1-3. 오브젝트 자라기

void GrowUp()
{
    m_spriteRenderer.sprite = itemData.GrowUpSprites[m_growUpIdx++];
    if (m_growUpIdx >= itemData.GrowUpSprites.Count)
    {
        m_needHarvest = true;
        m_growUpIdx = 0;
    }

    m_timeSpan = 0f;
}

itemData.GrowUpSpeed 에 지정된 시간에 따라 성장 단계에 맞게 Sprite가 변경된다.
아이템 드랍 상호작용은 나무가 다 자란 이후에만 가능하도록 했다.


2. 열매(씨앗) 오브젝트

2-1. 아이템 획득 처리

public void I_Collect()
{
    gameObject.SetActive(false);

    QuickSlotUI quickSlotUI = UIManager.Inst.GetUI("QuickSlotUI") as QuickSlotUI;
    quickSlotUI.AddItem(this);
    m_parent.DropItemCollected((Vector2)transform.position);
}

퀵슬롯을 호출해 AddItem 처리를 하고, parent인 나무 오브젝트에 해당 위치에서 제거됐음을 알린다. (해당 위치에 다른 아이템을 드롭할수 있도록)

0개의 댓글