Home>

I have a ship prefab that has characteristics and logic. Due to my inexperience in creating this object, I made a regular spawn. That is, each spawning object had its own characteristics and so on, which, of course, loaded the system. Then I found out about scriptableObject, but as I understood, the logic is not written there. Only the description of the object should be written there. But in R. Sakutin's course, logic is written in SO. Question: Is it correct to write the logic in SO and will it be executed at all in this case?

  • Answer # 1

    Writing logic in ScriptableObject is very correct. But you need to take into account that, unlike MonoBehaviour, there will be no events like Awake (), Start () and so on.

    For example, you can approach the code in a ScriptableObject like this:

    1. Describe the interface, the step is optional but will help you understand the idea
    public interface ISomeSubSystemManager
    {
        void Init ();
        void DoTheWork ();
        void ProcessSomething ();
    }
    
    1. Make basic SO based on this interface
    using UnityEngine;
    //We don't want create 'CreateAssetMenu' items, because its our base class
    public abstract class DamageSystemManager: ScriptableObject, ISomeSubSystemManager
    {
        public List <
    Unit >
     units {get; set; }
        public abstract void Init ();
        public abstract void DoTheWork ();
        public abstract void ProcessSomething ();
        public abstract void AddUnit (Unit unit);
    }
    
    1. Describing the logic of the system (s)
    using UnityEngine;
    [CreateAssetMenu (fileName= "GroundUnitsDamageSystemManager", menuName= "DamageSystemManagers /GroundUnitsDamageSystemManager", order= 1)]
    public class GroundUnitsDamageSystemManager: DamageSystemManager
    {
        public override void Init ()
        {
            //Init something
        }
        public override void DoTheWork ()
        {
            //Do some work
        }
        public override void ProcessSomething ()
        {
            //Process Something
        }
        public override void AddUnit (Unit unit);
        {
            //Add and Process new units
        }
    }
    
    1. Already from the main code, you can work with the created () and instance (s) of these SOs.
    using UnityEngine;
    public class SomeMonoBehaviour: MonoBehaviour
    {
        public DamageSystemManager damageSystemManager;
        void Start ()
        {
            damageSystemManager.Init ();
        }
        void Update ()
        {
            damageSystemManager.ProcessSomething ();
        }
    }
    

    For the system described above, regular classes may be more suitable, but I wanted to describe what you can count on if you use SO as a container with code.

  • Answer # 2

    Most often they are used as a data container, a set of profiles of the same type with different settings, a container with an array of such profiles or constants. Of course, in such ScriptableObject there can be methods for receiving data in a different form, in a more convenient way by enum or key, getting a random one from a certain array, generated data based on configured parameters, and so on.

    It can even have an entity responsible for which array elements are unlocked for use and which is the current and the entity of saving and loading this data, such as for a set of skins.

    It is very convenient to use it even without any fields, as a general access point outside the scene instead of static signal tones. If the object is not tied to a specific scene, then you can make it a ScriptableObject, that's the whole principle.

    ScriptableObject certainly doesn't execute Unity magic methods: Start, OnEnable, Update, etc. If it is larger than the data container, someone has to kick it once at the start of the game, so that it initializes /loads data, etc. Some kind of "entry point".

    Roma has a lot of experience, more than those who can be contacted with a question on forms on the Internet.

  • Answer # 3

    In theory, ScriptableObject is created to store information, settings, configuration. If logic is implemented in the inherited class from ScriptableObject, then it will work. But why load a class intended for storing information with some kind of business logic?

    When designing, it is better to write classes in such a way that their behavior is predictable and expected. Would you expect, for example, that a book describing the technical characteristics of a ship would control the ship itself or command the crew? But, at the same time, it would be quite expected if such a performance characteristics book could produce any calculations, calculations associated with the parameters stored in it.

    Everyone can have their own point of view on the logic in ScriptableObject. This is a holivar question. But I would advise to separate this logic.