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 Pass SerializeField class to composed class by Editor OnValidate

Discussion in 'Scripting' started by Atsutake, Aug 30, 2023.

  1. Atsutake

    Atsutake

    Joined:
    Mar 8, 2023
    Posts:
    18
    Greets community,

    I wanted to pass a class/struct (i.e. agentLocomotion) of Mob to a class/struct that is composed by Mob (chaseLocomotion) by OnValidate of Editor, so that agentLocomotion of Mob is directly accessible in ChaseLocomotion. Same goes for NavMeshAgent,Transform (even MonoBehaviours) of Mob...

    The classes:

    Code (CSharp):
    1. public class Mob : MonoBehaviour
    2. {
    3.     [SerializeField] protected AgentLocomotion _agentLocomotion;
    4.     public AgentLocomotion agentLocomotion => _agentLocomotion;
    5.  
    6.     [SerializeField] protected ChaseLocomotion _chaseLocomotion;
    7.     public ChaseLocomotion chaseLocomotion => _chaseLocomotion;
    8.  
    9.     ...
    10.  
    11. #if UNITY_EDITOR
    12.     public override void Validate()
    13.     {
    14.         _chaseLocomotion.Validate(this);
    15.     }
    16. #endif
    17.  
    18.     ...
    19. }
    20.  
    21. public class ChaseLocomotion
    22. {
    23.     [SerializeField, HideInInspector] Transform transform;
    24.     [SerializeField, HideInInspector] Mob entity;
    25.     [SerializeField, HideInInspector] NavMeshAgent agent;
    26.     [SerializeField, HideInInspector] AgentLocomotion agentLocomotion;
    27.  
    28.     public ChaseLocomotion(Mob newEntity = null, NavMeshAgent newAgent = null, AgentLocomotion newAgentLocomotion = null, Transform newTransform = null)
    29.     { // ONLY if struct
    30.         entity = newEntity;
    31.         agent = newAgent;
    32.         agentLocomotion = newAgentLocomotion;
    33.         transform = newTransform;
    34.     }
    35.  
    36. #if UNITY_EDITOR
    37.     public void Validate(Mob newEntity)
    38.     {
    39.         entity = newEntity;
    40.         transform = entity.transform;
    41.         agent = entity.Agent;
    42.         agentLocomotion = entity.agentLocomotion;
    43.     }
    44. #endif
    45. }
    46.  
    47. public class AgentLocomotion { ... }
    I am not sure if this can be passed by constructor or like I did by an additional function.
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    Unity's serialisation is by default 'by values', so once this asset gets reserialised,
    agentLocomotion
    will be a completely new instance. You can get around this by serialising it with
    [SerializeReference]
    (both in the monobehaviour and in the class) and they will point to the same instance.

    Though for this kind of stuff, I just tend to inject these references in Awake.
     
    Atsutake likes this.
  3. Atsutake

    Atsutake

    Joined:
    Mar 8, 2023
    Posts:
    18
    I see, but this won't work for structs because they are value type and not reference?

    How would this impact game loading time SerializeReference vs. Awake?
     
  4. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    No, structs get passed by value so it will always be a copy.

    Not really answerable. You have to measure this.

    Nonetheless SerializeReference only affects loading/deserialisation by a tiny amount. Awake also incurs overhead during scene loading.

    I can only see either being an issue if you had hundreds, if not thousands of enemies.

    If we're talking only a few dozen, I doubt it will be an issue.

    In any case, don't speculate, measure. Use the profiler.
     
    Last edited: Aug 31, 2023
    Atsutake likes this.
  5. Atsutake

    Atsutake

    Joined:
    Mar 8, 2023
    Posts:
    18
    Thank you, I got it.