- Home /
My Instantiated Button doesn't work on non instantiated objects.
I'm trying to make my game menu seamless however I am having a lot of issues when it comes to instantiating buttons. The perfect example I can think of is with my inventory. It takes the information(item id and quantity) in my xml database and puts it into a dictionary that is used to make things happen in real time as the xml database is also updated. For each item in the database there is an instantiated button. My Original goal was that once you click on this button that has the item's name its description would display and you'd be set to use the item however I wasn't able to have this new instantiated button affect the gameobjects that weren't instantiated so I had to create a button to act as a middle man. Is there a way to get around this middle man? iteminfo: This is what the instantiated button currently does. It gives information to variables which can be used by other buttons to display the description.
Simply put, How do I go about instantiating this button and having it be able to successfully call the display description function itself without me having to use another function to store the data to call it later? Thanks in advance.
Here are the variables used followed by the functions as well as a pic of how the set up currently looks:
//Inventory Variables
public GameObject InventoryPanel;
public Text Itemdescription;
public GameObject Itemprefab;
private GameObject Itemslot;
public GameObject Itemcontent;
public GameObject Itemname;
private List<GameObject> itemdestroy = new List<GameObject>();
private static List<string> ItemIDs = new List<string>();
private static List<int> ItemQuantities = new List<int>();
int itemcount;
static int stock;
static string itemdesc;
static string itemid;
public static int itemrefresh;
public Text Itemquant;
Functions:
public void inventorybutton()
{
UnitEquipment.Inventorysetup();
itemrefresh = 1;
backcount++;
itemcount++;
InventoryPanel.SetActive(true);
Inventorydisplay();
}
//Inventory Stuff
public void Inventorydisplay()
{
ypos = -10;
xpos = 0;
foreach (KeyValuePair<string, int> kvp in UnitEquipment.Inventorylist)
{
ItemIDs.Add(kvp.Key);
ItemQuantities.Add(kvp.Value);
Debug.Log(kvp.Value);
}
ItemDatabase it = ItemDatabase.Load("ItemDatabase");
WeaponDatabase wp = WeaponDatabase.Load("WeaponDatabase");
if (itemcount > 1)
{
for (int j = 0; j < itemdestroy.Count; j++)
{
Destroy(itemdestroy[j]);
}
}
for (int i = 0; i <= UnitEquipment.Inventorylist.Count -1; i++)
{
Itemslot = Instantiate(Itemprefab);
itemdestroy.Add(Itemslot);
foreach (BaseEquipment itemit in it.Items)
{
if (ItemIDs[i] == itemit.ItemID)
{
Itemslot.name = itemit.ItemID;
Itemslot.GetComponentInChildren<Text>().text = itemit.Itemname;
Itemslot.GetComponentInChildren<Text>().name = itemit.ItemID;
Itemslot.transform.Find("Quantity").GetComponent<Text>().text = "x" + ItemQuantities[i].ToString();
}
}
foreach (BaseEquipment itemwp in wp.Weapons)
{
if (ItemIDs[i] == itemwp.ItemID)
{
Itemslot.name = itemwp.ItemID;
Itemslot.GetComponentInChildren<Text>().text = itemwp.Itemname;
Itemslot.GetComponentInChildren<Text>().name = itemwp.ItemID;
Itemslot.transform.Find("Quantity").GetComponent<Text>().text = "x" + ItemQuantities[i].ToString();
}
}
Itemslot.transform.SetParent(Itemcontent.transform);
Itemslot.GetComponent<RectTransform>().localPosition = new Vector3(xpos, ypos, 0);
ypos -= (int)Itemslot.GetComponent<RectTransform>().rect.height;
xpos = 0;
}
}
public void iteminfo()
{
ItemDatabase it = ItemDatabase.Load("ItemDatabase");
WeaponDatabase wp = WeaponDatabase.Load("WeaponDatabase");
foreach(BaseEquipment item in it.Items)
{
if (Itemname.name == item.ItemID)
{
itemid = item.ItemID;
itemdesc = item.ItemDescription;
}
}
foreach(BaseEquipment item in wp.Weapons)
{
if (Itemname.name == item.ItemID)
{
itemid = item.ItemID;
itemdesc = item.ItemDescription;
}
}
}
public void displayitemdescription()
{
Itemdescription.text = itemdesc;
}
Image:
i am not sure if i understood you, you simply want to call that function with its text description? something like this?
Button button = Itemslot.GetComponent<Button>();
button .onClick.AddListener(delegate {displayitemdescription(); });
I've never used addlistener before so I'm not sure, however what I'm trying to do is when I click the instantiated button, ins$$anonymous$$d of having to click another button to display the description, the instantiated button on click displays it. If the button wasn't instantiated it would work without an issue however that's not a possibility here.
From what I can tell the issue arises from the assigning game objects. The objects are all handled by button manager which has everything assigned to it from the menu manager script. When the object is instantiated, to the button none of the gameobjects are assigned therefore it can't assign the information, the most I am able to do is save the information into other game objects and then assign those gameobjects . The first image is how the prefab has the script the 2nd is how the main menu manager has it and this is the issue I'm running into.
If your new instantiated objet is losih the reference is becaue you are instantiating a prefab rather than a gameobject. Drag and drop thr prefab into the scene anf will also lose the refernce, just fill them, leave it somewhre that will never bother you and use that gameobject as GameObject for intantisting
Thank you, I will try this out immediately and this will greatly improve this project's presentation overall.
Answer by Meishin · Aug 31, 2019 at 04:43 AM
Hi @Uranus10,
If i understood correctly you can use event for this, example below where i add an event to a freshly instantiated button ;
// Add event on each items when you initialize your display list and reference the item in it
newButton.onClick.AddListener(delegate { AnyFunction(itemForThisButton);});
// Function called only when clicking on button
private void AnyFunction(BaseEquipment inItem){
// Do whatever you want
Debug.Log("I clicked on item : " + inItem.ItemId + ", Desc : " + inItem.ItemDescription)
}