Home > Back-end >  Only letting a string be a certain value: Scriptable Objects
Only letting a string be a certain value: Scriptable Objects

Time:08-02

I was working on a scriptable object type for any item in my game and I have a string called s_Type. I only want this string to be a certain value; "food", "story", "collectible", or "nothing". I though about using a class but it would create a loss of mess in my script and I would just prefer using a simple string. How could i return an error if the string's value is not one of the above?

Here is my current script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PickableItem : ScriptableObject
{
    [Header("Properties")]

    /// <summary>
    ///(string) The name of the item
    /// </summary>
    public string s_ItemName;

    /// <summary>
    /// (string) Description of the item
    /// </summary>
    public string s_Description;

    /// <summary>
    /// (string) types can be as followed: "food", "story", "collectible", "nothing"
    /// </summary>
    public string s_Type;
}

CodePudding user response:

Use an enum value:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PickableItem : ScriptableObject
{
    [Header("Properties")]

    /// <summary>
    ///(string) The name of the item
    /// </summary>
    public string s_ItemName;

    /// <summary>
    /// (string) Description of the item
    /// </summary>
    public string s_Description;

    /// <summary>
    /// (string) types can be as followed: "food", "story", "collectible", "nothing"
    /// </summary>
    public string s_Type  => s_TypeEnum.ToString();

    /// <summary>
    /// (string) types can be as followed: "food", "story", "collectible", "nothing"
    /// </summary>
    [SerializeField] private sType s_TypeEnum;
}

public enum sType 
{
    nothing, 
    story,
    collectible, 
    food
}

CodePudding user response:

Well, you cannot enforce a rule stating that the string will only be of those words, but if you want, you can use a property, like this:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PickableItem : ScriptableObject
{
    [Header("Properties")]

    /// <summary>
    ///(string) The name of the item
    /// </summary>
    public string s_ItemName;

    /// <summary>
    /// (string) Description of the item
    /// </summary>
    public string s_Description;

    /// <summary>
    /// (string) types can be as followed: "food", "story", "collectible", "nothing"
    /// </summary>
    private string s_Type0;

    public string s_Type
    {
        get
        {
            return s_Type0;
        }

        set
        {
            switch (value)
            {
                case "food":
                case "story":
                case "collectible":
                case "nothing":
                    s_Type0 = value;
                    break;
                default:
                    throw new InvalidArgumentException("Invalid value!");
            }
        }
    }
}

But I would prefer doing it this way:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PickableItem : ScriptableObject
{
    public enum S_TYPE
    {
        Food,
        Story,
        Collectible,
        Nothing
    }

    [Header("Properties")]
    /// <summary>
    ///(string) The name of the item
    /// </summary>
    public string s_ItemName;

    /// <summary>
    /// (string) Description of the item
    /// </summary>
    public string s_Description;

    /// <summary>
    /// (string) types can be as followed: "food", "story", "collectible", "nothing"
    /// </summary>
    public S_TYPE s_Type;
}

Then you can use s_Type.ToString() to get the string value, and then check accordingly.

CodePudding user response:

You can turn your field into a property and make its setter method throw an exception if the input is not an expected value:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PickableItem : ScriptableObject
{
    [Header("Properties")]

    /// <summary>
    ///(string) The name of the item
    /// </summary>
    public string s_ItemName;

    /// <summary>
    /// (string) Description of the item
    /// </summary>
    public string s_Description;
    
    /// <summary>
    /// (string) a private storage field for s_Type, can be named whatever you want
    /// </summary>
    private string s_type;
    
    /// <summary>
    /// (string) types can be as followed: "food", "story", "collectible", "nothing"
    /// </summary>
    public string s_Type {
      get {
        return s_type;
      }
      set {
        switch (value) {
          case "food":
          case "story":
          case "collectible":
          case "nothing":
            s_type = value;
            break;
          default:
            throw new ArgumentException("Unknown PickableItem type!");
        }
      }
    }
}

but creating an enum would probably be much better, especially if those values will be coming from your code and not user input. Still, here's your answer.

  • Related