Class FormerlySerializedAsAttribute
Records a previous fully qualified type name for a class or struct so that serialization systems can migrate existing data when a type is renamed or moved to a different namespace.
Inherited Members
Namespace: Scylla.Core.Attributes
Assembly: ScyllaCore.dll
Syntax
[AttributeUsage(AttributeTargets.Class|AttributeTargets.Struct, AllowMultiple = true, Inherited = false)]
public sealed class FormerlySerializedAsAttribute : Attribute
Remarks
When a class or struct is renamed or relocated to a different namespace, any serialized data (JSON config files, save data, ScriptableObject assets, etc.) that referenced the old type name will no longer deserialize correctly. Applying FormerlySerializedAsAttribute tells the Scylla serialization system that the decorated type was previously known under the supplied fully qualified name, allowing it to transparently remap old identifiers to the current type during deserialization.
Because this attribute allows multiple instances on the same type
(AllowMultiple = true), you can record an entire chain of historical
renames. Each entry represents one discrete rename step. The serialization
system can then resolve data serialized under any of those historical names,
regardless of how many renames have occurred over the lifetime of the project.
This attribute is intentionally non-inherited (Inherited = false). A
rename history belongs to the specific type that was renamed, not to its
subclasses, which have their own identity and rename histories.
Important distinction: This attribute operates at the type level
(class/struct names and namespaces). It is not a replacement for
UnityEngine.Serialization.FormerlySerializedAsAttribute, which Unity uses
at the field level to migrate renamed serialized fields within a type.
Both attributes can coexist on the same class when both the type name and field
names have changed.
The FullName value should be the complete namespace-qualified type
name exactly as it appeared in serialized data, for example
"Scylla.OldNamespace.OldTypeName". Supplying only a short name without
the namespace may fail to disambiguate types with identical short names in
different namespaces.
Tracking a single rename - type moved from one namespace to another:
[FormerlySerializedAs("Scylla.OldNamespace.PlayerController")]
public class CharacterController : MonoBehaviour
{
/* ... */
}
Tracking a chain of renames - each entry records one step in the rename history, allowing serialized data from any historical version to be resolved:
[FormerlySerializedAs("Scylla.OldNamespace.Player")]
[FormerlySerializedAs("Scylla.OldNamespace.PlayerController")]
public class CharacterController : MonoBehaviour
{
/* ... */
}
Reading all historical names from a type via reflection:
var history = typeof(CharacterController)
.GetCustomAttributes<FormerlySerializedAsAttribute>();
foreach (var entry in history)
Debug.Log(entry.FullName);
Constructors
FormerlySerializedAsAttribute(string)
Initializes a new FormerlySerializedAsAttribute that records one historical fully qualified type name.
Declaration
public FormerlySerializedAsAttribute(string fullName)
Parameters
| Type | Name | Description |
|---|---|---|
| string | fullName | The former fully qualified type name exactly as it appeared in serialized data,
including the namespace (e.g., |
Exceptions
| Type | Condition |
|---|---|
| ArgumentNullException | Thrown when |
Properties
FullName
Gets the former fully qualified type name (namespace and type name combined) that this attribute instance records.
Declaration
public string FullName { get; }
Property Value
| Type | Description |
|---|---|
| string | A non-null, non-empty string containing the complete namespace-qualified name
under which serialized data may reference this type, for example
|