1 minute read

개요


SerializeField는 Unity에서 비공개(private) 필드를 인스펙터(Inspector)에 노출하고 싶을 때 사용하는 속성(Attribute)입니다.
Unity의 직렬화 시스템을 통해 필드 값을 유지(persist) 하고, 에디터에서 편집 가능하도록 설정합니다.

장단점


장점

  • 캡슐화 유지: private 접근 제어자를 유지하면서도 인스펙터에 노출할 수 있어, 데이터의 무분별한 접근을 막습니다.
  • Unity 친화적: Unity의 직렬화 시스템을 통해 장면 저장, Prefab 저장, 빌드 시 데이터 유지가 가능합니다.
  • 직관적 편집: 인스펙터를 통해 값을 쉽게 설정하거나 수정할 수 있어, 프로그래머가 아닌 사용자도 데이터를 조작할 수 있습니다.

단점

  • 런타임 전용 데이터 관리: 인스펙터에서 보이지만, 실제로 런타임에서만 필요한 데이터는 불필요하게 노출될 수 있습니다.
  • 오용 가능성: SerializeField를 너무 남용하면 인스펙터가 복잡해지고, 캡슐화의 목적이 퇴색될 수 있습니다.



주의 사항


  • Unity 직렬화 시스템의 한계
    • Unity는 클래스 중 System.Serializable로 선언된 클래스만 직렬화합니다.
    • Dictionary, HashSet과 같은 컬렉션 타입은 기본적으로 Unity에서 직렬화되지 않습니다.
    • private static 또는 const 필드는 직렬화되지 않습니다.
  • 필드 타입
    • Unity는 직렬화 가능한 타입만 지원합니다. (ex. int, float, string, Vector3, GameObject, 사용자 정의 클래스 등)
  • 복잡한 데이터 구조
    • Unity는 중첩된 클래스 구조 또는 참조형 데이터에서 순환 참조(Circular Reference)를 제대로 직렬화하지 못할 수 있습니다.



사용 예시


[사용 예시]

using UnityEngine;
using System;

[Serializable] // 사용자 정의 클래스도 직렬화 가능하도록 설정
public class Weapon
{
    public string name;
    public int damage;
    public float range;
}

public class SerializeFieldExample : MonoBehaviour
{
    // 1. SerializeField를 사용한 private 필드
    [SerializeField] private int playerHealth = 100;
    [SerializeField] private float speed = 5.0f;
    [SerializeField] private string playerName = "Hero";

    // 2. 직렬화 가능한 사용자 정의 클래스
    [SerializeField] private Weapon equippedWeapon;

    // 3. 배열 직렬화
    [SerializeField] private Weapon[] weaponInventory;

    // 4. List 직렬화
    [SerializeField] private System.Collections.Generic.List<Weapon> weaponList;

    // 5. 직렬화 불가능한 Dictionary 예제
    private System.Collections.Generic.Dictionary<string, int> weaponMap; // 직렬화되지 않음

    private void Start()
    {
        // 직렬화된 데이터를 사용
        Debug.Log($"Player: {playerName}, Health: {playerHealth}");
        Debug.Log($"Equipped Weapon: {equippedWeapon.name} (Damage: {equippedWeapon.damage})");
        
        // 런타임에서 weaponMap 초기화
        weaponMap = new System.Collections.Generic.Dictionary<string, int>
        {
            { "Sword", 10 },
            { "Bow", 7 }
        };

        Debug.Log("Weapon Map Initialized at Runtime.");
    }
}

SerializeField를 사용할 때의 팁


  • 유효성 검사: 값이 잘못 설정되지 않도록 제한을 추가하세요. 예를 들어, Range 속성으로 값 범위를 제한할 수 있습니다:
[SerializeField, Range(0, 100)]
private int playerHealth;
  • 구조화된 데이터 관리: 사용자 정의 클래스를 사용하면 복잡한 데이터를 그룹화하고 직렬화하기 쉽습니다.
  • 적절한 노출: 정말 필요한 필드만 인스펙터에 노출하고, 지나치게 많은 SerializeField를 피하는게 좋습니다.


Top