To swap between different shop types, we have a ShopTabManager.cs
managing that.
With the code below, we can now create as many shop tabs as we want and assign this script for a new tab.
[SerializeField]
private Image tabFocusedImage;
[SerializeField]
private Color focusedColor, unfocusedColor;
[SerializeField]
private StorePopulator.StoreType storeType;
[SerializeField] private ShopTabManager otherTab;
[SerializeField] private StorePopulator storePopulator;
// Start is called before the first frame update
void Start()
{
GetComponent<Button>().onClick.AddListener(OnTabSwitch);
}
private void OnTabSwitch() // on player switches the shop tab
{
tabFocusedImage.color = focusedColor;
UnfocusTab();
storePopulator.storeType = this.storeType;
storePopulator.UpdateStoreContents();
}
private void UnfocusTab() // when the other tab should be unfocused as it's switched away
{
otherTab.tabFocusedImage.color = otherTab.unfocusedColor;
}
The store tab also changes the StoreType enum based on which tab we're currently in, so we know which shop to load in (avatars or stickers)
Found in the StorePopulator.cs
,
public enum StoreType // w hich type should be loaded up in the shop?
{
STICKER,
AVATAR
}
Then, we populate the store every time a tab is changed by running the UpdateStoreContents
method
public void UpdateStoreContents()
{
if (firstTimeOver)
{
foreach (Transform child in gameObject.transform)
{
Destroy(child.gameObject);
}
}
Object[] objects = UnityEngine.Resources.LoadAll("StoreItems/Objects/"); // get all the store item scriptable objects
foreach (Object obj in objects) // iterate the objects array
{
StoreObject storeObj = (StoreObject) obj; // cast it back to a sticker object cause we know they are stickers
if (storeObj.storeType == storeType)
{
if (!storeObj.purchasable) // if its not purchasable,
continue; // we skip this iteration and dont show in the shop.
GameObject storeGameObject = Instantiate(_gameManager.stickerStorePrefab, new Vector3(0,0),
Quaternion.identity); // create a new game object icon
storeGameObject.transform.SetParent(this.gameObject.transform, false); // update the parent
bool owned = false;
bool containsInList = _gameManager.user.details.ownedStickers.Contains(storeObj) ||
_gameManager.user.details.ownedAvatars.Contains(storeObj);
if (containsInList) // if the player already owns the sticker
{
owned = true; // set owned to true so they can't buy it again.
}
StoreIcon storeIcon = storeGameObject.GetComponent<StoreIcon>(); // get the store icon instance
// from the current newly instantiated game object
storeIcon.UpdateStoreIcon(storeObj, owned); // update the sticker and the owned status.
}
}
}
After creating the newly instantiated GameObject, we use the script from StoreIcon.cs
to manage per Store Item's visual appearance. By running the UpdateStoreIcon
method, we can update the item's visual representation, icons, names and whether it's already owned by the player.
public void UpdateStoreIcon(StoreObject storeObj, bool owned)
{
nameText.text = Regex.Replace(storeObj.name.Replace("Sticker", "").Replace("Avatar", ""),
"([a-z])([A-Z])", "$1 $2"); // putting a space before capital letters using Regex
this.sticker = storeObj;
this.owned = owned;
if(!owned)
priceText.text = storeObj.price.ToString();
else
{
priceText.text = "OWNED";
Destroy(GetComponent<Button>());
}
icon.sprite = storeObj.sprite;
}
public void UpdateStoreItemStatus()
{
priceText.text = "OWNED";
}
A StoreButton.cs
script is then use to see if a specific store item is clicked (purchased)
It'll check if the player has enough money, if not show an error prompt. If they have enough money, it'll query the Firebase data and update the new item in the inventory.
private void OnStorePurchase() // when the player buys an item
{
string collectionName = "";
string documentName = "";
if (storeItem.owned)
{
return; // dont buy sticker
}
if (_gameManager.user.details.points < storeItem.sticker.price) // not enough money
{
ErrorPopupManager.GeneratePopup("Not enough points to buy this!");
return;
}
collectionName = "users";
documentName = _gameManager.user.uuid;
int newPoints = _gameManager.user.details.points -
storeItem.sticker.price;
_pointsManager.UpdatePointsText(newPoints); // update the new points visually
_gameManager.user.UpdatePlayerDetails(newPoints, User.UpdateType.POINTS); // update the database with the new deducted points
storeItem.owned = true;
storeItem.UpdateStoreItemStatus();
User.UpdateType updateType = User.UpdateType.STICKER;
if (storePopulator.storeType == StorePopulator.StoreType.AVATAR)
{
updateType = User.UpdateType.AVATAR;
}
_gameManager.user.UpdatePlayerDetails(storeItem.sticker,updateType);
Debug.Log("BOUGHT");
}