- Home /
Choose random prefabs from list?
Hi, so i made a list with 10 prefabs in, and i want the shop to randomly pick 5 from the list everytime the shop is opened. I am really new to unity and have been following tutorials up to this point. Thanks.
The code is
namespace Assets.Scripts.UserInterface
{
public class StoreUIController : MonoBehaviour
{
public ItemList MerchantInventory;
[SerializeField]
private GameObject ItemTemplate;
[SerializeField]
private GameObject CurrencyTemplate;
private Transform _scrollViewContent;
private PlayerInventoryUIController _playerInventoryUI;
private void Start()
{
_playerInventoryUI = FindObjectOfType<PlayerInventoryUIController>();
}
public void PopulateInventory(ItemList inventoryList)
{
ClearInventory();
MerchantInventory = inventoryList;
if (_scrollViewContent == null)
{
_scrollViewContent = transform.Find("Scroll View").Find("Viewport").Find("Content"); ;
}
foreach (var item in inventoryList.ClothingItems)
{
GameObject newItem = Instantiate(ItemTemplate, _scrollViewContent);
newItem.transform.localScale = Vector3.one;
newItem.transform.Find("Image").GetComponent<Image>().sprite = item.Sprite;
newItem.transform.Find("Name").GetComponent<Text>().text = item.Name;
newItem.transform.Find("Description").GetComponent<Text>().text = item.Description;
foreach (var cur in item.PurchasePrice)
{
GameObject newCurrency = Instantiate(CurrencyTemplate, newItem.transform.Find("Currency/List"));
newCurrency.transform.localScale = Vector3.one;
newCurrency.transform.Find("Image").GetComponent<Image>().sprite = cur.Currency.Image;
newCurrency.transform.Find("Amount").GetComponent<Text>().text = cur.Amount.ToString();
}
newItem.transform.Find("Currency").Find("BuyBtn").GetComponent<Button>().onClick.AddListener(BuyOnClick);
}
}
public void ClearInventory()
{
MerchantInventory = null;
//Since this starts out as disabled, we need to do a check the first time we try to access the content element, as we may not have a reference to it.
if (_scrollViewContent == null)
{
_scrollViewContent = transform.Find("Scroll View").Find("Viewport").Find("Content");
}
foreach (Transform child in _scrollViewContent)
{
Destroy(child.gameObject);
}
}
public void BuyOnClick()
{
Item purchasedItem = MerchantInventory.ClothingItems.Find(x => x.Name.Equals(EventSystem.current.currentSelectedGameObject.transform.parent.parent.Find("Name").GetComponent<Text>().text));
if (purchasedItem == null)
{
Debug.Log("Unable To Find Item In Database");
return;
}
else if (purchasedItem.PurchasePriceInPound() >= _playerInventoryUI.PlayerInventory.PoundCoins)
{
Debug.Log("Cannot Afford Item");
return;
}
_playerInventoryUI.PurchaseItem(purchasedItem);
MerchantInventory.ClothingItems.Remove(purchasedItem);
PopulateInventory(MerchantInventory);
}
}
}
Sorry, at the moment the code here populates the shop with everything in the list. I was wondering what i would have to do to make the shop get populated by only 5 items which are randomly selected from the list each time.
Answer by UnityCoach · Oct 27, 2018 at 09:06 PM
Hi,
that's a good question. Randomly pick one item from a list is easy. You can simply do something like :
myListOfItems[Random.Range(0, myListOfItems.Length)] // if it's an array
myListOfItems[Random.Range(0, myListOfItems.Count)] // if it's a List
But picking a given number of items from a list is a bit more interesting.
Let me give this a try and explain through it. Let's begin with the method signature (our goal).
public static List<T> GetRandomItemsFromList<T> (List<T> list, int number)
This will be a generic method, with type T
so that it can work with a list of anything. It will take a list, and a number of items to pick for parameters. Then, we want to duplicate the input list, so that we can remove items from it as we add them to a new list. Eventually, we want to return the new list.
// this is the list we're going to remove picked items from
List<T> tmpList = new List<T>(list);
// this is the list we're going to move items to
List<T> newList = new List<T>();
return newList;
Now we want to loop and move items from one list to the other.
// make sure tmpList isn't already empty
while (newList.Count < number && tmpList.Count > 0)
{
int index = Random.Range(0, tmpList.Count);
newList.Add(tmpList[index]);
tmpList.RemoveAt(index);
}
So, here's the whole method :
public static List<T> GetRandomItemsFromList<T> (List<T> list, int number)
{
// this is the list we're going to remove picked items from
List<T> tmpList = new List<T>(list);
// this is the list we're going to move items to
List<T> newList = new List<T>();
// make sure tmpList isn't already empty
while (newList.Count < number && tmpList.Count > 0)
{
int index = Random.Range(0, tmpList.Count);
newList.Add(tmpList[index]);
tmpList.RemoveAt(index);
}
return newList;
}
And this is how to use it :
List<Item> randomItems = GetRandomItemsFromList<Item> (allItems, 5);
Hope this helps you figure this out.
Your answer
Follow this Question
Related Questions
A node in a childnode? 1 Answer
How to stop list from getting shorter ? [Beginner] 1 Answer
Nodes are deleted from the list for no reason 1 Answer
Random instantiation endlessly? 1 Answer