Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

ScriptableObject's cannot be placed within namespaces unless in DLLs?

Discussion in 'Editor & General Support' started by numberkruncher, Sep 4, 2013.

  1. numberkruncher

    numberkruncher

    Joined:
    Feb 18, 2012
    Posts:
    953
    This issue still occurs with the latest version of Unity 4.2.1. Whilst I may be mistaken, I was under the impression that Unity 4.0 was suppose to support namespaces within scripts now.

    When this issue does occur, attempting to delete the broken asset file causes Unity to crash to the desktop with some MemoryStream exception.

    Oddly, it is (and has for quite a while now) possible to place ScriptableObject's into custom namespaces if you compile them into DLL's. But for some reason attempting to do this with separate script assets does not work.

    I have reported this using the bug reporter. Here is the case number should anyone be interested:
    Case 561547
     
  2. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Can't be certain on ScriptableObjects, but namespaces still aren't fully supported for some objects. You can't put a Monobehavior in a namespace whether its in a script or a DLL, it just doesn't work. Your best bet is to not use namespaces for ScriptableObjects either.
     
  3. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    @numberkruncher, I have not problem to use ScriptableObject in namespaces. In my Decal System Pro, I have a TextureAtlasAsset which is a ScriptableObject within a namespace. In my development environment, it is obviously not in a dll, while in the final version the class is part of a dll. I had not problems with it.

    @Dustin Horne, lots of my classes are in namespaces, including scripts derived from MonoBehaviour, Editor, ... . This works since Unity 4 and I never had issues with it so far. What is not working for you?
     
  4. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Interesting, I'll have to give it a try again. It's been awhile since I tried it but with 4.0 I was still getting errors when putting a MonoBehavior derivative in a namespace but I may have missed something. My MonoBehavior in that instance was in a compiled assembly.
     
  5. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    It works in dlls too for me.
     
  6. numberkruncher

    numberkruncher

    Joined:
    Feb 18, 2012
    Posts:
    953
    MonoBehaviour classes seem to work fine within namespaces for me (both in and out of DLL's):

    "Scripting: MonoBehaviours can now be inside namespaces."
    - http://unity3d.com/unity/whats-new/unity-4.0

    Okay, I have narrowed the source of the problem down and it is 100% reproducible. This problem is caused when a custom scriptable object class is placed within a namespace which contains a function with a default parameter.

    The following editor script is used in each of the following test cases:
    Code (csharp):
    1.  
    2. // Assets/Editor/Test.cs
    3. using UnityEngine;
    4. using UnityEditor;
    5. using My.Namespace; // Cases 3, 4 and 5
    6.  
    7. public static class Test {
    8.     [MenuItem("Custom/Foo")]
    9.     static void Foo() {
    10.         var ms = ScriptableObject.CreateInstance<MyScriptable>();
    11.         AssetDatabase.CreateAsset(ms, "Assets/test.asset");
    12.     }
    13. }
    14.  
    Case 1: Works Fine - Bare Bones
    Code (csharp):
    1.  
    2. // Assets/Scripts/MyScriptable.cs
    3. using UnityEngine;
    4.  
    5. public class MyScriptable : ScriptableObject {
    6.     public int someNumber;
    7.     public void Foo(int xyz) {
    8.         someNumber = xyz;
    9.     }
    10. }
    11.  
    1. Select menu Custom|Foo.
    2. Select asset in project view and inspect.
    3. All good.
    4. Delete asset.

    Case 2: Works Fine - Namespace
    Code (csharp):
    1.  
    2. // Assets/Scripts/MyScriptable.cs
    3. using UnityEngine;
    4.  
    5. namespace My.Namespace {
    6.     public class MyScriptable : ScriptableObject {
    7.         public int someNumber;
    8.         public void Foo(int xyz) {
    9.             someNumber = xyz;
    10.         }
    11.     }
    12. }
    13.  
    1. Select menu Custom|Foo.
    2. Select asset in project view and inspect.
    3. All good.
    4. Delete asset.

    Case 3: Works Fine - Default Function Param
    Code (csharp):
    1.  
    2. // Assets/Scripts/MyScriptable.cs
    3. using UnityEngine;
    4.  
    5. public class MyScriptable : ScriptableObject {
    6.     public int someNumber;
    7.     public void Foo(int xyz = 123) {
    8.         someNumber = xyz;
    9.     }
    10. }
    11.  
    1. Select menu Custom|Foo.
    2. Select asset in project view and inspect.
    3. All good.
    4. Delete asset.

    Case 4: Fails - Default Function Param + Namespace
    Code (csharp):
    1.  
    2. // Assets/Scripts/MyScriptable.cs
    3. using UnityEngine;
    4.  
    5. namespace My.Namespace {
    6.     public class MyScriptable : ScriptableObject {
    7.         public int someNumber;
    8.         public void Foo(int xyz = 123) {
    9.             someNumber = xyz;
    10.         }
    11.     }
    12. }
    13.  
    1. Select menu Custom|Foo.
    2. Select asset in project view and inspect.
    3. Inspector indicates that script is missing sometimes saying "None (Mono Script)" otherwise oddly "None (Mono Behaviour)".
    4. Delete asset.
    5. CRASH

    Case 5: Works Fine - Same as Case 4 but inside a DLL
     
    axellolledoering likes this.
  7. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    You are right. I was able to reproduce that as well. I never encounter the issue because I don't use default values in my Decal System.
     
    axellolledoering likes this.
  8. AmazingRuss

    AmazingRuss

    Joined:
    May 25, 2008
    Posts:
    933
    Checking in from the future world of 2018! This still happens. I tried to isolate it by moving the offending script into an empty project, but it works fine in the empty project. Other ScriptableObjects in my project work fine, but any new ones I create will not assign a script to the asset. When put the inspector in debug mode and drag the script into the inspector field, I get this in the console:


    MonoBehaviour has unknown format!:
    Base Type:MonoBehaviour ByteSize:-1 MetaFlag:32768 (node index: 0)
    m_ObjectHideFlags Type:unsigned int ByteSize:4 MetaFlag:1 (node index: 1)
    m_InstanceID Type:int ByteSize:4 MetaFlag:0 (node index: 2)
    m_LocalIdentfierInFile Type:SInt64 ByteSize:8 MetaFlag:0 (node index: 3)
    m_PrefabParentObject Type:pPtr<EditorExtension> ByteSize:12 MetaFlag:1 (node index: 4)
    m_FileID Type:int ByteSize:4 MetaFlag:8388609 (node index: 5)
    m_PathID Type:SInt64 ByteSize:8 MetaFlag:8388609 (node index: 6)
    m_PrefabInternal Type:pPtr<Prefab> ByteSize:12 MetaFlag:1 (node index: 7)
    m_FileID Type:int ByteSize:4 MetaFlag:8388609 (node index: 8)
    m_PathID Type:SInt64 ByteSize:8 MetaFlag:8388609 (node index: 9)
    m_GameObject Type:pPtr<GameObject> ByteSize:12 MetaFlag:65 (node index: 10)
    m_FileID Type:int ByteSize:4 MetaFlag:65 (node index: 11)
    m_PathID Type:SInt64 ByteSize:8 MetaFlag:65 (node index: 12)
    m_Enabled Type:UInt8 ByteSize:1 MetaFlag:16641 (node index: 13)
    m_EditorHideFlags Type:unsigned int ByteSize:4 MetaFlag:1 (node index: 14)
    m_Script Type:pPtr<MonoScript> ByteSize:12 MetaFlag:0 (node index: 15)
    m_FileID Type:int ByteSize:4 MetaFlag:8388609 (node index: 16)
    m_PathID Type:SInt64 ByteSize:8 MetaFlag:8388609 (node index: 17)
    m_Name Type:string ByteSize:-1 MetaFlag:32769 (node index: 18)
    Array Type:Array ByteSize:-1 MetaFlag:16385 IsArray (node index: 19)
    size Type:int ByteSize:4 MetaFlag:1 (node index: 20)
    data Type:char ByteSize:1 MetaFlag:1 (node index: 21)
    m_EditorClassIdentifier Type:string ByteSize:-1 MetaFlag:8421377 (node index: 22)
    Array Type:Array ByteSize:-1 MetaFlag:8404993 IsArray (node index: 23)
    size Type:int ByteSize:4 MetaFlag:8388609 (node index: 24)
    data Type:char ByteSize:1 MetaFlag:8388609 (node index: 25)
     
  9. AmazingRuss

    AmazingRuss

    Joined:
    May 25, 2008
    Posts:
    933
    .. and the offending Scriptable object is
    Code (CSharp):
    1. namespace Blah
    2. {
    3.     [CreateAssetMenuAttribute]
    4.     public class SpawnResult : ScriptableObject
    5.     {
    6.     }
    7. }

    I would submit it as a bug, but I can't report outside the project, and I can't upload the project.
     
  10. Shrubokrant

    Shrubokrant

    Joined:
    Oct 2, 2016
    Posts:
    80
    Just bumped into this issue: for me, trying to create a scriptable object and save it as an asset when it is defined in a dll does not work.
    The instance is properly created, but whenever I reload the editor, the data inside the asset is lost.

    Does anyone know if it's the expected behavior?
     
  11. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,431
    How are you modifying the values of the asset? do you have a custom inspector for it? if so, are you using SerializedProperty to modify it or target? This sounds like the asset might not be marked as dirty after modifying the values.
     
  12. jasonm_unity3d

    jasonm_unity3d

    Unity Technologies

    Joined:
    Mar 2, 2017
    Posts:
    41
    Which, exact, version of unity are you seeing this behavior in?
    A late fix was introduced in 2018.2, that is present in the final release, that addresses a just such a scenario.
     
  13. Shrubokrant

    Shrubokrant

    Joined:
    Oct 2, 2016
    Posts:
    80
    I am setting the asset dirty, but the script is not recognized: I am creating the asset in an [InitializeOnLoadMethod] method, no custom inspector, just a data holder. The asset is properly created the first time, but after reloading the engine it is not recognized anymore.

    Since it is for an asset store plugin, I unfortunately cannot rely only on version 2018.2: I found a workaround now, but I will check it on the last version as well!
     
  14. amisner2k

    amisner2k

    Joined:
    Jan 9, 2017
    Posts:
    43
    I'm running Unity 2018.2.2f1 and I recently did a Reimport All. After doing so, two asset store assets I was using (Maintainer and QHierarchy) started acting up. Maintainer kept logging in the console that it couldn't load its settings file and QHierarchy threw repeating errors in the console.

    After looking at their code I noticed they were using ScriptableObjects to store their settings. QHierarchy's ScriptableObject definition was defined within a namespace and I was able to repeat the same issues as described by others in this thread. After moving the ScriptableObject definition outside of the namespace, the errors went away and the .asset file in the project view was able to find its definition script file.
     
    Ladace likes this.
  15. SugoiDev

    SugoiDev

    Joined:
    Mar 27, 2013
    Posts:
    395
    Got similar results to @amisner2k the breakage in QHierarchy is very noticeable.
    My own ScriptableObjects break too. Not only that, when the bug triggers, almost all MonoBehaviours also stop being recognized. Some still continue working for some reason (all in namespaces). I could not find a way to revert it to a working state either. Reimporting did not help. You have delete the library folder and rollback to a working version.

    Then there's this: With the pretty much the same setup, everything works fine in one computer but not in another. Same OS and similar hardware, same Unity version, fresh project from source control, etc.
    I manually copied the Library folder from the working machine to the broken one and it started working.
    Since the issue seems very non-deterministic, I can't produce a stable reproduction case.

    I'm assuming this is caused by the changes in the parser related to this: Scripting: Fixed "using static" directive causing Unity to not find the class in the script (962043, 962275)(release notes: https://unity3d.com/unity/whatsnew/unity-2018.2.2)

    The mentioned issue isn't fixed, it is still present (at least with 2018.2.2 and 2018.2.3 on Windows). I just submitted a bug report (#1069915) about the static imports issue. Maybe fixing that will help with these weird issues we're seeing on this thread.