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

Feature Request [Sequences] implicit string operator

Discussion in 'Timeline' started by CaseyHofland, May 17, 2023.

  1. CaseyHofland

    CaseyHofland

    Joined:
    Mar 18, 2016
    Posts:
    528
    Hi there, I've been using SceneReference in my own code for ease of use.

    We build today and it turns out the implicit string operator is wrapped inside an
    #if UNITY_EDITOR
    directive. This seems weird since it just returns the
    SceneReference.path
    , which is accessible.

    Thought I'd point it out!
     
  2. ellka

    ellka

    Unity Technologies

    Joined:
    Jun 17, 2019
    Posts:
    70
    Hey Casey!

    It is wrapped up in UNITY_EDITOR because the path is gotten from the SerializeField m_SceneAsset that is editor only. If I remember correctly it's because Unity can't directly serialize Scene objects.

    But maybe I'm misunderstanding something from your comment. If you can put the code reference, I could take a look! I'm curious now :D!
     
  3. CaseyHofland

    CaseyHofland

    Joined:
    Mar 18, 2016
    Posts:
    528
    This is the SceneReference script from Sequences:
    Code (CSharp):
    1. #if UNITY_EDITOR
    2. using UnityEditor;
    3. using UnityEditor.SceneManagement;
    4. #endif
    5.  
    6. namespace UnityEngine.Sequences
    7. {
    8.     /// <summary>
    9.     /// Scene wrapper to allow proper serialization of SceneAsset references.
    10.     /// SceneAsset only exist in Editor so the path is stored as well any time the object is serialized.
    11.     /// The Scene path is used at runtime, assuming the Scene has been added to the Build Settings.
    12.     /// </summary>
    13.     // Inspired from: https://github.com/starikcetin/unity-scene-reference
    14.     [System.Serializable]
    15.     public class SceneReference : ISerializationCallbackReceiver
    16.     {
    17. #if UNITY_EDITOR
    18.         [SerializeField] Object m_SceneAsset;
    19.  
    20.         bool isValidSceneAsset
    21.         {
    22.             get
    23.             {
    24.                 if (!m_SceneAsset) return false;
    25.  
    26.                 return m_SceneAsset is SceneAsset;
    27.             }
    28.         }
    29. #endif
    30.  
    31.         [SerializeField][HideInInspector] string m_ScenePath;
    32.  
    33.         /// <summary>
    34.         /// Path to the Scene asset, relative to the project folder.
    35.         /// </summary>
    36.         public string path
    37.         {
    38.             get
    39.             {
    40. #if UNITY_EDITOR
    41.                 return GetScenePathFromAsset();
    42. #else
    43.                 return m_ScenePath;
    44. #endif
    45.             }
    46.             set
    47.             {
    48.                 m_ScenePath = value;
    49. #if UNITY_EDITOR
    50.                 m_SceneAsset = GetSceneAssetFromPath();
    51. #endif
    52.             }
    53.         }
    54.  
    55. #if UNITY_EDITOR
    56.         Object GetSceneAssetFromPath()
    57.         {
    58.             return string.IsNullOrEmpty(m_ScenePath) ? null : AssetDatabase.LoadAssetAtPath<SceneAsset>(m_ScenePath);
    59.         }
    60.  
    61.         string GetScenePathFromAsset()
    62.         {
    63.             return m_SceneAsset == null ? string.Empty : AssetDatabase.GetAssetPath(m_SceneAsset);
    64.         }
    65.  
    66.         public static implicit operator string(SceneReference sceneReference)
    67.         {
    68.             return sceneReference.path;
    69.         }
    70.  
    71.         void BeforeSerialize()
    72.         {
    73.             // Asset is invalid but have a path try to get the Scene
    74.             if (isValidSceneAsset == false && string.IsNullOrEmpty(m_ScenePath) == false)
    75.             {
    76.                 m_SceneAsset = GetSceneAssetFromPath();
    77.                 if (m_SceneAsset == null) m_ScenePath = string.Empty;
    78.  
    79.                 EditorSceneManager.MarkAllScenesDirty();
    80.             }
    81.             // Asset takes precedence and overwrites path
    82.             else
    83.             {
    84.                 m_ScenePath = GetScenePathFromAsset();
    85.             }
    86.         }
    87.  
    88.         void AfterDeserialize()
    89.         {
    90.             EditorApplication.update -= AfterDeserialize;
    91.             BeforeSerialize();
    92.         }
    93.  
    94. #endif
    95.         /// <summary>
    96.         /// Receives callback event from <see cref="ISerializationCallbackReceiver"/>.
    97.         /// </summary>
    98.         public void OnBeforeSerialize()
    99.         {
    100. #if UNITY_EDITOR
    101.             BeforeSerialize();
    102. #endif
    103.         }
    104.  
    105.         /// <summary>
    106.         /// Receives callback event from <see cref="ISerializationCallbackReceiver"/>.
    107.         /// </summary>
    108.         public void OnAfterDeserialize()
    109.         {
    110. #if UNITY_EDITOR
    111.             // The AssetDatabase can't be accessed during serialization, delay the call.
    112.             EditorApplication.update += AfterDeserialize;
    113. #endif
    114.         }
    115.     }
    116. }
    117.  
    The implicit string operator here returns
    sceneReference.path
    .

    You'll notice that
    sceneReference.path
    is not wrapped inside an
    #if UNITY_EDITOR
    directive, whilst the implicit string operator is.

    Since
    sceneReference.path
    returns a serialized path reference at runtime, this should not be an issue. Especially since you can't change the private variables anyway.



    So it was really strange to me why the implicit operator would not be included at runtime: seems like an oversight :D
     
  4. ellka

    ellka

    Unity Technologies

    Joined:
    Jun 17, 2019
    Posts:
    70
    Ah! Ok, I was looking at the right code, but not at the right line.
    Yeah... indeed, it seems it could be outside the UNITY_EDITOR scope!
    Thanks for the heads up!