<구현 목록>
1. 인벤토리 아이템(itemCell) Random Create버튼을 통해 동적 생성
2. 아이템 클릭 시 Focus(체크 및 테두리)상태
3. 만약 Focus 상태인 아이템이 없을때, Auto Select 버튼 클릭시 모든 아이템 Focus.
4. 모든 아이템이 Focus 상태라면, Auto Select 버튼 클릭시모든 아이템 Focus 상태 해제.
5. 수량(item_amount)이 2개 이상일 경우 휴지통(delete 버튼) 클릭시, 수량 1 감소
6. 총 아이템 수량(? / 200)도 item_info.json 내의 item_amount(아이템 수량)에 따라 증가 및 감소
7. 버튼의 클릭에 의한 동작 시 item_info.json (인벤토리 아이템 파일) 파일 생성/파일내용 수정 및 삭제
8. 인벤토리 스크롤 뷰(Clamped)
+++++
+++++
using Newtonsoft.Json;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
public class InvenDataManager
{
public static readonly InvenDataManager Instance = new InvenDataManager();
public Dictionary<int, ItemData> dicItemDatas = new Dictionary<int, ItemData>();
public Dictionary<int, ItemInfo> dicInfoDatas = new Dictionary<int, ItemInfo>();
private InvenDataManager() { }
public void LoadItemData()
{
var asset = Resources.Load<TextAsset>("item_data");
var json = asset.text;
var datas = JsonConvert.DeserializeObject<ItemData[]>(json);
foreach (var data in datas)
{
this.dicItemDatas.Add(data.id, data);
}
Debug.LogFormat("item_data Load Complete! => Count : {0}", this.dicItemDatas.Count);
}
public void LoadInfoData()
{
string filePath = Path.Combine(Application.persistentDataPath, "item_info.json");
if (File.Exists(filePath))
{
var json = File.ReadAllText(filePath);
var datas = JsonConvert.DeserializeObject<ItemInfo[]>(json);
foreach (var data in datas)
{
this.dicInfoDatas.Add(data.id, data);
}
Debug.LogFormat("Info Load Complete! => Count : {0}", this.dicInfoDatas.Count);
}
else
{
Debug.LogFormat("Cannot find file: " + filePath + "\n" + "new item_info.json created!");
SaveInfoData();
}
}
public void SaveInfoData()
{
var Datas = this.dicInfoDatas.Values.ToArray();
var json = JsonConvert.SerializeObject(Datas);
string path = Path.Combine(Application.persistentDataPath, "item_info.json");
File.WriteAllText(path, json);
Debug.Log("item_info Save Complete!");
}
}
InvenDataManager.cs
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using TMPro;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;
public class UIInventory : MonoBehaviour
{
[SerializeField] UIInvenScrollView uIInvenScrollView;
[SerializeField] Button createBtn;
[SerializeField] Button selectBtn;
[SerializeField] Button deleteBtn;
[SerializeField] TMP_Text count;
private void Awake()
{
InvenDataManager.Instance.LoadItemData();
InvenDataManager.Instance.LoadInfoData();
}
private void Start()
{
count.text = InvenDataManager.Instance.dicInfoDatas.Values.Sum(i => i.item_amount).ToString() + " / 200";
this.createBtn.onClick.AddListener(() => {
int randomNum = Random.Range(100, 130);
//bool isItem = false;
// 딕셔너리에서 randomNum과 일치하는 id를 가진 항목 접근
if (InvenDataManager.Instance.dicInfoDatas.TryGetValue(randomNum, out ItemInfo existingItemInfo))
{
// 해당 항목의 item_amount 증가
existingItemInfo.item_amount++;
//isItem = true;
}
else
{
// 일치하는 항목이 없을 경우 새 항목 추가
ItemInfo newItemInfo = new ItemInfo
{
id = randomNum,
item_amount = 1
};
InvenDataManager.Instance.dicInfoDatas.Add(randomNum, newItemInfo);
}
// 데이터 저장
InvenDataManager.Instance.SaveInfoData();
uIInvenScrollView.UpdateUI();
count.text = InvenDataManager.Instance.dicInfoDatas.Values.Sum(i => i.item_amount).ToString()+ " / 200";
});
this.deleteBtn.onClick.AddListener(() => {
InvenCell[] invenCells = uIInvenScrollView.GetInvenCells();
Debug.Log("deleteBtn 작동");
foreach (var cell in invenCells)
{
if (cell.isSelect == true)
{
// 검색 결과를 한 번만 계산하고 재사용
var matchedItem = InvenDataManager.Instance.dicInfoDatas.FirstOrDefault(i => i.Value.id == cell.GetId());
Debug.Log(matchedItem);
// 검색된 요소가 유효한지 확인
if (matchedItem.Value != null)
{
matchedItem.Value.item_amount--;
InvenDataManager.Instance.dicInfoDatas[matchedItem.Key].item_amount = matchedItem.Value.item_amount;
if (matchedItem.Value.item_amount == 0)
{
InvenDataManager.Instance.dicInfoDatas.Remove(matchedItem.Key);
}
InvenDataManager.Instance.SaveInfoData();
uIInvenScrollView.UpdateUI();
count.text = InvenDataManager.Instance.dicInfoDatas.Values.Sum(i => i.item_amount).ToString() + " / 200";
}
}
}
});
this.selectBtn.onClick.AddListener(() =>
{
InvenCell[] invenCells = uIInvenScrollView.GetInvenCells();
if(invenCells.FirstOrDefault(c => c.isSelect == false) == null)
{
foreach (var cell in invenCells)
{
cell.focusGO.SetActive(false);
cell.isSelect = false;
}
}
else
{
foreach (var cell in invenCells)
{
cell.focusGO.SetActive(true);
cell.isSelect = true;
}
}
});
}
}
UIInventory.cs
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.U2D;
using UnityEngine.UI;
public class UIInvenScrollView : MonoBehaviour
{
[SerializeField] GameObject invenCellGO;
[SerializeField] GameObject content;
[SerializeField] private SpriteAtlas itemAtlas;
private InvenCell[] invenCells;
private void Start()
{
UpdateUI();
}
public InvenCell[] GetInvenCells()
{
return this.invenCells;
}
public void UpdateUI()
{
// 기존에 생성된 Cell을 모두 제거
foreach (Transform child in content.transform)
{
Destroy(child.gameObject);
}
// invenCells 배열 초기화 및 새로운 아이템으로 채우기
invenCells = new InvenCell[InvenDataManager.Instance.dicInfoDatas.Count];
int i = 0;
foreach (var infoData in InvenDataManager.Instance.dicInfoDatas.Values)
{
GameObject cell = Instantiate(invenCellGO, content.transform);
invenCells[i] = cell.GetComponent<InvenCell>();
string spriteName = "";
var itemData = InvenDataManager.Instance.dicItemDatas
.FirstOrDefault(item => item.Value.id == infoData.id);
// itemData에서 sprite_name을 얻어 sprite 할당
spriteName = itemData.Value.sprite_name;
invenCells[i].icon.sprite = itemAtlas.GetSprite(spriteName);
invenCells[i].amount_text.text = InvenDataManager.Instance.dicInfoDatas[itemData.Value.id].item_amount.ToString();
invenCells[i].SetId(itemData.Value.id);
i++;
}
for (int j = 0; j < invenCells.Length; j++)
{
// 현재 반복문의 인덱스를 새로운 변수에 할당
int currentIndex = j;
// 현재 인덱스에 해당하는 셀의 버튼에 이벤트 리스너 추가
invenCells[currentIndex].cellBtn.onClick.AddListener(() => {
if (invenCells[currentIndex].isSelect == true)
{
invenCells[currentIndex].focusGO.SetActive(false);
invenCells[currentIndex].isSelect = false;
}
// 현재 버튼에 해당하는 셀의 FocusGO만 활성화
invenCells[currentIndex].focusGO.SetActive(true);
invenCells[currentIndex].isSelect = true;
Debug.LogFormat("invenCells: {0} 버튼 설정", currentIndex);
});
}
}
}
UIInvenScrollView.cs
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class InvenCell : MonoBehaviour
{
private int id;
public TMP_Text amount_text;
public Image icon;
public GameObject focusGO;
public Button cellBtn;
public bool isSelect;
public int SetId(int num)
{
this.id = num;
return this.id;
}
public int GetId()
{
return this.id;
}
}
InvenCell.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ItemInfo
{
public int id;
public int item_amount;
}
ItemInfo.cs
using System;
public class ItemData
{
public int id;
public string sprite_name;
}
ItemData.cs
'산대특 > 게임 UIUX프로그래밍' 카테고리의 다른 글
[LearnUGUI] 마우스 클릭시 Hit Damage 프리팹(Prefab)으로 생성해서 띄우기 (0) | 2024.03.11 |
---|---|
[LeanUGUI] Boss의 HP 바를 Boss 위에 따라다니게 만들기 (0) | 2024.03.11 |
[LearnUGUI] 인벤토리 만들기 (2) - 데이터 연동으로 동적 인벤토리 만들기 (저장 및 불러오기) (0) | 2024.02.21 |
[LearnUGUI] 인벤토리 만들기 (1) - Grid Scroll VIew 만들기 (0) | 2024.02.18 |
[LearnUGUI] 동적 Gem ScrollView + 데이터 연동 구현하기 (0) | 2024.02.11 |