I’m working on a system for selecting hats in a shop within my game, and I want it to be based on the current day. Here’s what I’m aiming to achieve:
- Daily Hat Selection:
Each day should determine which hats are displayed in the shop. To achieve this, I multiply the current day number by three to create a starting index for selecting hats. - Skipping Hats:
Some hats are marked asNotInCycle
, which means they shouldn’t be displayed. I need to make sure that these hats are skipped in the selection process. - Avoiding Repetitions:
The same hat should not appear more than once in a single day’s selection. Additionally, I want to ensure that the hat sets don’t repeat on consecutive days.
To implement this, I calculate the starting index based on the current day and then select hats in a cyclic manner, skipping those marked as NotInCycle
. I use wrapping logic to handle cases where the index goes out of bounds, making sure the selection is smooth and respects the constraints.
Here is my code:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class ShopCycleManager : MonoBehaviour
{
[Serializable]
public class Hat
{
public Sprite HatArt;
public int Id;
public bool NotInCycle;
}
public TextMeshProUGUI TimeLeftUnitlRefreshTxt;
public DateTime CurrentTime;
public TimeSpan TimeUntilShopRefresh;
public GameObject[] HatsInCycle;
public int Day;
public GameObject Data;
public int TotHats;
public Hat[] Hats;
public int Days;
// Start is called before the first frame update
void Awake()
{
Data = GameObject.Find("Data");
}
// Update is called once per frame
void Update()
{
if (Data.GetComponent<DataStore>().Refresh == false)
{
Day = Days*3;
}
else
{
Day = (System.DateTime.Now.Day+Data.GetComponent<DataStore>().RefreshShopOffset)*3;
}
SetHats();
/*
CurrentTime = DateTime.Now;
TimeUntilShopRefresh = CalculateTimeUntilNextNoon(CurrentTime);
TimeLeftUnitlRefreshTxt.text = $"{(int)TimeUntilShopRefresh.TotalHours}H, {TimeUntilShopRefresh.Minutes}M, {TimeUntilShopRefresh.Seconds}S, left until auto shop refresh";*/
}
void SetHats()
{
int Hat1, Hat2, Hat3;
int range = TotHats;
// Find Hat1
int i = WrapNumber(Day, range); // Start index
// Find first valid hat
while (Hats[i - 1].NotInCycle)
{
i = WrapNumber(i + 1, range);
}
Hat1 = Hats[i - 1].Id;
// Find Hat2
i = WrapNumber(i + 1, range);
// Find second valid hat
while (Hats[i - 1].NotInCycle)
{
i = WrapNumber(i + 1, range);
}
Hat2 = Hats[i - 1].Id;
// Find Hat3
i = WrapNumber(i + 1, range);
// Find third valid hat
while (Hats[i - 1].NotInCycle)
{
i = WrapNumber(i + 1, range);
}
Hat3 = Hats[i - 1].Id;
Debug.Log(Hat1 + ", " + Hat2 + ", " + Hat3);
}
int WrapNumber(int value, int range)
{
return ((value - 1) % range + range) % range + 1;
}
TimeSpan CalculateTimeUntilNextNoon(DateTime currentTime)
{
// Calculate the next 12 AM
DateTime nextMidnight = new DateTime(currentTime.Year, currentTime.Month, currentTime.Day).AddDays(1);
// Calculate the time span until next 12 AM
return nextMidnight - currentTime;
}
}
If you need more info just ask. But yea ive been banging my head against my wall for ages trying to make this work. I’m getting incorrect results and repeating hats. If theres a different way I can do this or if its an easy fix that would be great. Thanks