일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 앱 배포
- 유니티 GUI
- 연습
- Photon Fusion
- 팀 프로젝트
- 유니티 Json 데이터 연동
- 가상현실
- 모작
- 유니티 UI
- meta xr
- CGV
- 오브젝트 풀링
- 포트폴리오
- HAPTIC
- 오큘러스
- Oculus
- meta
- 팀프로젝트
- OVR
- VR
- XR
- 길건너 친구들
- input system
- ChatGPT
- 드래곤 플라이트 모작
- 드래곤 플라이트
- 개발일지
- 유니티
- 개발
- 멀티플레이
- Today
- Total
EasyCastleUNITY
골드 상점 GUI 본문
정적 스크롤 뷰를 사용한 골드를 파는 상점 UI를 만들어 보려고 한다.
먼저 기본 바탕인 정적 스크롤 뷰를 만들고 그 안에 각각의 셀들을 만들려고 한다.
scrollview에 Scroll Rect 컴포넌트 부여하고, 이 컴포넌트의 content 속성의 만들어둔 content를 할당한다.
이 다음에 scrollview에 Mask 컴포넌트를 할당한다.
이런 과정을 거치면 정적 스크롤뷰가 완성된다.
이제 content의 자식으로 들어갈 UIGoldCell을 만들어 보겠다.
guide 이미지를 바탕으로 필요한 리소스를 가져와 만들었다.
이름과 구매하는 골드의 양을 표시하는 텍스트의 색은 각각
이름 텍스트 색상 BEB5B6 , 골드 텍스트 색상 FFBC12 이다 (헥사코드)
각각 들어갈 이미지들은 전부 Native Size를 사용한다.
씬 구조
이러한 구조로 만들기로 하였다.
제일 상위가 UIMain이고 UIPageGoldShop->UIScrollView -> UIGoldCell 순이다.
따라서 필요한 스크립트는 총 4개이다.
데이터 테이블
데이터 연동을 통해 만들것이므로 데이터 테이블이 필요하다.
이름과 골드 이미지 변경을 위한 스프라이트 이름, 골드의 양, 가격 등의 정보를 저장하도록 만들었다.
만든 json 파일
[
{
"id": "10000",
"name": "Tiny of Gold",
"sprite_name": "set_icon_gold_0",
"gold_amount": "240",
"price": "1.99"
},
{
"id": "10001",
"name": "Fistful of Gold",
"sprite_name": "set_icon_gold_1",
"gold_amount": "650",
"price": "4.99"
},
{
"id": "10002",
"name": "Pouch of Gold",
"sprite_name": "set_icon_gold_2",
"gold_amount": "1500",
"price": "9.99"
},
{
"id": "10003",
"name": "Box of Gold",
"sprite_name": "set_icon_gold_3",
"gold_amount": "3000",
"price": "24.99"
},
{
"id": "10004",
"name": "Chest of Gold",
"sprite_name": "set_icon_gold_4",
"gold_amount": "8000",
"price": "59.99"
},
{
"id": "10005",
"name": "Vault of Gold",
"sprite_name": "set_icon_gold_5",
"gold_amount": "15000",
"price": "119.99"
}
]
DataManager
using Newtonsoft.Json;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class DataManager
{
public static readonly DataManager instance = new DataManager(); //싱글톤
//상자 정보를 저장할 사전
private Dictionary<int, ChestData> chestDataDics = new Dictionary<int, ChestData>();
//미션 정보를 저장할 사전
private Dictionary<int, MissionData> missionDataDic = new Dictionary<int, MissionData>();
//골드 정보를 저장할 사전
private Dictionary<int, GoldData> goldDataDic = new Dictionary<int, GoldData>();
//생성자
private DataManager()
{
}
public void LoadChestDatas()
{
TextAsset aseet = Resources.Load<TextAsset>("chest_data"); //json은 안 붙임
//역직렬화
ChestData[] chestDatas = JsonConvert.DeserializeObject<ChestData[]>(aseet.text);
foreach(var chestData in chestDatas)
{
this.chestDataDics.Add(chestData.id, chestData);
}
Debug.Log("상자 로드 완료");
}
public void LoadMissionDatas()
{
TextAsset asset = Resources.Load<TextAsset>("mission_data");
//역직렬화
MissionData[] missionDatas = JsonConvert.DeserializeObject<MissionData[]>(asset.text);
//사전 등록
foreach(var missionData in missionDatas)
{
this.missionDataDic.Add(missionData.id, missionData);
}
Debug.Log("미션 로드 완료");
}
public void LoadGoldDatas()
{
TextAsset asset = Resources.Load<TextAsset>("gold_data");
//역직렬화
GoldData[] goldDatas = JsonConvert.DeserializeObject<GoldData[]>(asset.text);
//사전 등록
foreach(var goldData in goldDatas)
{
this.goldDataDic.Add(goldData.id, goldData);
}
Debug.LogFormat("<color=yellow>Gold Count: {0}</color>",this.goldDataDic.Count);
Debug.Log("골드 로드 완료");
}
public List<ChestData> GetChestDatas()
{
return this.chestDataDics.Values.ToList();
}
public List<MissionData> GetMissionDatas()
{
return this.missionDataDic.Values.ToList();
}
public List<GoldData> GetGoldDatas()
{
return this.goldDataDic.Values.ToList();
}
}
GoldData -> 데이터 매핑 클래스
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GoldData
{
//id name sprite_name gold_amount price
//int string string int float
public int id;
public string name;
public string sprite_name;
public int gold_amount;
public float price;
}
실행결과 및 스크립트
UIGoldShopMain
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UIGoldShopMain : MonoBehaviour
{
[SerializeField]
private UIPageGoldShop uIPageGoldShop;
// Start is called before the first frame update
void Start()
{
DataManager.instance.LoadGoldDatas();
List<GoldData> goldDatas = DataManager.instance.GetGoldDatas();
this.uIPageGoldShop.Init(goldDatas);
}
}
UIPageGoldShop
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UIPageGoldShop : MonoBehaviour
{
[SerializeField]
private UIGoldScrollview goldScrollview;
public void Init(List<GoldData> goldDatas)
{
foreach(GoldData data in goldDatas)
{
Debug.LogFormat("<color=yellow>{0},{1},{2},{3},{4}</color>",
data.id, data.name, data.sprite_name, data.gold_amount, data.price);
this.goldScrollview.Init(data);
//클로져
int goldAmount = data.gold_amount;
float goldPrice = data.price;
}
}
}
UIGoldScrollview
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.U2D;
public class UIGoldScrollview : MonoBehaviour
{
[SerializeField]
private GameObject goldCellPrefab;
[SerializeField]
private SpriteAtlas goldAtlas;
public void Init(GoldData data)
{
GameObject context = GameObject.FindGameObjectWithTag("Content");
GameObject go = Instantiate(this.goldCellPrefab, context.transform);
UIGoldCell gold = go.GetComponent<UIGoldCell>();
this.SetGoldCellInfo(gold, data);
gold.Init();
gold.onBuyButtonClick = () => {
Debug.LogFormat("<color=yellow>골드 양:{0}, 가격:{1}</color>",
data.gold_amount, data.price);
};
}
private void SetGoldCellInfo(UIGoldCell cell, GoldData data)
{
cell.Id = data.id;
cell.Name = data.name;
cell.Sprite_name = data.sprite_name;
cell.GoldSprite = this.goldAtlas.GetSprite(data.sprite_name);
cell.Gold_amount = data.gold_amount;
cell.Price = data.price;
}
}
UIGoldCell
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class UIGoldCell : MonoBehaviour
{
public System.Action onBuyButtonClick;
#region Info
private int id;
private new string name;
private string sprite_name;
private int gold_amount;
private float price;
private Sprite goldSprite;
public string Name { get => name; set => name = value; }
public int Id { get => id; set => id = value; }
public string Sprite_name { get => sprite_name; set => sprite_name = value; }
public int Gold_amount { get => gold_amount; set => gold_amount = value; }
public float Price { get => price; set => price = value; }
public Sprite GoldSprite { get => goldSprite; set => goldSprite = value; }
#endregion
[SerializeField] private TMP_Text txtName;
[SerializeField] private TMP_Text txtGoldAmount;
[SerializeField] private TMP_Text txtPrice;
[SerializeField] private Image goldImage;
[SerializeField] private Button btnBuy;
public void Init()
{
this.txtName.text = this.name;
this.txtGoldAmount.text = string.Format("{0} Gold", this.gold_amount);
this.txtPrice.text = string.Format("US ${0}", this.price);
this.SetImage(this.goldImage, this.goldSprite);
this.btnBuy.onClick.AddListener(() => {
this.onBuyButtonClick();
Debug.LogFormat("골드 양:{0}, 가격:{1}", this.gold_amount, this.price);
});
}
private void SetImage(Image image, Sprite sprite)
{
image.sprite = sprite;
image.SetNativeSize();
}
}
기준이 되는 가이드 이미지가 모두 Native Size여서 신경쓰지 않았었지만,
이미지의 위치 때문인지 이상하게 나오게 된다.
그래서 데이터 테이블의 이미지의 위치 정보를 추가해보려고 한다.
변경된 json파일
[
{
"id": "10000",
"name": "Tiny of Gold",
"sprite_name": "set_icon_gold_0",
"gold_amount": "240",
"price": "1.99",
"posX": "0",
"posY": "100"
},
{
"id": "10001",
"name": "Fistful of Gold",
"sprite_name": "set_icon_gold_1",
"gold_amount": "650",
"price": "4.99",
"posX": "0",
"posY": "117"
},
{
"id": "10002",
"name": "Pouch of Gold",
"sprite_name": "set_icon_gold_2",
"gold_amount": "1500",
"price": "9.99",
"posX": "-45",
"posY": "80"
},
{
"id": "10003",
"name": "Box of Gold",
"sprite_name": "set_icon_gold_3",
"gold_amount": "3000",
"price": "24.99",
"posX": "0",
"posY": "100"
},
{
"id": "10004",
"name": "Chest of Gold",
"sprite_name": "set_icon_gold_4",
"gold_amount": "8000",
"price": "59.99",
"posX": "0",
"posY": "18"
},
{
"id": "10005",
"name": "Vault of Gold",
"sprite_name": "set_icon_gold_5",
"gold_amount": "15000",
"price": "119.99",
"posX": "0",
"posY": "21"
}
]
스크립트 변경되거나 추가된 부분
실행결과
그런데 이렇게 하니 이미지가 안 보이는 결과가 나왔다.
그래서 어떤 이유로 이런 문제가 생기는지 확인 하니
위에 메서드 SetImage에서 그냥 position을 받은 것이 문제였다.
데이터로 저장한 json 파일의 정보는 앵커를 기준으로 위치를 계산한 것이다.
그런데 그냥 월드 좌표 기준으로 위치를 지정해버리니, 이미지가 다른 곳으로 날아가 안보이는 결과가 나오게 된 것이다.
따라서 그냥 position이 아닌 anchoredPosition을 사용하면 된다는 것을 알았다.
https://keykat7.blogspot.com/2020/01/unity-rectTransform.html
이 블로그를 참고했다.
전체결과
이렇게 골드 상점에 대한 제작을 끝냈다.
'유니티 심화' 카테고리의 다른 글
유니티 GUI 미션 (데이터 연동 및 저장, 저장한 데이터 불러오기) (0) | 2023.09.10 |
---|---|
보석 상점 GUI (0) | 2023.09.09 |
유니티 GUI (스크롤 뷰 및 셀) 및 데이터 연동 (0) | 2023.09.07 |
유니티 GUI 3 (Stage UI) (0) | 2023.09.06 |
유니티 GUI 2 (0) | 2023.09.05 |