Search Unity

Question Item effects with Scriptable Objects and serialize

Discussion in 'Getting Started' started by Lory289, Apr 29, 2023.

  1. Lory289

    Lory289

    Joined:
    Apr 8, 2022
    Posts:
    1
    I'm pretty new to Unity and I am trying to make an inventory and equip system. Everything works fine with the inventory and the item pickup, and i am able to equip items, however i dont know how to activate equipped items effects.

    The items are scriptable objects hence i cannot attach any script to them. The only way around this I found was to make a Monobehaviour script to which i could attach both the scriptable object and the effect script, and it worked fine, but this time the problem was with the serialization into file to save the inventory through play sessions, since Monobehaviour is not serializable.

    My inventory saves a list of Scriptable Objects, and my equipment a dictionary where the keys are the equip slots and the values are the Scriptable Objects. How can i scan what items are equipped and activate the corresponding effect for each of them without making hundreds of if statements in the same file?

    Here is some code:

    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3.  
    4. public abstract class ItemClass : ScriptableObject
    5. {
    6.     [Header("Item")]
    7.     // data shared through every item in the game
    8.     public string itemName;
    9.     public bool equip;
    10.  
    11.     public abstract ItemClass GetItem();  
    12.     public abstract ConsumableClass GetConsumable();
    13.     public abstract KeyClass GetKey();
    14. }
    15.  
    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3. using Enums;
    4. using Interfaces;
    5.  
    6. [CreateAssetMenu(fileName = "New Tool Class", menuName = "Item/Consumable")]
    7. public class ConsumableClass : ItemClass
    8. {
    9.     [Header("Consumable")]
    10.     // data specific for each consumable item
    11.     public string name;
    12.     public string description;
    13.  
    14.     public override ItemClass GetItem() { return this; }
    15.     public override ConsumableClass GetConsumable() { return this; }
    16.     public override KeyClass GetKey() { return null; }
    17. }
    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3.  
    4. [CreateAssetMenu(fileName = "New Tool Class", menuName = "Item/Key")]
    5. public class KeyClass : ItemClass
    6. {
    7.     //data specific for each specific key item
    8.     public string name;
    9.     public string description;
    10.    
    11.     public override ItemClass GetItem() { return this; }
    12.     public override ConsumableClass GetConsumable() { return null; }
    13.     public override KeyClass GetKey() { return this; }
    14. }
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. namespace Interfaces
    4. {
    5.     public interface IItemEffect
    6.     {
    7.         public void Passive(); // passive skill
    8.         public void OnEquip(); // ability activated once when the item is equipped
    9.         public void OnHit();  // ability when hitting enemy  
    10.         public void LightSkill(); // active skill 1
    11.         public void HeavySkill(); // active skill 2
    12.     }
    13. }
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Interfaces;
    5. // This is the specific item effect
    6. public class FireCrystal : MonoBehaviour, IItemEffect
    7. {
    8.     private Stats _playerStats;
    9.  
    10.     public void OnEquip() {  }
    11.  
    12.     public void Passive() { Debug.Log("Hi I'm working!"); }
    13.  
    14.     public void OnHit() {  }
    15.  
    16.     public void LightSkill() { return; }
    17.  
    18.     public void HeavySkill() { return; }
    19. }
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using SaveLoad.Runtime;
    5. using Interfaces;
    6.  
    7. public class InventoryManager : MonoBehaviour
    8. {
    9.     public List<ItemClass> inv = new List<ItemClass>();
    10.     public Dictionary<string, ItemClass> equip = new Dictionary<string, ItemClass>();
    11.  
    12.     private Inventory _inventory;
    13.  
    14.     private void Start()
    15.     {
    16.         _inventory = GetComponent<Inventory>();
    17.     }
    18.  
    19.     public void Equip(ItemClass item, string equipSlot)
    20.     {
    21.         equip[equipSlot] = item;
    22.     }
    23.  
    24.     void Update()
    25.     {
    26.         if (Input.GetKeyDown(KeyCode.N))
    27.         {
    28.             foreach( ItemClass item in inv )
    29.            {
    30.                  if (item.equip) Equip(item, "Item");
    31.             }
    32.             foreach(KeyValuePair<string, ItemClass> item in equip) Debug.Log($"{item.Key}: {item.Value}");
    33.         }
    34.     }
    35.  
    36.     public void Add(ItemClass item)
    37.     {
    38.         inv.Add(item);
    39.         _inventory.SaveInv();
    40.     }
    41.  
    42.     public void Remove(ItemClass item)
    43.     {
    44.         inv.Remove(item);
    45.         _inventory.SaveInv();
    46.     }
    47. }
    48.