I'm creating a system where I have my cards in ScriptableObject, but each card has a unique function. What I thought of was creating a new class for each skill that inherits from "skills". So I put this script for each letter in my ScriptableObject, but now I'm trying to access it and I can't, because I couldn't use the AddComponent.
public class Cards : ScriptableObject
{
public Sprite cardSprite;
public int cardAttack;
public int cardHealth;
public int cardCost;
public Object cardAbility;
}
CodePudding user response:
A scriptable object is a data container. A material or lighting settings are scriptable objects. You can save them as assets and use them as settings for other scripts, but not attach them to GameObjects. Read more here.
To create ScriptableObjects in the asset browser, you need to add the following before the start of your class.
[CreateAssetMenu(fileName = "DefaultFileName", menuName = "ScriptableObjects/NameOfYourObjects", order = 1)]
To add them to a script, you use public Cards cards;
then you can drag them from your asset browser to the script in the inspector.
The only things you can add to a GameObject are MonoBehaviors
CodePudding user response:
As you realized, you can't use AddComponent with ScriptableObjects, because it can only be used to attach components to GameObjects.
ScriptableObjects however do support a somewhat similar concept of main assets and sub assets.
You can use AssetDatabase.AddObjectToAsset to add new sub assets, and they'll appear as nested children below the main asset in the Project view.
public abstract class Skill : ScriptableObject
{
#if UNITY_EDITOR
protected static void AddToCard<TSkill>(MenuCommand command) where TSkill : Skill
{
Card card = (Card)command.context;
TSkill skill = CreateInstance<TSkill>();
skill.name = skill.GetType().Name;
card.skill = skill;
string path = AssetDatabase.GetAssetPath(card);
AssetDatabase.AddObjectToAsset(skill, path);
AssetDatabase.ImportAsset(path);
}
[MenuItem("CONTEXT/Card/Remove Skill")]
protected static void RemoveSkill(MenuCommand command)
{
Card card = (Card)command.context;
string path = AssetDatabase.GetAssetPath(card);
Skill skill = AssetDatabase.LoadAssetAtPath<Skill>(path);
AssetDatabase.RemoveObjectFromAsset(skill);
AssetDatabase.ImportAsset(path);
}
#endif
}
using UnityEditor;
using UnityEngine;
[CreateAssetMenu]
public class ExampleSkill : Skill
{
#if UNITY_EDITOR
[MenuItem("CONTEXT/Card/Add Skill/Example Skill")]
private static void AddToCard(MenuCommand command) => AddToCard<ExampleSkill>(command);
#endif
}
using UnityEngine;
[CreateAssetMenu]
public class Card : ScriptableObject
{
public Skill skill;
}