Search code examples
c#unity-game-engine

Show Inventory Sprites on GameObject


So I have these three gameObjects that rotate around the player and an inventory system for ghosts that will eventually heal the player. I followed this tutorial: "https://www.youtube.com/watch?v=AoD_F1fSFFg" and am at the point where when you pickup an item, it is shown in your inventory. Instead of the sprites showing in the inventory, I want them to appear at the three gameObjects circling the player, but I am unsure on how to go about this. Please help.

Manager and 3 gameObjects (Ghost1, 2, 3)

public class GhostManager : MonoBehaviour
{
    public static GhostManager Instance;
    public List<Ghost> Ghosts = new List<Ghost>();

    public GameObject ghost1;
    public GameObject ghost2;
    public GameObject ghost3;

    private void Awake()
    {
        Instance = this;
    }

    public void Add(Ghost ghost)
    {
        Ghosts.Add(ghost);
    }

    public void Remove(Ghost ghost)
    {
        Ghosts.Remove(ghost);
    }

    public void ListItems()
    {
        foreach (var ghost in Ghosts)
        {
            GameObject obj = Instantiate(ghost1);
            var ghostIcon = obj.transform.Find("GhostIcon").GetComponent<Image>();

            ghostIcon.sprite = ghost.icon;
        }
    }
}
public class GhostPickUp : MonoBehaviour
{
    public Ghost ghost;
    private int maxGhosts = 3;

    void PickUp()
    {
        if (GhostManager.Instance.Ghosts.Count < maxGhosts)
        {
            GhostManager.Instance.Add(ghost);
            Destroy(gameObject);
        }
    }

    void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.CompareTag("Player"))
        {
            PickUp();
        }
    }
}
[CreateAssetMenu(fileName = "New Ghost", menuName = "Ghosts/Create New Ghosts")]
public class Ghost : ScriptableObject
{
    public int id;
    public string itemName;
    public int value;
    public Sprite icon;
}

Solution

  • Option 1: you can use a UI Canvas, set it to World Space and properly position it in you hierarchy and in your scene.

    In this case you can use the same sprites as for UI.

    Option 2: you can use a 3D Quad and properly position it in you hierarchy and in your scene.

    In this case you need to also properly set texture and material that represent your sprites.


    Your OnTriggerEnter seems fine, your PickUp seems fine, your Add seems fine.

    ListItems looks strange:

    • for some reason, you instantiate ghost1 in a loop. First of all, you don't need to instantiate it, as it is already in the scene. Second, you probaly don't want to dipaly all your objects in teh same place.

    • you use transform.Find("GhostIcon") to find a child of your newly created instance of ghost1 with the name GhostIcon. But I see no chidlren of ghost1 in your scene

    • what you need to do is something like this:

      for (var i = 0; i < 3; i++)
      {
          // Or you can just use List<GameObject> ghostVisuals instead of ghost1, ghost2 and ghost3
          GameObject currentGhost = null;
          if (i == 0)
              currentGhost = ghost1;
          else if (i == 1)
              currentGhost = ghost2;
          else if (i == 2)
            currentGhost = ghost3;
          else
              throw new InvalidOperationException();
      
          if (Ghosts.Count > i) {
              currentGhost.SetActive(true); // We have a ghost, so enable the GameObject
      
              // Here you access the data you need for the `currentGhost`
              // e.g. if you have added a child GhostIcon to it:
              var ghostIcon = currentGhost.transform.Find("GhostIcon").GetComponent<Image>();
              ghostIcon.sprite = Ghosts[i].icon;
          }
          else {
              currentGhost.SetActive(false); // No more ghosts, disable the game object
          }
      }
      

      This way, you access each of your three ghost game object in a sequence.