유니티 개발에서는 public / [SerializedField]인 변수들을 인스펙터에 노출시킨 후, 값을 직접 할당하여 사용한다.
이렇게 만들어놓은 변수를 잘 사용하다가, 모종의 이유로 변수명을 바꿔야하는 경우가 있다.
변수의 오타를 발견했거나, 리팩토링으로 다른 변수명을 사용하거나, 컨벤션에 맞추기 위해 바꾼다거나..
이때 단순히 변수명을 바꾸게되면 인스펙터에서 할당한 값이 없어지는 현상을 볼 수가 있다.
프리팹 a가 있고 여기에 스크립트 A.cs가 붙어있다고 해보자.
스크립트 A는 다음과 같이 public Gameobject Target 변수를 가지고 있으며, 인스펙터에서 프리팹 b를 할당해주었다.
using UnityEngine;
public class A : MonoBehaviour
{
public GameObject Target;
}
이때 Target 변수명을 TargetNew로 바꾸면, 아래처럼 할당해놓은 b가 사라진 것을 볼 수가 있다.

그 이유는 프리팹 a를 텍스트 편집기로 열어보면 알 수 있다.
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &8108531127142828263
GameObject:
m_ObjectHideFlags: 0
...
Transform:
m_ObjectHideFlags: 0
...
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8108531127142828263}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 99fb6bfebe831b8428413b6004928140, type: 3}
m_Name:
m_EditorClassIdentifier:
Target: {fileID: 356670576730046704, guid: 6f3141cc99a2e524bacecbeabf1188e2, type: 3}
a.prefab을 열어 [MonoBehaviour] 항목을 확인하면 맨 아래 Target: {fileId: ...}로 작성된 것을 볼 수가 있다.
이는 저장된 프리팹에서 이전의 Target이란 이름의 변수로 저장되어있음을 의미한다.
새로운 변수의 이름은 TargetNew인데 해당하는 항목이 프리팹에 저장되어있지 않아서 할당이 안된 상태로 보인 것이다.
a.prefab의 Target을 TargetNew로 수정 후 저장해보면, 정상적으로 할당된 변수가 돌아왔음을 확인할 수 있다.

그렇다면, 변수 이름을 바꿔도 할당된 변수 값을 유지하고 싶으면 어떻게 해야할까?
바로 "FormerlySerializedAs" 어트리뷰트를 사용하면 값을 유지한채로 변수명을 안전하게 바꿀 수 있다.
FormerlySerializedAs의 원본 클래스를 찾아가면 아래와 같이 되어있다.
//
// Summary:
// Use this attribute to rename a field without losing its serialized value.
[RequiredByNativeCode]
[AttributeUsage(AttributeTargets.Field, AllowMultiple = true, Inherited = false)]
public class FormerlySerializedAsAttribute : Attribute
{
private string m_oldName;
//
// Summary:
// The name of the field before the rename.
public string oldName => m_oldName;
//
// Parameters:
// oldName:
// The name of the field before renaming.
public FormerlySerializedAsAttribute(string oldName)
{
m_oldName = oldName;
}
}
유니티에서 Serialization을 할 때, 'TargetNew'라는 이름의 항목이 안보이면 'Target' 이름으로 찾아가라고 명시해주는 것이다.
a.prefab의 TargetNew를 다시 Target으로 되돌려보자.
그리고 A.cs의 TargetNew 변수 위에다가 다음과 같이 작성해주면 된다.
using UnityEngine;
using UnityEngine.Serialization;
public class A : MonoBehaviour
{
[FormerlySerializedAs("Target")]
public GameObject TargetNew;
}
유니티 프로젝트에서 변수명은 자주 바뀌기 일상이다.
협업을 할 때, 다른 팀원들과 오해를 빚지 않기 위해 이전 내용을 기록하듯이 FormerlySerializedAs을 사용하면 좋을 것이다.
'게임개발 > Unity' 카테고리의 다른 글
| [Unity] Debug.Log 커스터마이징 (0) | 2025.07.12 |
|---|---|
| [Unity] 안쓰는 함수 멋지게 표현하기 (System.Obsolete) (0) | 2025.06.12 |
| [Unity] NetworkVariable, INetworkSerializable Synchronization Problem (0) | 2025.06.05 |
| [Unity] StopCoroutine, 코루틴 중지시키기 (3) | 2025.06.03 |
| [Unity] Button OnClick Event is triggered twice (0) | 2024.08.26 |