이전에 아이템을 습득하고, 그 아이템이 인벤토리로 들어가는 과정까지 코딩했다.
그럼 이제 플레이어가 인벤토리에서 아이템을 볼 수 있도록 하는 기능을 추가해보자.
일단 PlayerManager에 다음과 같이 코드를 추가하자.
//중략
[SerializeField] GameObject inventoryUI;
void Update()
{
//중략
if(Input.GetKeyDown(KeyCode.I)){
OpenInventory();
}
}
//인벤토리 여는 함수 추가
void OpenInventory(){
if(inventoryUI.activeSelf){
inventoryUI.SetActive(false);
}
else{
inventoryUI.SetActive(true);
}
}
//아이템 습득
private void OnTriggerStay2D(Collider2D other) {
//중략
}
}
중략된 내용 잘 보고, 위치 잘 보고 코드를 추가해주자.
일단, Input.GetKeyDown을 사용한 이유는 Update문에 넣었기 때문에, GetKey로 사용한다면 I가 눌려있는 도중에 계속 꺼졌다, 켜졌다 할것이다. 그래서 누르는 순간 한번만 호출되는 GetKeyDown을 사용하였다.
인벤토리 오브젝트를 넣을 inventoryUI 게임 오브젝트 변수를 추가해주고, 인스팩터창에서 인벤토리 오브젝트를 추가해주어야한다.
인벤토리 여는 함수는 따로구현해 분리해두었다.
이렇게 추가해주면 된다.
이후, 게임을 실행시키고 i버튼을 누르면 인벤토리가 열릴것이다.
만약 안열린다면 한/영키를 누른 후, 다시 실행해보자. 한글일 경우에는 인벤토리가 안켜질 수 있다.
이제 인벤토리 내부를 코딩해주자.
일단 인벤토리의 특성은
아이템을 습득했을 때, 아이템이 인벤토리에 떠야한다.
그리고, 우리가 인벤토리를 켰을 때, 게임이 멈추는게 아니므로, 인벤토리를 켜둔 상태에서 플레이어가 움직여 아이템을 습득한다면, 인벤토리에서 습득한 아이템이 자동으로 업데이트되어야 한다.
이 두가지를 염려해두고 코딩을 해보자.
일단 우리가 저번 인벤토리 구현때, UI는 구현해뒀지만, 인벤토리에 들어갈 슬롯은 구현 안해뒀다.
이 슬롯도 구현해줘야한다.
여기서는 오브젝트 풀링 기법을 사용해보려 한다.
[Unity] 오브젝트 풀링
0. 오브젝트 풀링이란? 오브젝트 풀링은 말 그대로 객체 수영장이라는 뜻이다. 예를 들어 수 많은 오브젝트를 생성해야하는 탄막슈팅게임 (이러한 게임에서는 수 많은 총알들을 생성해야 한다...
freeedeveloper.tistory.com
오브젝트 풀링은 미리 오브젝트를 만들어두고, 이 오브젝트를 켰다 껐다 하면서 생성, 파괴를 하는 방법이다.
좋은점은, 생성, 파괴할때 메모리적으로 문제가 생길 수 있는데 수가 적으면 상관 없지만 수가 많으면 낭비되는 메모리가 많이 발생하기 때문이다. (가비지콜랙팅에 의한 프레임 드랍이 생길 수 있다. 위의 링크를 참고하자.)
일단, UI아래에 Pooling이라는 오브젝트를 추가해준 뒤, Slot이란 오브젝트도 추가해주고, 슬롯을 여러개 만들어두자.
이런식으로 구성했다.
Slots 하위의 Image라는 오브젝트는 크기가 200 * 200이다. 그리고 이름을 Slot으로 바꿔주자.
이렇게 작업하고, 아이템과 동일하게 slot을 프리팹으로 만들어주자.
오브젝트 풀링 매니저를 만들어주자.
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
public class ObjectPoolingManager : MonoBehaviour
{
public static ObjectPoolingManager Instance;
#region slot
[SerializeField] GameObject slotPrefab;
[SerializeField] GameObject slotParent;
public Queue<GameObject> slotQueue = new Queue<GameObject>();
#endregion
private void Awake() {
if(Instance == null){
Instance = this;
}
}
private void Start() {
//slot 오브젝트 2000개 미리 생성
for(int i = 0; i< 2000;i++){
GameObject slot = Instantiate(slotPrefab, new Vector3(this.transform.position.x, this.transform.position.y, 0f), Quaternion.identity, slotParent.transform);
slot.SetActive(false);
slotQueue.Enqueue(slot);
}
}
public void InsertQueue(GameObject go, Queue queue){
queue.Enqueue(go);
go.SetActive(false);
}
public GameObject GetQueue(Queue<GameObject> queue){
GameObject go = queue.Dequeue();
go.SetActive(true);
return go;
}
}
코드에 대한 설명은 위의 링크를 참고하자.
여기서 링크와 다르게 수정된 부분은, slot을 위한 Queue를 따로 설정해줬다.(혹시나 다른 오브젝트 풀링을 사용할 수도 있으니 미리 작업한것이다.)
그리고 InsertQueue와 GetQueue의 구조도 살짝 변경되었는데, 여러개의 큐가 생성될 수도 있기 때문에 함수에서 사용할 큐를 받아오고 있다. (싱글톤 구조이기때문에 어디서든 public으로 선언된 큐에 접근할 수 있어서 필요한 큐를 언제든지 불러와 함수에 넣어주면 된다.)
이렇게 코딩해준 스크립트는 아까 만들어뒀던 PoolingObj 오브젝트에 붙여주자.
이렇게 붙여주고 아까 만들어둔 변수들도 넣어준 뒤, 실행해보면, 미리 생성되는 오브젝트들이 잘 보일것이다.
우리는 이제 이걸 사용해 인벤토리를 구현해줄것이다.
인벤토리를 켜고 끌때, 위의 슬롯을 불러오고 해당하는 스크롤 뷰로 이동시키는 작업을 할것이다.
이동할 때, 하나씩 꺼내서, GameManager의 Inventory 리스트에서 하나씩 검색하여 아이템 이미지를 바꿔주는 작업을 할 것이다.
우리가 아이템 습득을 구현할 때 print로 뒀던 부분이 있다.
//아이템 습득
private void OnTriggerStay2D(Collider2D other) {
if(other.tag == "Item"){ //태그 확인
if(Input.GetKey(KeyCode.Space)){ //아이템 습득 키 확인
GameManager.Instance.AddInventoryItem(other.GetComponent<ItemManager>().ReturnItem()); //인벤토리에 아이템 추가
print("아이템 획득함");
Destroy(other.gameObject); //인벤토리에 추가해줬으니, 오브젝트를 삭제
}
}
}
저 Print함수를 수정해 다음과 같이 만들어주자.
//아이템 습득
private void OnTriggerStay2D(Collider2D other) {
if(other.tag == "Item"){ //태그 확인
if(Input.GetKey(KeyCode.Space)){ //아이템 습득 키 확인
GameManager.Instance.AddInventoryItem(other.GetComponent<ItemManager>().ReturnItem()); //인벤토리에 아이템 추가
GameObject go = ObjectPoolingManager.Instance.GetQueue(ObjectPoolingManager.Instance.slotQueue); //미리 만들어둔 오브젝트를 가져옴
go.GetComponent<Image>().sprite = other.GetComponent<SpriteRenderer>().sprite;
go.transform.SetParent(GameManager.Instance.cropsParent);
Destroy(other.gameObject); //인벤토리에 추가해줬으니, 오브젝트를 삭제
}
}
}
일단 Gamemanager의 inventory에도 아이템을 추가해주고, 이전에 만들어뒀던 풀링 오브젝트를 하나 가져와서 이미지를 교체해준다.
GameManager에 추가해주는 이유는, 추후에 우리가 저장 기능을 구현할 때 사용하려고 한다.
이후, parent를 변경해줘야한다.
public class GameManager : MonoBehaviour
{
#region Instance
//중략
#endregion
#region Parents
public Transform cropsParent;
#endregion
//중략
}
GameManager에서 Parent를 만들어주고, 이 오브젝트에는 Crop의 콘텐츠를 담을 오브젝트를 추가해주자.
이렇게 해두고, Setparent를 사용해 오브젝트를 스크롤 뷰에 넣은것이다.
이렇게 하면 다음과 같이 된다.
이렇게 아이템을 인벤토리에 넣는 작업은 완료했다.
이제 인벤토리에 들어간 아이템을 조금 더 손봐야한다.
아직 작물이 여러개인경우와 이미지를 띄우는 방법, 아이템 종류별로 넣기 등등 할일이 태산이다!
다음은 슬롯으로 만들어 뒀던 프리펩을 조금 더 손볼것이다.
'Develop > 마음대로 만드는 게임' 카테고리의 다른 글
[NProject] 마음대로 만드는 게임 - 13. 슬롯 수정2 (0) | 2024.05.21 |
---|---|
[NProject] 마음대로 만드는 게임 - 12. 슬롯 수정 1 (0) | 2024.05.20 |
[NProject] 마음대로 만드는 게임 - 10. 아이템을 만들어 보자! 4 (0) | 2024.05.20 |
[NProject] 마음대로 만드는 게임 - 9. 아이템을 만들어 보자! 3 (0) | 2024.05.20 |
[NProject] 마음대로 만드는 게임 - 8. 아이템을 만들어 보자! 2 (0) | 2024.05.16 |