본문 바로가기
TIL

[멋쟁이사자처럼 부트캠프 TIL 회고] 유니티 게임개발 3기 20일차 2D게임 제작(3)

by HYttt 2024. 12. 17.

아이템 인벤토리

  • 아이템을 획득하면 인벤토리에 수량과 함께 표시하도록 구현

  • UI캔버스에 인벤토리 추가
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[CreateAssetMenu(fileName = "ItemData", menuName = "Datas/ItemData")]
public class ItemData : ScriptableObject
{
    public string itemName;
    public Sprite icon;
}
public class ItemInfo
{
    public ItemData itemData;
    public int amount;
}
public class ItemManager : MonoBehaviour
{
    public List<ItemData> itemDatas = new List<ItemData>();
    
}
  • 아이템 데이터를 저장할 Scriptable Object 생성
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ItemGetter : MonoBehaviour
{
    public RectTransform itemRectTransform;
    public Canvas canvas;
    public GameObject itemPrefab;
    public GameObject getEffectPrefab;
    public Inventory inventory;

    public Camera camera;

    public AnimationCurve curve = AnimationCurve.Linear(0, 0, 1, 1);
    
    private float EaseInOut(float t)
    {
        return t < 0.5f ? 2f * t * t : -1f + (4f - 2f * t) * t;
    }
    IEnumerator GoingToBox(RectTransform itemTransform, RectTransform boxTransform)
    {
        float duration = 1.0f;
        float t = 0.0f;

        Vector3 itemBeginPOS = itemTransform.position;
        
        while (1.0f >= t / duration)
        {
            Vector3 newPosition = Vector3.Lerp(itemBeginPOS, 
                boxTransform.position, curve.Evaluate(t / duration));

            itemTransform.position = newPosition;
            
            t += Time.deltaTime;
            yield return null;
        }

        itemTransform.position = boxTransform.position;
        
        inventory.AddItem(itemTransform.GetComponent<GotObject>());
        Destroy(itemTransform.gameObject);
        
        var particle = Instantiate(getEffectPrefab, boxTransform.position,getEffectPrefab.transform.rotation);
        var vector3 = particle.transform.position;
        vector3.z = 0.0f;
        particle.transform.position = vector3;
        Destroy(particle, 3.0f);
        
    }
    private void OnTriggerEnter2D(Collider2D other)
    {
        Debug.Log(other);
        
        var newObject = Instantiate(itemPrefab, 
            other.transform.position, Quaternion.identity, canvas.transform);
        newObject.GetComponent<GotObject>().SetItemData(other.GetComponent<SpawnedItem>().itemData);
        newObject.transform.position = other.transform.position;
        var newScreenPosition = Camera.main.WorldToScreenPoint(newObject.transform.position);
        Vector2 localPoint;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(
            canvas.GetComponent<RectTransform>(), newScreenPosition, camera, out localPoint);
        newObject.transform.localPosition = localPoint;
        
        StartCoroutine(GoingToBox(newObject.GetComponent<RectTransform>(), itemRectTransform));
        Destroy(other.gameObject);
    }
}
using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using Random = UnityEngine.Random;

public class Inventory : MonoBehaviour
{
    [SerializeField]GridLayoutGroup gridLayoutGroup;
    private ItemButton[] buttons;

    private int selectedItemIndex1 = -1;
    private int selectedItemIndex2 = -1;
    private void Awake()
    {
        buttons = gridLayoutGroup.
            GetComponentsInChildren<ItemButton>();

        // ItemManager itemManager = FindObjectOfType<ItemManager>();
        for (var i = 0; i < buttons.Length; i++)
        {
            var i1 = i;
            buttons[i].GetComponent<Button>().
                onClick.AddListener(() => 
                    OnClickItemButton(i1)
                );
        }
    }
    public void AddItem(GotObject item)
    {
        for (var i = 0; i < buttons.Length; i++)
        {
            if (buttons[i].ItemInfo == null)
            {
                buttons[i].ItemInfo = new ItemInfo() { itemData = item.ItemData, amount = 1 };
                var amountTxt = buttons[i].GetComponentInChildren<TMP_Text>();
                amountTxt.enabled = true;
                amountTxt.text = buttons[i].ItemInfo.amount.ToString();
                break;
            }
            if (buttons[i].ItemInfo.itemData.Equals(item.ItemData))
            {
                buttons[i].ItemInfo.amount += 1;
                var amountTxt = buttons[i].GetComponentInChildren<TMP_Text>();
                amountTxt.text = buttons[i].ItemInfo.amount.ToString();
                break;
            }
        }
    }
    void OnClickItemButton(int index)
    {
        if (0 > selectedItemIndex1)
        {
            selectedItemIndex1 = index;
        }
        else if (0 > selectedItemIndex2)
        {
            selectedItemIndex2 = index;
        
            var itemInfo1 = buttons[selectedItemIndex1].ItemInfo;
            var itemInfo2 = buttons[selectedItemIndex2].ItemInfo;
            buttons[selectedItemIndex1].ItemInfo = itemInfo2;
            buttons[selectedItemIndex2].ItemInfo = itemInfo1;
            selectedItemIndex1 = -1;
            selectedItemIndex2 = -1;
        }
    }
}

 

몬스터 충돌과 넉백

  • 플레이어와 몬스터 하위에 충돌을 확인하는 오브젝트를 추가하고 콜라이더 컴포넌트를 추가한다

  • 몬스터쪽 오브젝트에는 Rigidbody2D도 추가하고 BodyType을 Kinematic으로 변경한다.
  • 플레이어의 콜라이더는 IsTrigger를 체크한다.

  • 플레이어와 몬스터의 레이어 마스크를 설정한다. 
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class HitCollision : MonoBehaviour
{
    [NonSerialized] public Rigidbody2D parentRigidbody;

    void Start()
    {
        parentRigidbody = GetComponentInParent<Rigidbody2D>();
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Monster : MonoBehaviour
{
    private SpriteRenderer _spriteRenderer;
    private Animator _animator;
    private Rigidbody2D _rigidbody;

    public float Speed = 5.0f;
    public int switchCount = 0;
    private int moveCount = 0; 
    
    public Vector2 _direction;
    
    private LayerMask playerlayerMask;
    void Start()
    {
        _spriteRenderer = GetComponent<SpriteRenderer>();
        _animator = GetComponent<Animator>();
        _rigidbody = GetComponent<Rigidbody2D>();
        playerlayerMask = LayerMask.NameToLayer("Player");
    }
    
    void FixedUpdate()
    {  
        transform.position += new Vector3(_direction.x * Speed * Time.deltaTime, 0, 0);

        moveCount++;

        if (moveCount >= switchCount)
        {
            _direction *= -1;
            _spriteRenderer.flipX = _direction.x < 0;
            moveCount = 0;
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MonsterHitCollision : MonoBehaviour
{
    public float power = 500f;
    void OnTriggerEnter2D(Collider2D other)
    {
        Rigidbody2D rb = other.GetComponent<HitCollision>().parentRigidbody;
    
        Vector3 backPosition =  rb.transform.position - transform.position;
        backPosition.Normalize();
        backPosition.x *= 3;
        rb.AddForce(backPosition * power, ForceMode2D.Force);
    }
}