Use ScriptableObject correctly

Hi
When I intend to use scriptableobject in my game, I have a doubt how to use it correctly
For example I have a soldier that has different classes like MoveComponent, AttackComponent,…

public class MoveComponent:MonoBehaviour{
   float currentSpeed;
   float currentHP;
   float maxSpeed; // initialized by ScriptableObject
   float maxHP; // initialized by ScriptableObject
   Wepoan[] weapons; // initialized by ScriptableObject

   [SerializeField]
   MoveSoldierSO moveSoldierSO;
   [SerializeField]
   HealthSoldierSO healthSoldierSO;
   [SerializeField]
   WeaponSoldierSO weaponSoldierSO;
   void Awake(){
      maxSpeed=moveSoldierSO.maxSpeed;
      maxHP=healthSoldierSO.maxHP;
      weapons=weaponSoldierSO.weapons;
   }
   void OnEnable(){

   }
}

My questions:
1- I do not know whether I make a scriptableobject for a soldier like below:

[System.Serializable]
public class SoldierSO:ScriptableObject{
   public float maxSpeed;
   public Wepoan[] weapons;
   public float maxHP;
//...
}

or separate them:

[System.Serializable]
public class MoveSoldierSO:ScriptableObject{
   public float maxSpeed;
}
[System.Serializable]
public class HealthSoldierSO:ScriptableObject{
   public float maxHP;
}
[System.Serializable]
public class WeaponSoldierSO:ScriptableObject{
   public Wepoan[] weapons;
}

If I separate them, I can use them in suitable components instead of sending the complete scriptableObject to them(components)
It is better to break them in level of components or one field(every scriptableObject contains only one field like maxHP, maxSpeed,… because I see that some people create scriptableObjects that have only one field)?

public class FloatVariable:ScriptableObject{
   public float value;
}
// it can be maxHP,maxSpeed,etc
they are dragged and dropped on an inspector directly

I see a scriptableObject as a tool to inject data to my classes but I faced codes a lot that send GameObject to a ScriptableObject and initialize them inside it:

public class MoveSO:ScriptableObject{
  [SerializeField]
   float maxSpeed;
   public void Initialize(GameObject _obj){
      MoveComponent moveBehaviour=_obj.GetComponent<MoveComponent>();
      moveBehaviour.maxSpeed=maxSpeed;
   }
}

Even more, they bring all functions inside a scriptableobject and call them from monobehaviour functions(in update or OnCollsionEnter or ClickEvent,…)
I am confused which way is suitable
Thank you

You don’t need to add System.Serializable to Scriptable Objects.

As for which is better, I think it’s a matter of choice & what’s comfortable for you. If you did go the route of using very small pieces, I think you should make them a little more generic, though.
You could watch this if you haven’t seen it (where something similar is done):

I just watched that today, for the first time.

1 Like

Thank you dude
I have already seen the video. It caused my confusion and clutter :slight_smile:

Also I watched the video
Unite 2016 - Overthrowing the MonoBehaviour Tyranny in a Glorious Scriptable Object Revolution

I think that they do not only use scriptableObjects as a tool to inject data to monobehaviours and initialize them.
They create scriptableObjects as inner classes inside monobehaviours that contain both data and functions

If we need that designers can interact easily, define, change and set properties, scriptableObjects can help and they are more suitable than finding them in a scene but we should define a lot of properties like (font,outline,shadow,color,alignment,… only for one text component!)

public class TextSO:ScriptableObject{
   public Color color;
   public Font font;
   public int fontSize;
//...
}

public class TextBehaviour:Monobehaviour{
   [SerializeField]
   TextSO textSO;
}

Most of your examples don’t make much sense and it is hard to imagine what you want to achieve. Better try to descibe your goal in plain english.