250306 TIL

박소희·2025년 3월 6일

Unity_7기

목록 보기
41/94

과제

  1. 낙하 피해 구현
    플레이어가 땅에 있지 않는 시간이 제한 시간보다 많을 때 데미지 입음.
private void CalFallDamage()
{
    if (!CharacterManager.Instance.Player.controller.IsGrounded())
    { // 공중에 떠 있을 때
        fallTime += Time.deltaTime;
    }
    else // 착지 시
    {
        if(fallTime >= fallDamageThreshold)
        {
            float damage = fallTime * fallDamageCal;
            TakeDamage(damage);
        }
        fallTime = 0f; // 낙하 시간 초기화
    }
}

public void TakeDamage(float damage)
{
    health.Subtract(damage);
    onTakeDamage?.Invoke();
}
  1. 아이템 구현
    SO로 아이템 데이터를 저장한다.
[CreateAssetMenu(fileName = "Item", menuName = "New Item")]
public class ItemData : ScriptableObject
{
    [Header("Info")]
    public string displayName;
    public string description;
    public Sprite icon;
    public GameObject dropPrefab;

    [Header("Stacking")]
    public bool canStack;
    public int maxStackAmount;
    
}
  1. 인벤토리 구현
    아이템을 저장할 ItemSlot을 만들고, UIInventory에서 관리한다.
    UIInventory에서는 인벤토리에 아이템 추가, 버리기, 선택 등을 구현한다.
    public void ThrowItem(ItemData item)
    {
        Instantiate(item.dropPrefab, dropPosition.position, Quaternion.Euler(Vector3.one * UnityEngine.Random.value * 360));
    }
    public void AddItem()
    {
        ItemData data = CharacterManager.Instance.Player.itemData;
        if (data.canStack)
        {
            ItemSlot slot = GetItemStack(data);
            if (slot != null)
            {
                slot.quantity++;
                UpdateUI();
                CharacterManager.Instance.Player.itemData = null;
                return;
            }
        }

        ItemSlot emptySlot = GetEmptySlot();

        if (emptySlot != null)
        {
            bool isEmpty = !HasAnyItem();
            emptySlot.data = data;
            emptySlot.quantity = 1;
            UpdateUI();
            CharacterManager.Instance.Player.itemData = null;
            if (isEmpty) SelectItem(0);
            return;
        }

        ThrowItem(data);
        CharacterManager.Instance.Player.itemData = null;
    }

    public void SelectItem(int index)
    {
        for (int i = 0; i < slots.Length; i++)
        {
            if (selectedItem != null && i != index)
            {
                slots[i].Select(false); 
            }
        }
        selectedItem = slots[index];
        selectedItem.Select(true);
        selectedItemIndex = index;
    }
  1. 인벤토리 내 아이템 선택
  • 문제
    스크롤하여 인벤토리 내 아이템을 선택할 수 있게 했는데, 휠을 한 번 내려도 두 번 이상 슬롯의 인덱스가 이동했다.
 public void OnScroll(InputAction.CallbackContext context)
 {
     if (hasItem)
     {
         if (context.phase != InputActionPhase.Performed) return;
         float scrollValue = context.ReadValue<Vector2>().y;

         if (scrollValue > 0)
         {
             ChangeSelectedItem(1);
         }
         else if (scrollValue < 0)
         {
             ChangeSelectedItem(-1);
         }
     }
 }
  • 해결
    Performed 조건을 추가해 중복 입력을 방지해줬다.

0개의 댓글