I was really excited about the new generic serialization update but when I tried it in my case I got an unexpected result.
I have a generic class inheriting from a scriptable object and I also have subclasses that are serialized as concrete types so that I may create .asset files from them.
What I wanted to do was to have a public field of MyGenericSO or something like that and to then get an asset reference field in the inspector. Instead, the inspector showed the direct field of the class type which prevents me from dragging in my asset into the inspector.
Is this by design or will this be resolved in the final release?
public class SerlizationTest : MonoBehaviour
{
public Wrapper<int> wrapper;
public ScriptableWrapper<int> shouldBeScriptableObject;
public ConcreteWrapper isSctriptableObject;
}
[System.Serializable]
public class Wrapper<T>
{
public T value;
}
[System.Serializable]
public class ScriptableWrapper<T> : ScriptableObject
{
public T value;
}
public class ConcreteWrapper : ScriptableWrapper<int>
{
}
The code above produces this result in the inspector which doesnât really make that much sense. The second field should render like the third, not the first so I would call this a bug.
I also get an error in the console:
UnityException: ScriptableObject.ctor is not allowed to be called during serialization, call it from Awake or Start instead. Called from MonoBehaviour âSerlizationTestâ on game object âGameObject (1)â.
See âScript Serializationâ page in the Unity Manual for further details.
UnityEngine.ScriptableObjectâŚctor () (at <0d01204b437e47c1a78b600b597a89f4>:0)
ScriptableWrapper`1[T]âŚctor () (at <247d1935aa774493a25c0b3378dd702d>:0)
Agreed, this looks like a bug to me - shouldBeScriptableObjectshould indeed be rendered as a ScriptableObject field instead of expanded like that. Could you use the Bug Reporter to file that as a bug, and paste the number here?
For those of you still coming across this post, the bug has been fixed as of 2020.1.0a22 which, at the time of writing, isnât publicly available yet but should be soon.
So I just tried Unity 2020.1.0a22 which DOES indeed fix the issue I described above but the functionality isnât quite complete by the looks of it:
public class SerlizationTest : MonoBehaviour
{
public Wrapper<int> wrapper;
public ScriptableWrapper<int> shouldBeScriptableObjectWithInt;
public ScriptableWrapper<string> shouldBeScriptableObjectWithString;
public IntWrapper isSctriptableObjectWithInt;
public StringWrapper isSctriptableObjectWithString;
}
[System.Serializable]
public class Wrapper<T>
{
public T value;
}
[System.Serializable]
public class ScriptableWrapper<T> : ScriptableObject
{
public T value;
}
[CreateAssetMenu (menuName = "int wrapper")]
public class IntWrapper : ScriptableWrapper<int>
{
}
[CreateAssetMenu (menuName = "string wrapper")]
public class StringWrapper : ScriptableWrapper<string>
{
}
Thereâs all my code and this is the result:
Ultimately, this does now produce fields in the inspector that only accept the correct types but I have 2 comments on this:
In the âShould Be Scriptable Objectâ fields, the type specified on the right should say âScriptable Wrapperâ or whatever the type is for that field rather than âScriptable Wrapper`1â on both fields regardless of the type
In the screenshots below I am dragging an instance of a concrete IntWrapper as a serialised asset over the string fields:
The generic fieldâs UI updates as if it would accept the input even though it DOESNâT accept the input which is actually the CORRECT outcome. In other words, functionally it works but the feedback in the UI is wrong. In the second image Iâm dragging an IntWrapper into the StringWrapper field and this UI and outcome is correct. My mouse cursor even becomes a black no entry sign which doesnât happen in the first image.
Is the team already aware of this? Should I submit another bug report / two bug reports?
Ah, thanks! Please submit a new bug report, yes. I think weâll probably prioritise this one a little lower than the previous one, as itâs a UI glitch rather than a core data problem, but it should still get fixed.
@JakHussain seriously, thank you. This will be a huge improvement for my workflow knowing this is implemented/fixed, and thank you as well @superpig for responding and helping out too! Super excited to take advantage of the inspector + generics more now!
Iâm using 2019.3.05f and I have a SO, which itself has a generic SO field with custom type passed in. This field doesnât even show in the inspector, is this part of the same problem?
@MrDizzle26 This feature is only available in Unity 2020.1 which is still in alpha so if you really need to use this feature youâll need to upgrade. Iâd suggest keeping a non upgraded version of your project aside in case the alpha causes some irreversible damage to your project (very unlikely).
So Iâve downloaded Unity 2020.1, and my SO field shows in the inspector, but I am unable to assign a generic SO of a derived type to a field that expects a super. So polymorphism doesnât work for generic references?
public abstract class Effect { }
public class ChildEffect : Effect { }
public abstract class StatEffect : ScriptableObject where T : Effect
{
public T Effect;
}
// This is concrete SO
public class ChildStatEffect : StatEffect { }
public class SomeClass
{
// Unity wonât let me assign ChildStatEffect into this slot in the inspector?
StatEffect StatEffect;
}
Try marking the objects that you pass as T to be serialisable? That would likely play a part in generically serialising it. In my example above Iâm using primitives which are serialisable by default.
@JakHussain Have you submitted a bug report regarding the representation of generic arguments in object picker? If so, could you share a link to IssueTracker? I see the bug isnât fixed yet in 2021, and I failed to find it on IssueTracker. Iâd like to vote on it so that it is fixed sooner.
@EdEddnEddy The issue was âfixedâ in 2021.2 Unity Issue Tracker - Assets are not listed in the Object picker field when ScriptableObject is Generic
Now all assets inherited from BaseScriptableEvent appear in the object selector window. However, if you create a BaseScriptableEvent field, BaseScriptableEvent or assets will also appear in the list, so itâs not really a fix. I requested a further fix to which they replied it is more of a feature request than a bug report. They might consider adding it in the future but donât expect it to be fixed soon