Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Is it possible to do this in a scriptable object?

Discussion in 'Scripting' started by elliotbra, Jul 8, 2023.

  1. elliotbra

    elliotbra

    Joined:
    Jul 21, 2022
    Posts:
    46
    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.UI;
    6.  
    7. [CreateAssetMenu(fileName = "Shop", menuName = "Scriptable Objects/New Shop Item", order = 1)]
    8. public class ShopItemData : ScriptableObject
    9. {
    10.     public string ItemName;
    11.     public Sprite ItemImage;
    12.     public string ItemType;
    13.     public int ItemCost;
    14.     public int ItemPercentage;
    15.     public bool unlocked;
    16.  
    17.     void Update()
    18.     {
    19.         unlocked = PlayerPrefs.GetInt(ItemName + "Unlocked")!= 0;
    20.     }
    21. }
     
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    4,019
    Do what exactly? CreateAssetMenu? Reference a Sprite? Use Update? Use PlayerPrefs? Concatenate strings?
     
    Bunny83 likes this.
  3. elliotbra

    elliotbra

    Joined:
    Jul 21, 2022
    Posts:
    46
    I mean the Update and PlayerPrefs.
     
  4. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    4,019
    What makes you think it wouldn't work? You already have the code so I would assume you gave it a try. ;)

    In any case I see nothing in that code that wouldn't work. But keep in mind if you create multiple assets using ShopItemData then they will ALL access PlayerPrefs EVERY FRAME to check their unlocked state. Also, string concatentation every update will create GC allocations / garbage.

    I'd rather advise on making an event ItemUnlocked that the ScriptableObject registers with to be notified when an item gets unlocked.
     
  5. elliotbra

    elliotbra

    Joined:
    Jul 21, 2022
    Posts:
    46
    Okay, thank you
     
  6. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,124
    ScriptableObject doesn't have an Update() method that is automatically called every frame.

    https://docs.unity3d.com/ScriptReference/ScriptableObject.html

    You wouldn't want to do it even if you could though as PlayerPrefs accesses a storage device which is always a high performance penalty compared to accessing main memory. Ideally you only want to do this once, and you don't want to use PlayerPrefs as it's not designed for holding more than small amounts of data (ie settings data).
     
    Bunny83 likes this.
  7. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,524
    Right. So the issue here is that the code does work. However Update would never be called since it currently is private and therefore is not accessible from outside the class. So if another system wants to update the values of a certain SO instance it has to explicitly call that method. You probably should rename the method to be more descriptive like LoadFromPrefs or something like that. You probably would have a SaveToPrefs as well which does the opposite, right? Or how do you save the values in the first place? Since you encapsulate the loading of that value inside the class itself, the saving should be handled in that class as well. So the details about how the values are saved / loaded are "DKDC" (Don't Know, Don't Care) to other systems.