jacobdufault / fullinspector

Full Inspector supercharges Unity's inspector
MIT License
111 stars 27 forks source link

Deserialization error on type collection derived from BaseScriptableObject #156

Open lazlo-bonin opened 8 years ago

lazlo-bonin commented 8 years ago

I have a scriptable object type using the following inheritance hierarchy:

Propagation : EphemeresScriptableObject : BaseSriptableObject

I reference it as a property of a scene behaviour that uses the following inheritance hierarchy:

Repository : EphemeresBehaviour : BaseBehavior

The property is a Propagation[] (array). The same problem occurs if it's a List<Propagation>.

Upon deserialization, I get the following error and cannot assign elements in the list (selecting a Propagation object does not assign it to the object field, which stays at "None").

[Error] Exception caught when deserializing property <propagations> with type <Ephemeres.Repository>
System.InvalidCastException: Cannot cast from source type to destination type.
0. Array.Copy()
1. Array.Copy()
2. ArrayList.CopyTo()
3. ArrayList.ToArray()
4. FullSerializer.Internal.fsArrayConverter.TryDeserialize()
5. FullSerializer.fsSerializer.InternalDeserialize_5_Converter()
6. FullSerializer.fsSerializer.InternalDeserialize_4_Cycles()
7. FullSerializer.fsSerializer.InternalDeserialize_3_Inheritance()
8. FullSerializer.fsSerializer.InternalDeserialize_2_Version()
9. FullSerializer.fsSerializer.InternalDeserialize_1_CycleReference()
10. FullSerializer.fsSerializer.TryDeserialize()
11. FullSerializer.fsSerializer.TryDeserialize()
12. FullInspector.FullSerializerSerializer.Deserialize()
13. FullInspector.Internal.fiISerializedObjectUtility.RestoreState[FullSerializerSerializer]()
14. FullInspector.Internal.fiISerializedObjectUtility.RestoreState() at Assets/Plugins/FullInspector2/Core/fiISerializedObjectUtility.cs:229
15. FullInspector.BaseBehavior`1.RestoreState() at Assets/Plugins/FullInspector2/Core/BaseBehavior.cs:65
16. FullInspector.Internal.fiSerializationManager.DoDeserialize() at Assets/Plugins/FullInspector2/Core/fiSerializationManager.cs:210
17. FullInspector.Internal.fiSerializationManager.OnUnityObjectDeserialize() at Assets/Plugins/FullInspector2/Core/fiSerializationManager.cs:117
18. FullInspector.BaseBehavior`1.UnityEngine.ISerializationCallbackReceiver.OnAfterDeserialize() at Assets/Plugins/FullInspector2/Core/BaseBehavior.cs:132

Here is the full code for Repository:

using Ephemeres.Audio;
using Ephemeres.Motel;
using Ephemeres.Photography;
using UnityEngine;
using Utility;

namespace Ephemeres
{
    [Singleton(Automatic = false, Persistent = false)]
    public class Repository : EphemeresBehaviour, ISingleton
    {
        public static Repository instance => Singleton<Repository>.instance;
        public static bool instantiated => Singleton<Repository>.instantiated;

        public Mesh cubeMesh { get; private set; }

        public Photo photo { get; private set; }
        public AudioSourcePoolable audioSource { get; private set; }
        public VisibilityCubeDecal timedCube { get; private set; }
        public VisibilityCuboidDecal timedCuboid { get; private set; }
        public FootstepBank footsteps { get; private set; }
        public Propagation[] propagations { get; private set; }

        public Repository()
        {

        }
    }
}

Here is the full code for Propagation:

using UnityEngine;
using FullInspector;

namespace Ephemeres.Motel
{
    [CreateAssetMenu]
    public class Propagation : EphemeresScriptableObject
    {
        public MovieTexture source { get; set; }

        public int startFrame { get; set; } = 0;

        public int endFrame { get; set; } = 100;

        public Channel visibilityChannel { get; set; } = Channel.RGB;

        public Chroma visibilityChroma { get; set; } = Chroma.Black;

        public bool enforcePurity { get; set; }

        [InspectorRange(2, 14)]
        public int sampleCount { get; set; } = 14;

        public Texture2D[] maps { get; set; } = new Texture2D[0];

        [InspectorRange(0, 2)]
        public float intensity { get; set; } = 1;

        [InspectorRange(0, 1)]
        public float edgelessVisibility { get; set; } = 1;
    }
}

(Using C# 6.0 for Unity, which explains the property initializers).

jacobdufault commented 8 years ago

I'm having trouble reproducing when I convert the code so I can compile it. This is what I tested with:

using FullInspector;
using UnityEngine;

[CreateAssetMenu]
public class Propagation : BaseScriptableObject {
    public MovieTexture source { get; set; }

    public int startFrame = 0;

    public int endFrame = 100;

    //public Channel visibilityChannel { get; set; } = Channel.RGB;

    //public Chroma visibilityChroma { get; set; } = Chroma.Black;

    public bool enforcePurity { get; set; }

    [InspectorRange(2, 14)]
    public int sampleCount = 14;

    public Texture2D[] maps = new Texture2D[0];

    [InspectorRange(0, 2)]
    public float intensity = 1;

    [InspectorRange(0, 1)]
    public float edgelessVisibility = 1;
}
using FullInspector;
using UnityEngine;

public class Repository : BaseBehavior {
    //public static Repository instance => Singleton<Repository>.instance;
    //public static bool instantiated => Singleton<Repository>.instantiated;

    public Mesh cubeMesh { get; private set; }

    public int a;

    //public Photo photo { get; private set; }
    //public AudioSourcePoolable audioSource { get; private set; }
    //public VisibilityCubeDecal timedCube { get; private set; }
    //public VisibilityCuboidDecal timedCuboid { get; private set; }
    //public FootstepBank footsteps { get; private set; }
    public Propagation[] propagations;

    public Repository() {

    }
}

Would you mind verifying this still reproduces with this code, or send up updated code that demonstrates the issue?

Thanks!