Search Unity

Serialize fields only in Editor

Discussion in 'Scripting' started by zee_ola05, Sep 27, 2016.

  1. zee_ola05

    zee_ola05

    Joined:
    Feb 2, 2014
    Posts:
    166
    Is there a way to serialize fields but only in Editor? In the example below. I have a prefab that is in Resources folder. I have a tool to parent it on a transform. I don't want PlacementTool to hold reference to the prefab when the game is built, I only want it in the Editor.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using FullInspector;
    4.  
    5. public class PlacementTool : BaseBehavior
    6. {
    7.     [SerializeField]
    8.     private GameObject m_prefab;
    9.  
    10.     [InspectorName ("Place")]
    11.     [InspectorButton]
    12.     private void PlacePrefab()
    13.     {
    14.         // Place prefab under this transform
    15.     }
    16.  
    17.     [InspectorName ("Delete")]
    18.     [InspectorButton]
    19.     private void PlaceInstance()
    20.     {
    21.         // Destroy prefab instance
    22.     }
    23. }
    24.  
     
  2. zee_ola05

    zee_ola05

    Joined:
    Feb 2, 2014
    Posts:
    166
    Answering my own question. Looks like putting the fields inside #if UNITY_EDITOR does it.
     
    Alverik likes this.
  3. Xaon

    Xaon

    Joined:
    Feb 28, 2013
    Posts:
    62
    I'm digging this up for the sake on future googlers. DO NOT PUT any serialized fields under #if UNITY_EDITOR! It will screw you're builds. And it's so nasty that the serialization bug can pop randomly months after the code is written.

    (any serialized means: public, public with HideInInspector attribute and private/protected with SerializeFields attribute)
     
    Bunny83 likes this.
  4. forestrf

    forestrf

    Joined:
    Aug 28, 2010
    Posts:
    230
    Could you elaborate on this? Do you know of an alternative or workaround for serializing variables only for the editor?
     
  5. forestrf

    forestrf

    Joined:
    Aug 28, 2010
    Posts:
    230
    Ok, this was fun. Searching for this problem again after some time I found my own answer asking about it. Nice.

    I found that not only #if UNITY_EDITOR doesn't work, if that encloses an array, the game can crash on startup and report the asset with the serialized data as corrupt
     
  6. Xaon

    Xaon

    Joined:
    Feb 28, 2013
    Posts:
    62
    Sorry I haven't replied back then. Dunno how I forgot.
    If I guess correctly data for each component is serialized to flat byte stream. Unity reads all public/serialized fields as a description of what those bytes should mean. But when you put code under conditional compilation the description of fields becames invisible for Unity editor. Though probably there's more to the story.

    In order to have editor only data it has to be put in separate file or at least component. Then you can remove component from scenes/prefabs at runtime. You can also try removing those components during build but you'll have to revert changes on your repo each time after build or you'll need second repo just for that.
     
  7. HarryCodder

    HarryCodder

    Joined:
    Feb 20, 2015
    Posts:
    84
  8. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,992
    Good spot. Yeah they may have fixed the build pipeline to specifically look out for editor only fields and re-serialize all assets when building the game. Though I haven't tested it yet myself.

    I'm actually confused what they actually mean by this line:
    This doesn't seem to make much sense to me. "UNITY_STANDALONE" is a platform define symbol which is also set in the editor if the current target is standalone. Of course you would run into issues when you switch platforms as this would again screw up the serialized data. Maybe they meant that case?

    Anyways, this was a good necro post. Correcting outdated information is a good thing. Though certain outdated topics should be simply ignored (like UnityScript related questions for example).
     
  9. HarryCodder

    HarryCodder

    Joined:
    Feb 20, 2015
    Posts:
    84
    I was wondering the same thing, it would be nice if a Unity dev can give some insights about that.

    I'm note sure if something like this would work (to have some kind of forward compatibility) :
    Code (CSharp):
    1. #if UNITY_EDITOR || !UNITY_2021_2_OR_NEWER
    2. public int m_inEditorOnlyIfSupported;
    3. #endif
     
    Ali_V_Quest likes this.
  10. Ali_V_Quest

    Ali_V_Quest

    Joined:
    Aug 2, 2015
    Posts:
    138
    any official answer if this works in Unity 2020 or if it might cause crashes on some platforms ?


    Code (CSharp):
    1. #if UNITY_EDITOR
    2. public int m_inEditorOnly;
    3. #endif
     
  11. RadRedPanda

    RadRedPanda

    Joined:
    May 9, 2018
    Posts:
    1,647
    I mean, the code you showed has nothing to do with the problem in the thread. It'll behave as expected.
     
  12. Ali_V_Quest

    Ali_V_Quest

    Joined:
    Aug 2, 2015
    Posts:
    138
    replies to this thread stated that putting serialized fields in #if UNITY_EDITOR can create crashes in older versions of Unity
     
  13. RadRedPanda

    RadRedPanda

    Joined:
    May 9, 2018
    Posts:
    1,647
    They're talking about a field which is serialized in the editor, not serialized in the build, and still exists in the build. Pretty sure they mean something like this.

    Code (CSharp):
    1. #if UNITY_EDITOR
    2. [SerializeField]
    3. #endif
    4. private int _fieldSerializedOnlyInEditor;
    If you have the code you suggested, it won't show up in the build at all. If you're referencing
    m_inEditorOnly
    anywhere else in your code that's not tagged out, then the build will fail.
     
  14. RadRedPanda

    RadRedPanda

    Joined:
    May 9, 2018
    Posts:
    1,647
    Upon further reading, I think I miss-understood what the thread was about. My bad. You can pretty much ignore what I said. Unfortunately, I don't know the answer to your question.
     
    Ali_V_Quest likes this.