주말과제(Goldshop)
1. 정적 스크롤뷰
<버튼 클릭하면 타입과 가격 나오기(가장기본)>
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UIGoldCell : MonoBehaviour
{
public enum eGoldType
{
Tiny,Fistful,Pouch,Box,Chest,Vault
}
[SerializeField]
protected Button btnPrice;
[SerializeField]
protected eGoldType goldType;
[SerializeField]
protected float price;
// Start is called before the first frame update
void Start()
{
this.btnPrice.onClick.AddListener(() =>
{
Debug.LogFormat("타입:{0}, 가격:{1}", this.goldType, this.price);
});
}
}
전에 할 때는 왜 하는지 잘 모르겠었는데 집에서 천천히 하니까 확실히 이해되는느낌
<Init()을 이용해서 가격과 타입 출력하기>
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UIGoldCell : MonoBehaviour
{
public enum eGoldType
{
Tiny,Fistful,Pouch,Box,Chest,Vault
}
[SerializeField]
protected Button btnPrice;
[SerializeField]
protected eGoldType goldType;
[SerializeField]
protected float price;
// Start is called before the first frame update
public void Init()
{
this.btnPrice.onClick.AddListener(() =>
{
Debug.LogFormat("타입:{0}, 가격:{1}", this.goldType, this.price);
});
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UIGoldScrollView : MonoBehaviour
{
[SerializeField]
private UIGoldCell[] goldCells;
// Start is called before the first frame update
void Start()
{
for(int i = 0; i < goldCells.Length; i++)
{
UIGoldCell cell = goldCells[i];
cell.Init();
}
}
}
결과는 첫번째(Init 사용x 가장기본) 과 같음
init을 왜 하는지 이해되지 않았었는데 scollview 에서 관리하기 위함이라는것을 알게 되었음
<대리자를 이용>
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UIGoldScrollView : MonoBehaviour
{
[SerializeField]
private UIGoldCell[] goldCells;
// Start is called before the first frame update
void Start()
{
for(int i = 0; i < goldCells.Length; i++)
{
UIGoldCell cell = goldCells[i];
cell.onClickPrice = () =>
{
Debug.LogFormat("<color=blue>타입: {0},가격 {1}</color>", cell.GoldType, cell.Price);
};
cell.Init();
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UIGoldCell : MonoBehaviour
{
public enum eGoldType
{
Tiny,Fistful,Pouch,Box,Chest,Vault
}
[SerializeField]
protected Button btnPrice;
[SerializeField]
protected eGoldType goldType;
[SerializeField]
protected float price;
public System.Action onClickPrice;
public eGoldType GoldType
{
get
{
return this.goldType;
}
}
public float Price
{
get
{
return this.price;
}
}
// Start is called before the first frame update
public void Init()
{
this.btnPrice.onClick.AddListener(() =>
{
Debug.LogFormat("타입:{0}, 가격:{1}", this.goldType, this.price);
this.onClickPrice();
});
}
}
<데이터 연동>
DataManager.cs
private Dictionary<int, GoldData> dicGoldDatas;
public void LoadGoldData()
{
TextAsset asset = Resources.Load<TextAsset>("gold_data");
Debug.Log(asset.text);
GoldData[] arrGoldDatas = JsonConvert.DeserializeObject<GoldData[]>(asset.text);
Debug.LogFormat("arrGoldDatas:{0}", arrGoldDatas.Length);
this.dicGoldDatas = arrGoldDatas.ToDictionary(x => x.id);
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test07Main : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
DataManager.instance.LoadGoldData();
}
}
Main만들고, this.chestScrollview.Init();
UIGoldScrollView컴포넌트 Init 메서드에서 상자정보를 출력
List<ChestData> chestDatas = DataManager.instance.GetChestDatas();
DataManager.cs에서 추가된 코드
public List<GoldData> GetGoldDatas()
{
return this.dicGoldDatas.Values.ToList();
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test07Main : MonoBehaviour
{
[SerializeField]
private UIGoldScrollView scrollView;
// Start is called before the first frame update
void Start()
{
DataManager.instance.LoadGoldData();
this.scrollView.Init();
}
}
MonoBehaviour 지움
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GoldData
{
public int id;
public string name;
public int type;
public float price;
public int amount;
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UIGoldScrollView : MonoBehaviour
{
[SerializeField]
private UIGoldCell[] goldCells;
// Start is called before the first frame update
public void Init()
{
List<GoldData> goldDatas = DataManager.instance.GetGoldDatas();
foreach(GoldData data in goldDatas)
{
Debug.LogFormat("<color=yellow>id:{0}</color>,name:{1},type:{2},price:{3},amount:{4}", data.id, data.name, data.type, data.price, data.amount);
}
}
}
버튼 클릭하면 타입과 가격이 나오는 것이 안나왔는데 UIScrollView를 수정하면서 UI.GoldCell의 Init() 함수를 호출하지 않아 안나왔다 -> Start로 바꿈
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UIGoldCell : MonoBehaviour
{
public enum eGoldType
{
Tiny,Fistful,Pouch,Box,Chest,Vault
}
[SerializeField]
protected Button btnPrice;
[SerializeField]
protected eGoldType goldType;
[SerializeField]
protected float price;
public eGoldType GoldType
{
get
{
return this.goldType;
}
}
public float Price
{
get
{
return this.price;
}
}
// Start is called before the first frame update
void Start()
{
this.btnPrice.onClick.AddListener(() =>
{
Debug.LogFormat("타입:{0}, 가격:{1}", this.goldType, this.price);
});
}
}
ScrollView의 Init에서 상자정보를 출력하고 버튼 출력하면 상자 타입과 가격을 출력
2. 동적 스크롤뷰
- UIGoldCell 프리팹 등록
<초기화 메서드 호출 (Data를 매개변수로 넘김)>
이름,가격 출력
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class UIGoldCell : MonoBehaviour
{
public enum eGoldType
{
Tiny,Fistful,Pouch,Box,Chest,Vault
}
[SerializeField]
protected Button btnPrice;
[SerializeField]
protected eGoldType goldType;
[SerializeField]
protected float price;
[SerializeField]
protected TMP_Text txtName;
public eGoldType GoldType
{
get
{
return this.goldType;
}
}
public float Price
{
get
{
return this.price;
}
}
// Start is called before the first frame update
public void Init(GoldData data)
{
this.price = data.price;
this.txtName.text = data.name;
this.btnPrice.onClick.AddListener(() =>
{
Debug.LogFormat("타입:{0}, 가격:{1}", this.txtName.text, this.price);
});
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UIGoldScrollView : MonoBehaviour
{
[SerializeField]
private UIGoldCell[] goldCells;
[SerializeField]
private GameObject uiGoldPrefab;
[SerializeField]
private Transform content;
// Start is called before the first frame update
public void Init()
{
List<GoldData> goldDatas = DataManager.instance.GetGoldDatas();
foreach(GoldData data in goldDatas)
{
Debug.LogFormat("<color=yellow>id:{0}</color>,name:{1},type:{2},price:{3},amount:{4}", data.id, data.name, data.type, data.price, data.amount);
UIGoldCell cell = null;
GameObject go = Instantiate<GameObject>(this.uiGoldPrefab, content);//content위치에
cell = go.GetComponent<UIGoldCell>();
cell.Init(data);
}
}
}
이름과 가격은 잘 출력되는데 ui에서는 제대로 표현되지 않음
다른분꺼 블로그 참고하여 했더니 제대로 표현됨
[SerializeField]
protected TMP_Text txtPrice;
this.txtPrice.text = string.Format("US${0}", this.price);
왜 그냥 price를 쓰면 안되는지 잘은 이해안되지만 이렇게 추가하니 해결됨
추가로
Debug.LogFormat("이름:{0}, 가격:{1}", this.txtName.text, this.txtPrice);
왜 .text를 쓰는지 궁금해서 txtPrice.text라 안쓰고 그냥 txtprice라고만 치니
이렇게 나옴
+amount도 표시하기(log출력은 X)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class UIGoldCell : MonoBehaviour
{
public enum eGoldType
{
Tiny,Fistful,Pouch,Box,Chest,Vault
}
[SerializeField]
protected Button btnPrice;
[SerializeField]
protected eGoldType goldType;
[SerializeField]
protected TMP_Text txtPrice;
[SerializeField]
protected TMP_Text txtAmount;
[SerializeField]
protected TMP_Text txtName;
[SerializeField]
protected float price;
public eGoldType GoldType
{
get
{
return this.goldType;
}
}
public float Price
{
get
{
return this.price;
}
}
// Start is called before the first frame update
public void Init(GoldData data)
{
this.price = data.price;
this.txtName.text = data.name;
this.txtAmount.text = string.Format("{0} Gold",data.amount.ToString());
this.txtPrice.text = string.Format("US ${0}", this.price);
this.btnPrice.onClick.AddListener(() =>
{
Debug.LogFormat("이름:{0}, 가격:{1}", this.txtName.text, this.txtPrice.text);
});
}
}
<아틀라스>
ㅎsprite_name이 왜 필요한지 이제 깨달았다 .. ㅎ
계속 this.icon.sprite = atlas.GetSprite(data.sprite_name); 이부분에서 null exception이 나서 몇시간동안 계속 찾았는데 .. Atlas위치가 Resources아래에 있지 않았다 ..
[전체코드]
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.U2D;
using System;
public class AtlasManager : MonoBehaviour
{
[SerializeField]
private string[] arrAtlasNames;
private Dictionary<string, SpriteAtlas> dicAtlases = new Dictionary<string, SpriteAtlas>();
public static AtlasManager instance;
// Start is called before the first frame update
private void Awake()
{
if(instance!=null&& instance != this)
{
Destroy(this);
throw new System.Exception("An instance of this singleton already exits.");
}
else
{
instance = this;
}
DontDestroyOnLoad(this.gameObject);
}
public void LoadAtlases()
{
foreach(var atlasName in this.arrAtlasNames)
{
var atlas = Resources.Load<SpriteAtlas>(atlasName);
this.dicAtlases.Add(atlasName, atlas);
}
Debug.LogFormat("{0}개의 아틀라스를 로드 했습니다. ", this.dicAtlases.Count);
}
public SpriteAtlas GetAtlas(string atlasName)
{
return this.dicAtlases[atlasName];
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
using System.Runtime.InteropServices.WindowsRuntime;
using Newtonsoft.Json.Bson;
using System.Linq;
public class DataManager :MonoBehaviour
{
public static readonly DataManager instance = new DataManager();
private Dictionary<int, ChestData> dicChestDatas = new Dictionary<int, ChestData>();
// Start is called before the first frame update
private DataManager()
{
}
public void LoadChestData()
{
TextAsset asset = Resources.Load<TextAsset>("chest_data");
Debug.Log(asset.text);
ChestData[] chestDatas = JsonConvert.DeserializeObject<ChestData[]>(asset.text);
foreach (ChestData data in chestDatas)
{
this.dicChestDatas.Add(data.id, data);
}
Debug.LogFormat("dicchestDatas:{0}", dicChestDatas.Count);
}
public List<ChestData> GetChestDatas()
{
return this.dicChestDatas.Values.ToList();
}
private Dictionary<int, MissionData> dicMissionDatas;
public void LoadMissionData()
{
//Resources 폴더에서 mossion_data에셋(Test asset)을 로드
TextAsset asset = Resources.Load<TextAsset>("mission_data");
//가져오기
//string json = asset.text;
Debug.Log(asset.text);
//역직렬화
MissionData[] arrMissionDatas = JsonConvert.DeserializeObject<MissionData[]>(asset.text);
Debug.LogFormat("arrMissionDatas:{0}", arrMissionDatas.Length);
//사전에 넣기
this.dicMissionDatas = arrMissionDatas.ToDictionary(x => x.id);
}
public List<MissionData> GetMissionDatas()
{
return this.dicMissionDatas.Values.ToList();
}
private Dictionary<int, GoldData> dicGoldDatas;
public void LoadGoldData()
{
TextAsset asset = Resources.Load<TextAsset>("gold_data");
Debug.Log(asset.text);
GoldData[] arrGoldDatas = JsonConvert.DeserializeObject<GoldData[]>(asset.text);
Debug.LogFormat("arrGoldDatas:{0}", arrGoldDatas.Length);
this.dicGoldDatas = arrGoldDatas.ToDictionary(x => x.id);
}
public List<GoldData> GetGoldDatas()
{
return this.dicGoldDatas.Values.ToList();
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using UnityEngine.U2D;
public class UIGoldCell : MonoBehaviour
{
public enum eGoldType
{
Tiny,Fistful,Pouch,Box,Chest,Vault
}
[SerializeField]
protected Button btnPrice;
[SerializeField]
protected eGoldType goldType;
[SerializeField]
protected TMP_Text txtPrice;
[SerializeField]
protected TMP_Text txtAmount;
[SerializeField]
protected TMP_Text txtName;
[SerializeField]
protected float price;
[SerializeField]
protected Image icon;
public eGoldType GoldType
{
get
{
return this.goldType;
}
}
public float Price
{
get
{
return this.price;
}
}
// Start is called before the first frame update
public void Init(GoldData data)
{
this.price = data.price;
this.txtName.text = data.name;
this.txtAmount.text = string.Format("{0} Gold",data.amount.ToString());
this.txtPrice.text = string.Format("US ${0}", this.price);
var atlas = AtlasManager.instance.GetAtlas("GoldAtlas");
this.icon.sprite = atlas.GetSprite(data.sprite_name);
this.btnPrice.onClick.AddListener(() =>
{
Debug.LogFormat("이름:{0}, 가격:{1}", this.txtName.text, this.txtPrice.text);
});
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.U2D;
public class UIGoldScrollView : MonoBehaviour
{
[SerializeField]
private GameObject uiGoldPrefab;
[SerializeField]
private Transform content;
[SerializeField]
private SpriteAtlas atlas;
// Start is called before the first frame update
public void Init()
{
List<GoldData> goldDatas = DataManager.instance.GetGoldDatas();
foreach(GoldData data in goldDatas)
{
Debug.LogFormat("<color=yellow>id:{0}</color>,name:{1},type:{2},price:{3},amount:{4},{5}", data.id, data.name, data.type, data.price, data.amount,data.sprite_name);
UIGoldCell cell = null;
GameObject go = Instantiate<GameObject>(this.uiGoldPrefab, content);//content위치에
cell = go.GetComponent<UIGoldCell>();
cell.Init(data);
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test07Main : MonoBehaviour
{
[SerializeField]
private UIGoldScrollView scrollView;
// Start is called before the first frame update
void Start()
{
DataManager.instance.LoadGoldData();
AtlasManager.instance.LoadAtlases();
this.scrollView.Init();
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GoldData
{
public int id;
public string name;
public int type;
public float price;
public int amount;
public string sprite_name;
}