does anyone know how to create a list that has two Data types like List<Float,Int> sorta deal?.
and also does anything have a good way of handling stackable items? like consumable items?
does anyone know how to create a list that has two Data types like List<Float,Int> sorta deal?.
and also does anything have a good way of handling stackable items? like consumable items?
are you looking for a Dictionary?
Based on your other question you need something like this:
public class Player : MonoBehaviour
{
private List<IInventoryItem> inventory = new List<IInventoryItem>();
private void AddItemToInventory(IInventoryItem item)
{
inventory.Add(item);
}
private void OnCollisionEnter2D(Collision2D coll)
{
if (coll.gameObject.tag == "RedPotion")
{
AddItemToInventory(new PotionItem {Name = "Red Potion", HealthPoints = 100});
Destroy(coll.gameObject);
}
else if (coll.gameObject.tag == "BluePotion")
{
AddItemToInventory(new PotionItem { Name = "Blue Potion", HealthPoints = 25 });
Destroy(coll.gameObject);
}
else if (coll.gameObject.tag == "WoodenShield")
{
AddItemToInventory(new ShieldItem { Name = "Wooden Shield", ProtectionPoints = 30 });
Destroy(coll.gameObject);
}
}
}
public interface IInventoryItem
{
string Name { get; set; }
}
public abstract class InventoryItemBase : IInventoryItem
{
public string Name { get; set; }
}
public class PotionItem : InventoryItemBase
{
public int HealthPoints { get; set; }
}
public class ShieldItem : InventoryItemBase
{
public int ProtectionPoints { get; set; }
}
And later you can use items this way:
foreach (var inventoryItem in inventory)
{
Debug.Log(inventoryItem.Name);
var potionItem = inventoryItem as PotionItem;
if (potionItem != null)
{
Debug.Log(potionItem.HealthPoints);
}
var shieldItem = inventoryItem as ShieldItem;
if (shieldItem != null)
{
Debug.Log(shieldItem.ProtectionPoints);
}
}
i should prob have asked different but i am using Scriptable Objects to Define data for a item. and i somehow need to give each Item that exist a Varible of how many there is of that item
@iamvideep_1 no since its a inventory item and multiple of same kind can exist that wouldn’t work to my knowledge
Then you could derive your InventoryItemBase form ScriptableObject
public abstract class InventoryItemBase : ScriptableObject, IInventoryItem
{
public string Name { get; set; }
}
well u can’t really do that since Scriptable Objects doesn’t really exist in the game they just hold information as soon as u change a ScriptableObject the information changes for all items that uses that ScriptableOjbect
Does something like this help for the first part of your question.
public struct CustomData
{
public float data1;
public int data2;
}
List<CustomData> myCustomDataList = new List<CustomData>();
Regarding the second part, as far as I am aware there is no automatic way to handle stackable items, you’ll need to work something out that fits in with your inventory design.
ye thats the thing i am trying to find out. how i can go about making items stackable when i am using Scriptable Objects. since each item can be stackable i need some value to determine how many times it can be used before it should be deleted
In your gameitem/inventory slot class have a qty variable, and each time you use the item, reduce the value of qty by one. When it reaches zero the stack is empty so you can destroy the item.
i wish it was that simple.
but i need to find a way to give it a Quanitity number everytime i loot it. and Potions are never instantiated as objects
Create these classes:
using UnityEngine;
public abstract class InventoryItemBase : ScriptableObject
{
public string Name;
}
[CreateAssetMenu]
[System.Serializable]
public class PotionItem : InventoryItemBase
{
public int HealthPoints;
}
[CreateAssetMenu]
[System.Serializable]
public class ShieldItem : InventoryItemBase
{
public int ProtectionPoints;
}
Now from the Unity menu Assets - > Create some Potion Items and some Shield Items, for example Blue Potion, Red Potion, Wooden Shield, Bronze Shield and as you wish and assign their properties (maybe Red Potion could have more health points then Blue Potion and so on).
Now create empty scene with two empty GameObjects and call them “Player” and “Chest”. Create the classes below and drag them to the appropriate GameObject (Chest on Chest and Player on Player):
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public List<InventoryItemBase> Inventory = new List<InventoryItemBase>();
private void OpenChest()
{
var chest = GameObject.Find("Chest").GetComponent<Chest>();
for (var index = 0; index < chest.InventoryItems.Length; index++)
{
var item = chest.InventoryItems[index];
if (item != null)
{
Inventory.Add(item);
chest.InventoryItems[index] = null;
}
}
}
private void DisplayInventory()
{
foreach (var inventoryItem in Inventory)
{
Debug.Log(inventoryItem.Name);
var potionItem = inventoryItem as PotionItem;
if (potionItem != null)
{
Debug.Log(potionItem.HealthPoints);
}
var shieldItem = inventoryItem as ShieldItem;
if (shieldItem != null)
{
Debug.Log(shieldItem.ProtectionPoints);
}
}
}
private void Start()
{
OpenChest();
DisplayInventory();
}
}
using UnityEngine;
public class Chest : MonoBehaviour
{
public InventoryItemBase[] InventoryItems;
}
Now click on Chest gameobject and from the inspector make Inventory Items array of size for example 5 and drag your potions and shields there.
Run the scene and you will see your items moving from the chest to the player’s inventory.
What exactly are you storing in the list now? One typical way to do this is something like:
class InventoryItem
{
string Id { get; private set; }
int Quantity { get; set; }
...
}
void AddInventoryItem (InventoryItem item)
{
var existing = _inventory.Find(x => x.Id == item.Id);
if(existing != null)
{
existing.Quantity++;
}
else
{
_inventory.Add(item);
}
}
class Pickup : MonoBehaviour
{
public InventoryItem GetItem () { ... }
...
}
I didn’t read every reply, but just throwing in my opinion as a “simple” option.
With the item as a scriptable object, the easiest way I think is to have a class that holds both the item and the quantity (stack size).
public class ItemHolder : MonoBehaviour {
ScriptableObjectItem item;
int amount;
}
That’s it
Whatever you have more or less in your game/design should still work with that idea.
Exactly what he said, plus to handle the list stackable
List<ItemHolder> items = new List<ItemHolder>(0)
void AddToInventory(ItemHolder item)
{
int i = ListContains(item);
if( i >= 0)
{
ItemHolder old = items[i];
old.amount = Mathf.Clamp( old.amount + item.amount,0,maxStackSize);
}
else
{
items.add(item);
}
}
int ListContains(item)
{
for(int i = 0; i< items.Count;i++)
{
if(items[i].ScriptableObjectItem == item.ScriptableObjectItem)
return i;
}
return -1;
}
Uh forgot to Mark this as Solved