Confused about why my UI Text is not updating.

Hello,

I’m trying to prototype an inventory and having an issue updating my UI Text. All I want to achieve for now is to list my inventory down the side of the screen and allow the user to scroll through the inventory which will add a “>” to the item’s text field.

I’ve managed to do most of this. When the user picks up items in the scene, the UI refreshes and draws them to the screen. Pressing Q after having both items in the inventory draws a “>” in front of the first picked up item. Pressing Q again should remove the “>” from the first item and add it to the second. However, both items get the “>”. Pressing Q a third time correctly removes “>” from both items as I now have nothing selected.

I tried calling the method that I use to redraw the inventory (thus grabbing their original names and removing the “>” like I do when no items are selected) but then no “>” draw at all despite me debugging and can see that the object I am trying to effect seems correct and the .text seems to be set correctly.

I’m confused my adding this method call UpdateItemInventory() in UpdateItemSelection() makes my Text components not update at all.

Hopefully I’ve explained this well enough, any help would be greatly appreciated.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Inventory : MonoBehaviour {

    private GameObject player;

    // Temp variables for placeholder UI
    public GameObject tempInventoryText;
    private Transform tempInventoryUI;

    public int itemSelected = 0;

    // Create an array to store picked up items
    private static List<GameObject> inventoryItems = new List<GameObject>();

    void Start()
    {
        player = gameObject.GetPlayer();
        // Temp UI gameObject has a tag UI_Parent. This has a vertical layout so each Text script added to it when
        // the UI is updated gets put into a new row.
        tempInventoryUI = GameObject.FindGameObjectWithTag("UI_Parent").transform;
    }

    void Update()
    {
        if (Input.GetButtonDown("ItemSelect"))
        {
            if(inventoryItems.Count > 0)
            {
                if (itemSelected < inventoryItems.Count)
                {
                    itemSelected++;
                    UpdateItemSelection();
                }
                else
                {
                    itemSelected = 0;
                    UpdateItemSelection();
                }
            }
        }
    }

    // Method that allows gameobjects to be added to the players inventory, can be called from other scripts.
    public void AddItemToInventory(GameObject itemObject)
    {
        inventoryItems.Add(itemObject);
        print("The player has " + inventoryItems.Count + " items in their inventory!");
        int i = 0;

        foreach(GameObject inventoryItem in inventoryItems)
        {
            print("Inventory item [" + i + "] is : " + inventoryItem);
            i++;
        }

        // Once items have been added to the inventory, update the temp UI and update selection
        UpdateItemInventory();
        UpdateItemSelection();
    }

    private void UpdateItemInventory()
    {
        // Delete all inventory from the screen before replacing it.
        // For every transform under UI_Parent, destroy.
        foreach(Transform trans in tempInventoryUI)
        {
            Destroy(trans.gameObject);
        }

        // For each item in the inventory, instanciate empty text prefab and put it under the tagged GameObject, "UI_Parent"
        foreach(GameObject inventoryItem in inventoryItems)
        {
            GameObject tempItemUI = Instantiate(tempInventoryText, tempInventoryUI) as GameObject;
            Text tempUIText = tempItemUI.GetComponentInChildren<Text>();
            // Set the text of the empty Text prefab to the current for each loop item name.
            tempUIText.text = inventoryItem.name;
        }
    }
    
    private void UpdateItemSelection()
    {
        if (inventoryItems.Count > 1)
        {
            if (itemSelected != 0)
            {
                //Leaving the below call in makes no ">" draw to the screen at all. Taking away the method allows me to draw them to the screen but
                // I need to try and clear the UI before adding them so that I don't get all items with a ">"
                UpdateItemInventory();

                Text tempItemSelected = tempInventoryUI.GetChild(itemSelected - 1).gameObject.GetComponentInChildren<Text>();
                string currentItemUIText = tempItemSelected.text;
                tempItemSelected.text = ">" + currentItemUIText;
            }
            else
            {
                // Redraw inventory
                UpdateItemInventory();
            }
        }
    }
}

Ok, I’m going to attempt to really help you out here with all of this UI stuff.

Text tempItemSelected = tempInventoryUI.GetChild(itemSelected - 1).gameObject.GetComponentInChildren<Text>();

This is crazy difficult to follow! Not to mention, it’s unnecessary. I highly recommend that you create more classes to deal with this situation more appropriately. Because it’s been 3 days and no one has answered you, I spend about a half hour typing the following out for you. Please ask questions, and I hope many more can use my code as well.

Updated Inventory Class:

using UnityEngine;
using System.Collections.Generic;
using System;

public class Inventory : MonoBehaviour
{
    [SerializeField]
    private GameObject _player;             //A reference to the Player GameObject
    [SerializeField]
    private RectTransform _rectTransfrom;   //A reference to the Inventory UI parent transform
    [SerializeField]
    private GameObject _itemHolderPrefab;   //A reference to the Item UI prefab
    [SerializeField]
    private List<InventoryItemUI> _items;   //A reference to the Item UIs (Dynamic Generic Collection) in the inventory

    private int _selectedIndex;             //Index of the selected item within _items

    /// <summary>
    /// I use the Awake method to get references for all of my objects.
    /// </summary>
    private void Awake()
    {
        //Allow the Player to be dragged on in the Inspector, but if it's null, get the player a different way.
        //Note: This gives me an error, so just remove the comments below.
        //if (_player == null)
            //_player = gameObject.GetPlayer();

        //Allow the Rect Transform (UI Parent Transform) to be dragged on in the Inspector, but if it's null, assume it's on this object and get the component.
        if (_rectTransfrom == null)
            _rectTransfrom = GetComponent<RectTransform>();

        if (_itemHolderPrefab == null)
        {
            _itemHolderPrefab = new GameObject();
            _itemHolderPrefab.AddComponent<InventoryItemUI>();
        }

        _items = new List<InventoryItemUI>();
        _selectedIndex = -1;
    }

    /// <summary>
    /// Just checking if we should increment the selected index. If we should, do so, then update.
    /// </summary>
    private void Update()
    {
        if (Input.GetButtonDown("ItemSelect"))
        {
            if (_items.Count > 0)
            {
                UpdateSelection();
            }
        }
    }

    /// <summary>
    /// Instantiates a new itemHodler from the prefab.
    /// Then we create a reference to the ItemUI.
    /// Then we set the ItemUI's item to the passed in item.
    /// Then we add that ItemUI to the list of other UIs.
    /// </summary>
    /// <param name="item">The item data for the new Item Holder</param>
    public void AddItem(InventoryItem item)
    {
        GameObject itemHolder = Instantiate(_itemHolderPrefab);
        InventoryItemUI itemUI = itemHolder.GetComponent<InventoryItemUI>();
        itemUI.source = item;

        _items.Add(itemUI);
    }

    /// <summary>
    /// Use FindItem to get the Index that this item is associated with.
    /// </summary>
    /// <param name="item"></param>
    public void RemoveItem(InventoryItem item)
    {
        RemoveItemAt(FindItem(item));
    }

    /// <summary>
    /// If the index is within valid range, delete the item.
    /// We first get a reference to the Game Object of the ItemUI.
    /// We then remove the ItemUI.
    /// Lastly, delete the Game Object.
    /// </summary>
    /// <param name="index"></param>
    public void RemoveItemAt(int index)
    {
        if (index > 0 && index < _items.Count)
        {
            GameObject itemHolder = _items[index].gameObject;
            _items.RemoveAt(index);
            Destroy(itemHolder);
        }
    }

    /// <summary>
    /// Used to find the index of the ItemUI that this Item is associated with.
    /// Returns -1 if it doesn't exist.
    /// </summary>
    /// <param name="item"></param>
    /// <returns></returns>
    private int FindItem(InventoryItem item)
    {
        for (int i = 0; i < _items.Count; i++)
            if (_items*.source == item)*

return i;

return -1;
}

///


/// This will deselect an item if the selected index is within range.
/// Then it will add to the the selection index.
/// Lastly it selects the the new ItemUI.
///

private void UpdateSelection()
{
if (_selectedIndex >= 0 && _selectedIndex < _items.Count)
_items[_selectedIndex].Deselect();

if (_selectedIndex < _items.Count)
_selectedIndex++;
else
_selectedIndex = 0;

_items[_selectedIndex].Select();
}
}
InventoryItemUI Class:
using UnityEngine;
using UnityEngine.UI;

public class InventoryItemUI : MonoBehaviour
{
[SerializeField]
private Text _displayText;

private InventoryItem _data;

public InventoryItem source { get { return _data; } set { _data = value; } }
public string displayText { get { return _displayText.text; } set { _displayText.text = value; } }

///


/// This will add a carrot to the source name on the Text object.
///

public void Select()
{
displayText = "> " + source.name;
}

///


/// This will set the Text object’s text to the source name.
///

public void Deselect()
{
displayText = source.name;
}
}
InventoryItem Class:
public class InventoryItem
{
public string name = “New Item”;

//This is just a class to hold all of your data and pass it around without being coupled with specific UI functionality.
}
I hope this helps out a lot! Good luck!