I am currently working on an inventory script to hold items like keys in my game. I have it all set up where items can be picked up, and are basically added to a list of items I can cycle through with “Q.”
This works well. However I have ran into issues when removing the objects from the list, i.e. using the key and removing it from the player’s inventory.
If I have a set up like: Barehands, Key1, Key2, Key3, and start “deleting” the keys starting with 3, then 2, etc. it works perfectly. Key three gets deleted and the game recognizes I am now holding Key2, since it is now the last one in the list.
However, with the same setup, I experience an issue when attempting to use the keys in the opposite direction. When holding: Barehands, Key1, Key2, Key3, when I delete Key1, instead of Key2 becoming the active item in the player’s hand, it glitches. Usually, the result is the key being deleted, but no new item being “selected,” furthermore, when I press “Q” again, it seems to either select Barehands (first in list) as the active item, or skip Key2 and make Key3 active, although using Key3 deletes Key2 from the list, etc.
I don’t usually like to just throw code walls up and ask for a solution but I have been banging my head against the wall all week. I believe the original item-switching mechanism was from a Brackeys tutorial and was modified for my game, in addition to random things inside the DestroyItem() function in hopes of me solving it myself. Any ideas on how to fix this issue?
My Inventory Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Inventory : MonoBehaviour
{
public GameObject[] items; //Held Items
public GameObject heldItems;
private ItemSwitching itemSwitching; //Tracking of Item Slot Number
public GameObject currentHeldItem; //current Item in hand
public GameObject destoryThis;
// Start is called before the first frame update
void Start()
{
heldItems = GameObject.Find("HeldItems");
itemSwitching = heldItems.GetComponent<ItemSwitching>();
}
// Update is called once per frame
void Update()
{
if (itemSwitching.selectedItem != 0)
{
currentHeldItem = items[itemSwitching.selectedItem]; //If not barehanded, make currentHeldItem the current item in hand
}
else
{
currentHeldItem = null; //else make it nothing
}
if (Input.GetKeyDown(KeyCode.L))
{
DestroyItem();
}
destoryThis = currentHeldItem;
}
public void updateInventory()
{
//Move every item down, filling all possible slots first.
int nextFree = 0;
for (int i = 0; i < items.Length; i++) // whole inventory list
{
GameObject ivi = items[i]; // temp copy
if (ivi == null) continue;
//print("copying " + ivi.name + " from " + i + " to " + nextFree);
items[i] = null; // so we don't have extra copies
items[nextFree] = ivi; // this may copy over the same spot, which is fine
nextFree++;
}
}
public void DestroyItem()
{
currentHeldItem = null;
Debug.Log(destoryThis);
Destroy(destoryThis);
items[itemSwitching.selectedItem] = null; //Make Inventory Slot Empty
itemSwitching.selectItem();
items[itemSwitching.selectedItem].SetActive(true);
itemSwitching.selectedItem++;
updateInventory();
}
My Item Switching Script:
using UnityEngine;
public class ItemSwitching : MonoBehaviour
{
public int selectedItem = 0;
public GameObject currentlyHeldItem;
// Start is called before the first frame update
void Start()
{
selectItem();
}
// Update is called once per frame
void Update()
{
int previousSelectedItem = selectedItem;
if (Input.GetKeyDown(KeyCode.Alpha1))
{
selectedItem = 0;
}
if (Input.GetKeyDown(KeyCode.Alpha2) && transform.childCount >= 2)
{
selectedItem = 1;
}
if (Input.GetKeyDown(KeyCode.Q))
{
if (selectedItem >= transform.childCount - 1)
selectedItem = 0;
else
selectedItem++;
}
if (!Input.GetKeyDown(KeyCode.Q) && selectedItem >= transform.childCount )
{
selectedItem = transform.childCount - 1;
}
if (previousSelectedItem != selectedItem)
{
selectItem();
}
}
public void selectItem()
{
int i = 0;
foreach (Transform item in transform)
{
if (i == selectedItem)
{
item.gameObject.SetActive(true);
Debug.Log(item.gameObject.name);
currentlyHeldItem = item.gameObject;
}
else
{
item.gameObject.SetActive(false);
}
i++;
}
}
}
The deletion function is called from a third script that just checked if iyemSwitch.currentlyHeldItem is the required object (key for door player is trying to open), and calls the DestroyItem() function in the inventory script.