ValueTuples have [Serializable] attributes and Public fields, but they can not be serialized.
Vector3 and some built-in types don’t have [Serializable] attributes, but they can be serialized.
Is there any way to know if a type can be serialized by Inspector from C#?
The Unity docs would be the best place to start your investigation.
I already know them.
ValueTuple is an exception to what they say, and I also want to know how to make certain types fit into Unity built-in types.
Does everything in the UnityEngine namespace apply to inspector serializable?
Why? I think ValueTuple
is exactly what they say: it is not serializable because it doesn’t fulfill the rules they laid out on the link I provided above.
What is the exact exception?
It doesn’t dependent where it is declared, it depends on the rules you can find on the link I provided above.
Especially these, but the rest also apply:
ValueTuple
currently doesn’t fulfill these rules.
Wrap in a Serializable
class using this:
- Use serialization callbacks, by implementing ISerializationCallbackReceiver, to perform custom serialization.
As an example, this is part of the code for ValueTuple<T1, T2>.
[Serializable]
[StructLayout(LayoutKind.Auto)]
public struct ValueTuple<T1, T2> :
IEquatable<(T1, T2)>,
IStructuralEquatable,
IStructuralComparable,
IComparable,
IComparable<(T1, T2)>,
IValueTupleInternal,
ITuple
{
public T1 Item1;
public T2 Item2;
When I copy and paste this code and remove IValueTupleInternal interface, it can be serialized.
If I’m not mistaken Unity cannot serialize a generic type T with no restrictions (aka “where T: System.Object”). This means it could literally be anything.
It might work with [SerializeReference] though.
What part of that code changes what has already been noted above?
Well, of course, custom structs (when fulfill the rules I even pasted for you above) can be serialized. And when you do that, it becomes a custom struct called “ValueTuple
” and it won’t be the C# type ValueTuple
But as @Kurt-Dekker asked above, what’s your point?
I can’t find what rule is not fulfilled.
The TupleTest below has been serialized.
public ValueTuple<int, int> TupleTest;
[Serializable]
[StructLayout(LayoutKind.Auto)]
public struct ValueTuple<T1, T2> {
public T1 Item1;
public T2 Item2;
public ValueTuple(T1 item1, T2 item2) {
this.Item1 = item1;
this.Item2 = item2;
}
}
I copied from mscorlib.dll.
Yeah, that’s only .NetFramework, in .NetStandard (netstandard.dll) it looks like this:
public partial struct ValueTuple<T1, T2> : System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.IComparable, System.IComparable<System.ValueTuple<T1, T2>>, System.IEquatable<System.ValueTuple<T1, T2>>, System.Runtime.CompilerServices.ITuple
{
public T1 Item1;
public T2 Item2;
[...]
}
Unity Serializer probably implements the lowest common denominator here. I’m obviously not sure because I don’t work at Unity.
Ah, I understand, UnityEngine does not seem to look for Serializable types in mscorlib.dll or UnityEngine.dll.