using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class StoreManager : MonoBehaviour { private StoreObject store; private List products = new List(); private GameObject uiStore; public GameObject uiParent; public bool isInitialized = false; public float widthSpacing = 0.4f; public float heightSpacing = 0.5f; sealed internal class ProductInstance { public GameObject ui; public ProductObject product; public List instances = new List(); public ProductInstance(GameObject go, ProductObject p) { ui = go; product = p; } } public void SetStoreObject(StoreObject so) { this.store = so; } public void OpenStore() { if (!isInitialized) InitializeStore(); else UpdateAllProductsUI(); uiStore.SetActive(true); GameManager.Instance.SetIsUIMenuOpen(true); } private void InitializeStore() { uiStore = Instantiate(store.storePrefab, uiParent.transform); uiStore.transform.localPosition = new Vector3(0, 0, 5); InitializeProductPage(); isInitialized = true; } private void InitializeProductPage() { ProductObject product; for (int i = 0; i < store.products.Count; i++) { product = store.products[i]; GameObject go = Instantiate(store.productUIPrefab, uiStore.transform); go.transform.localPosition = CalculateCardPosition(i); ProductInstance pi = new ProductInstance(go, product); products.Add(pi); go.GetComponent().SetInformation(products.Count - 1, product.uiName, product.uiDescription, product.uiImage, product.price, IsProductBuyable(pi)); } } public void DestroyStore() { Destroy(uiStore); isInitialized = false; } public void CloseStore() { uiStore.SetActive(false); GameManager.Instance.SetIsUIMenuOpen(false); } private void UpdateProductUI(GameObject ui, bool isBuyable) { ui.GetComponent().UpdateUI(isBuyable); } private void UpdateAllProductsUI() { foreach(ProductInstance pi in products) { pi.ui.GetComponent().UpdateUI(IsProductBuyable(pi)); } } private Vector3 CalculateCardPosition(int index) { Rect rect = store.productUIPrefab.GetComponent().rect; Rect storeRect = uiStore.GetComponent().rect; int numberPerRow = (int) storeRect.width / (int) (rect.width + widthSpacing); int widthIndex = index % numberPerRow; int heightIndex = index / numberPerRow; int scale = (int) uiStore.GetComponent().referencePixelsPerUnit; // FIXME: Algorithm for positionning does not work in all cases (weird behaviour possible if more then 4 products) return new Vector3 ( ((widthIndex * rect.width) + (widthIndex * widthSpacing) + (rect.width / 2) + widthSpacing - (storeRect.width / 2)) * scale, ((heightIndex * rect.height) + (heightIndex * heightSpacing) + (rect.height / 3) - heightSpacing) * scale, 0 ); } public bool BuyProduct(int id) { ProductInstance pi = products[id]; if (!IsProductBuyable(pi)) return false; if (!BillPlayer(pi.product.price)) return false; SpawnProduct(pi); UpdateProductUI(pi.ui, IsProductBuyable(pi)); return true; } public bool BillPlayer(int price) { PlayerManagement playerScript = GameObject.FindGameObjectWithTag("Player").GetComponent(); if(playerScript.BraveryPoints >= price) { playerScript.DeductPoints(price); return true; } return false; } private void SpawnProduct(ProductInstance pi) { TransformAndQuaternionData location = GetNextPossibleLocationForProduct(pi); if (location == null) return; GameObject go = Instantiate(pi.product.prefab, location.position, location.rotation); pi.instances.Add(go); } private TransformAndQuaternionData GetNextPossibleLocationForProduct(ProductInstance pi) { foreach(TransformAndQuaternionData location in pi.product.spawnLocations) { if (pi.instances.Find(p => p.transform.position == location.position) == null) return location; } return null; } private bool IsProductBuyable(ProductInstance pi) { return pi.instances.Count < pi.product.spawnLocations.Count; } }