Button, Text를 추가하고
UI는 계산을 해선 안된다.
그리고 숫자 추가하고 자리를 잡아준다.
(업로드는 내일)
버튼 위치만 고치면 된다.
UIProductinfo.cs
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
public class UIProductInfo : MonoBehaviour
{
public enum EProduct
{
Coke, Coffee, Milk, Kkang, Homerun
}
[System.Serializable]
public struct ProductInfo
{
public EProduct name;
public int price;
public int stock;
public bool HaveStock()
{
return stock > 0;
}
public void Print()
{
Debug.Log(name + " / " + price + " 원 / " + stock + "개");
}
}
public static string EnumToString(EProduct _name)
{
switch (_name)
{
case EProduct.Coke: return "콜라";
case EProduct.Coffee: return "커피";
case EProduct.Milk: return "밀크";
case EProduct.Kkang: return "깡";
case EProduct.Homerun: return "홈런볼";
}
return string.Empty;
}
}
UVVendingMachine.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using System;
public class UIVendingMachine : MonoBehaviour
{
[SerializeField]
private GameObject productButtonPrefab = null;
//[SerializeField]
//private string name = null;
//[SerializeField]
//private UIProductInfo.ProductInfo[]
// productInfos = null;
private RectTransform imgBackTr = null;
private TextMeshProUGUI textName = null;
private List<UIProductButton> productBtnList = new List<UIProductButton>();
private int vmIndex = -1;
private void Awake()
{
Image imgBack =
GetComponentInChildren<Image>();
imgBackTr = imgBack.GetComponent<RectTransform>();
textName =
GetComponentInChildren<TextMeshProUGUI>();
}
// 게으른 초기화(Lazy Initialization)
public void Init(VMDatabase.VMInfo _vmInfo, UIProductButton.OnClickDelegate _onClickCallback)
{
vmIndex = _vmInfo.vmIndex;
//textName.text = name;
textName.text = _vmInfo.vmName;
BuildButtons(_vmInfo.productInfos, _onClickCallback);
}
public void TurnOnOff(bool _on)
{
gameObject.SetActive(_on);
}
private void BuildButtons(
UIProductInfo.ProductInfo[] _productInfos, UIProductButton.OnClickDelegate _onClickCallback)
{
// odd, even
bool odd = _productInfos.Length % 2 != 0 ? true : false;
Vector3 startPos = Vector3.zero;
float offsetW = 0f;
float offsetH = 0f;
CalcStartPosAndOffset(
_productInfos,
out startPos,
out offsetW,
out offsetH);
for (int i = 0; i < _productInfos.Length; ++i)
{
GameObject go =
Instantiate(
productButtonPrefab,
transform);
UIProductButton productBtn =
go.GetComponent<UIProductButton>();
productBtn.Init(vmIndex, i, _productInfos[i]);
productBtn.SetLocalPosition(
new Vector3(
startPos.x + (offsetW * (i % 3)),
startPos.y - (offsetH * (i / 3)),
0f
));
productBtn.SetOnClickDelegate(_onClickCallback);
productBtnList.Add(productBtn);
}
}
private void CalcStartPosAndOffset(
UIProductInfo.ProductInfo[] _productInfos,
out Vector3 _startPos,
out float _offsetW,
out float _offsetH)
{
float imgW = imgBackTr.sizeDelta.x;
int divCntW = (_productInfos.Length % 2) + 3;
float offsetW = imgW / divCntW;
float startX = -(imgW * 0.5f) + offsetW;
float imgH = imgBackTr.sizeDelta.y;
int divCntH = ((_productInfos.Length + 2) / 3);
float offsetH = imgH / divCntH;
float startY = (imgH * 0.5f) - offsetH;
_startPos = new Vector3(startX, startY, 0f);
_offsetW = offsetW;
_offsetH = offsetH;
}
public void UpdateStock(int _btnIdx, int _stock)
{
productBtnList[_btnIdx].UpdateStock(_stock);
}
public bool EqualIndex(int _vmIdx)
{
return vmIndex == _vmIdx;
}
}
VMDatabase.cs
using System.Collections;
using System.Collections.Generic;
using System.IO.IsolatedStorage;
using UnityEngine;
public class VMDatabase : MonoBehaviour
{
[System.Serializable]public struct VMInfo
{
public int vmIndex;
public string vmName;
public UIProductInfo.ProductInfo[] productInfos;
public VMInfo(int _vmIdx, string _vmName, UIProductInfo.ProductInfo[] _productInfos)
{
vmIndex = _vmIdx;
vmName = _vmName;
productInfos = _productInfos;
}
public static VMInfo NULL()
{
return new VMInfo(-1, string.Empty, null);
}
public bool isNull()
{
return vmIndex == -1;
}
}
[SerializeField] private VMInfo[] vmInfos = null;
public VMInfo[] FindAll()
{
return vmInfos;
}
public VMInfo FindWithIndex(int _vmIndex)
{
foreach (VMInfo info in vmInfos)
{
if (info.vmIndex == _vmIndex)
{
return info;
}
}
//Null 객체
return VMInfo.NULL();
}
public bool FindProductInfo(int _vmIdx, int _btnIdx, ref UIProductInfo.ProductInfo _productinfo)
{
foreach(VMInfo info in vmInfos)
{
if(info.vmIndex == _vmIdx)
{
if(_btnIdx >= 0 && _btnIdx < info.productInfos.Length)
{
_productinfo = info.productInfos[_btnIdx];
return true;
}
}
}
return false;
}
//Increment / Decrement
public void StockDecrement(int _vmIdx, int _btnIdx)
{
foreach(VMInfo info in vmInfos)
{
if(info.vmIndex == _vmIdx)
{
--info.productInfos[_btnIdx].stock;
}
}
}
}
VMPlayer.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class VMPlayer : MonoBehaviour
{
private int money = 100000;
public int Money { get { return money; } }
public bool CanPay(int _price)
{
return money > _price;
}
public void Pay(int _price)
{
money -= _price;
}
}
UIProductButton.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class UIProductButton : MonoBehaviour
{
private enum EIndex { Name, Price, Stock }
public delegate void OnClickDelegate(int _vmIdx, int _btnIdx);
private OnClickDelegate onClickCallback = null;
private Button btn = null;
private TextMeshProUGUI[] texts = null;
private RectTransform rectTr = null;
private int vmIndex = -1;
private int btnIndex = -1;
private void Awake()
{
btn = GetComponentInChildren<Button>();
texts = GetComponentsInChildren<TextMeshProUGUI>();
rectTr = GetComponent<RectTransform>();
}
public void Init(int _vmIdx, int _btnidx, UIProductInfo.ProductInfo _info)
{
vmIndex = _vmIdx;
btnIndex = _btnidx;
texts[(int)EIndex.Name].text = UIProductInfo.EnumToString(_info.name);
texts[(int)EIndex.Price].text = _info.price.ToString() + "원";
texts[(int)EIndex.Stock].text = _info.stock.ToString() + "개";
}
public void SetOnClickDelegate(OnClickDelegate _callback)
{
onClickCallback = _callback;
btn.onClick.AddListener(() =>
{
onClickCallback?.Invoke(vmIndex, btnIndex);
});
}
public void SetLocalPosition(Vector3 _localPos)
{
rectTr.localPosition = _localPos;
}
public void UpdateStock(int _stock)
{
texts[(int)EIndex.Stock].text = _stock.ToString() + "개";
}
}
UIVMButton.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
public class UIVMButton : MonoBehaviour
{
public delegate void OnClickDelegate(int _idx);
private int index = -1;
private Button btn = null;
private void Awake()
{
btn = GetComponent<Button>();
}
public void SetOnClickCallBack(int _idx , OnClickDelegate _onClickCallback)
{
btn.onClick.AddListener(
() =>
{
_onClickCallback(_idx);
});
}
}
UIVMHolder.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UIVMHolder : MonoBehaviour
{
private UIVendingMachine[] vms = null;
private UIVendingMachine prevVm = null;
private void Awake()
{
vms = GetComponentsInChildren<UIVendingMachine>();
}
public void Init(VMDatabase.VMInfo[] _vmInfos, UIProductButton.OnClickDelegate _onClickCallback)
{
for(int i = 0; i < _vmInfos.Length; ++i)
{
vms[i].Init(_vmInfos[i], _onClickCallback);
}
TurnOffAll();
}
private void TurnOffAll()
{
foreach(UIVendingMachine vm in vms)
{
vm.TurnOnOff(false);
}
}
public void TurnOn(int _idx)
{
if(prevVm != null)
{
prevVm.TurnOnOff(false);
}
vms[_idx].TurnOnOff(true);
prevVm = vms[_idx];
}
public void UpdateStock(int _vmIdx, int _btnIdx, int _stock)
{
foreach(UIVendingMachine vm in vms)
{
if (vm.EqualIndex(_vmIdx))
{
vm.UpdateStock(_btnIdx, _stock);
}
}
}
}
UIVMButtonHolder.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UIVMButtonHolder : MonoBehaviour
{
private UIVMButton[] vmBtns = null;
private void Awake()
{
vmBtns = GetComponentsInChildren<UIVMButton>();
}
public void SetOnClickCallback(UIVMButton.OnClickDelegate _onClickCallback)
{
for(int i = 0; i < vmBtns.Length; ++i)
{
vmBtns[i].SetOnClickCallBack(i, _onClickCallback);
}
}
}
VMSimulator.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class VMSimulator : MonoBehaviour
{
[SerializeField] private VMPlayer vmPlayer = null;
[SerializeField] private UIVMButtonHolder vmBtnHolder = null;
[SerializeField] private UIVMHolder vmHolder = null;
[SerializeField] private VMDatabase vmDB = null;
[SerializeField] private UIWallet wallet = null;
private void Start()
{
vmHolder.Init(vmDB.FindAll(), ProductButtonCallback);
vmBtnHolder.SetOnClickCallback(VMButtonCallback);
wallet.SetMoney(vmPlayer.Money);
}
private void VMButtonCallback(int _vmIdx)
{
vmHolder.TurnOn(_vmIdx);
}
private void ProductButtonCallback(int _vmIdx, int _btnIdx)
{
UIProductInfo.ProductInfo info = new UIProductInfo.ProductInfo();
if(vmDB.FindProductInfo(_vmIdx, _btnIdx, ref info))
{
if (info.HaveStock())
{
if (vmPlayer.CanPay(info.price))
{
vmPlayer.Pay(info.price);
wallet.SetMoney(vmPlayer.Money);
info.Print();
//데이터베이스 재고 줄이기
vmDB.StockDecrement(_vmIdx, _btnIdx);
//갱신된 DB 정보 가져오기
if(vmDB.FindProductInfo(_vmIdx, _btnIdx, ref info))
{
//해당 버튼 정보 갱신
vmHolder.UpdateStock(_vmIdx, _btnIdx, info.stock);
}
//vmDB.FindProductInfo
}
}
info.Print();
}
}
}
하이라키