업무_메모

[Unity] 프로퍼티는 왜 직렬화되지 않을까?

shine94 2025. 5. 5. 06:04

유니티에서 프로퍼티는 직렬화가 되지 않았다

그 이유를 찾기 위해 자료를 찾는 과정에서 C#과 유니티는 직렬화 대상 규칙이 다르다는 사실을 알게 되었다

 

C#의 표준 직렬화 시스템에서는 프로퍼티도 직렬화된다
그러나 유니티에서 제공하는 직렬화 시스템을 사용하며, 프로퍼티의 직렬화를 제공하지 않는다

 

 

🤔 왜 다를까?

먼저 .NET의 내부 구현을 확인해봤다

PopulateProperties 함수를 통해 public 프로퍼티들이 직렬화 대상으로 포함되었다는 사실을 알 수 있었다

 

https://github.com/dotnet/runtime/blob/main/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs#L46

 

runtime/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs at mai

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps. - dotnet/runtime

github.com

[RequiresUnreferencedCode(JsonSerializer.SerializationUnreferencedCodeMessage)]
[RequiresDynamicCode(JsonSerializer.SerializationRequiresDynamicCodeMessage)]
private static JsonTypeInfo CreateTypeInfoCore(Type type, JsonConverter converter, JsonSerializerOptions options)
{
    JsonTypeInfo typeInfo = JsonTypeInfo.CreateJsonTypeInfo(type, converter, options);

    if (GetNumberHandlingForType(typeInfo.Type) is { } numberHandling)
    {
        typeInfo.NumberHandling = numberHandling;
    }

    if (GetObjectCreationHandlingForType(typeInfo.Type) is { } creationHandling)
    {
        typeInfo.PreferredPropertyObjectCreationHandling = creationHandling;
    }

    if (GetUnmappedMemberHandling(typeInfo.Type) is { } unmappedMemberHandling)
    {
        typeInfo.UnmappedMemberHandling = unmappedMemberHandling;
    }

    typeInfo.PopulatePolymorphismMetadata();
    typeInfo.MapInterfaceTypesToCallbacks();

    Func<object>? createObject = DetermineCreateObjectDelegate(type, converter);
    typeInfo.SetCreateObjectIfCompatible(createObject);
    typeInfo.CreateObjectForExtensionDataProperty = createObject;

    if (typeInfo is { Kind: JsonTypeInfoKind.Object, IsNullable: false })
    {
        NullabilityInfoContext nullabilityCtx = new();

        if (converter.ConstructorIsParameterized)
        {
            // NB parameter metadata must be populated *before* property metadata
            // so that properties can be linked to their associated parameters.
            PopulateParameterInfoValues(typeInfo, nullabilityCtx);
        }

        PopulateProperties(typeInfo, nullabilityCtx);

        typeInfo.ConstructorAttributeProvider = typeInfo.Converter.ConstructorInfo;
    }

    // Plug in any converter configuration -- should be run last.
    converter.ConfigureJsonTypeInfo(typeInfo, options);
    converter.ConfigureJsonTypeInfoUsingReflection(typeInfo, options);
    return typeInfo;
}

 

그럼 유니티는 어떨까?

마지막에 FromJsonInternal 함수 호출했는데,

이 함수는 유니티 C++ 내부에 구현되어 있어 코드를 직접 확인할 수 없었다

 

그러나 유니티 공식 문서에 직렬화 규칙이 명시되어 있었고,

이를 근거로 보면 유니티의 JSON 직렬화 시스템은 프로퍼티를 직렬화 대상에서 제외한다는 것을 확인할 수 있다

 

https://docs.unity3d.com/kr/2023.2/Manual/script-Serialization.html

 

스크립트 직렬화 - Unity 매뉴얼

직렬화는 데이터 구조 또는 게임 오브젝트 상태를 Unity가 보관하고 나중에 다시 복구할 수 있는 포맷으로 변환하는 자동 프로세스입니다.

docs.unity3d.com

https://docs.unity3d.com/6000.0/Documentation/Manual/script-serialization-rules.html

 

Unity - Manual: Serialization rules

Serialization rules Serializers in Unity are specifically designed to operate efficiently at runtime. Because of this, serialization in Unity behaves differently to serialization in other programming environments. Serializers in Unity work directly on the

docs.unity3d.com

 

 

📌 정리하면......

이러한 차이는 실행 환경이 다양함에 오는 차이이다
▼ 자세한 내용은 아래의 블로그 확인 GO
https://shine94.tistory.com/417

 

[ETC] 자바는 JVM 생략 OK, C#은 왜 .NET까지 묶일까?

☕ 자바는 "JVM 포함"이 당연한 생태계   자바는 애초에 "Write Once, Run Anywhere"를 목표로 만들어진 언어다   즉, 어디서든 돌아가려면 당연히 JVM이라는 실행 환경이 전제가 되어야 했다    그래

shine94.tistory.com

 

유니티에서는 프로퍼티 기반 멤버는 직렬화되지 않으며, 필드만 직렬화된다는 점을 잘 기억해야 할 것 같다