250613

lililllilillll·2025년 6월 13일

개발 일지

목록 보기
201/350

✅ What I did today


  • R&D : TextTree Editor : Day 12
  • Art Practice : Drawing


📝 Things I Learned


🏷️ Unity : Custom class 직렬화

인라인 직렬화: 기본적으로 Unity는 클래스를 참조하는 필드에 [SerializeReference]를 지정하지 않으면 값을 사용하여 커스텀 클래스 인라인을 직렬화합니다.
[SerializeReference] 직렬화: [SerializeReference]를 지정하면 Unity는 관리되는 레퍼런스로 오브젝트를 구축합니다. (Inspector 편집은 어려워진다고 gpt가 말함)

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



🛠️ R&D : TextTree Editor : Day 12


한 것

value가 field의 type으로 casting이 안되면 경고 문구 띄우기

SerializedProperty 담은 property field는 ValueChangedCallback이 안 먹힌다.
RegisterCallback<SerializedPropertyChangeEvent>로 해야됨.

유니티 이벤트를 inspector에서 할당하게 하고 싶은데, 문제는 이 정보를 json으로 저장 못 함.
억지로 하려면 ScriptableObject를 매개체로 사용해야할텐데,
이런 식으로 관리 복잡성을 늘릴 바에 차라리 통째로 json 말고 so로 저장하는게 나을 것 같음.
처음에 json으로 저장했던 이유는 텍스트로 저장하면 혹시라도 텍스트를 메모장으로 수정하거나 엑셀로 내보낼 때 더 편하지 않을까 생각했던 거였는데,
어차피 export 스크립트 짜야 하는 건 똑같고,
메모장으로 수정할 수 있다는 사소한 점보다 유니티 이벤트 및 씬을 별도의 장치 없이 바로 저장하고 런타임에서도 바로 갖다 쓸 수 있다는게 압도적으로 편익이 큼.

meat data로 scene 참조를 넣으려고 했는데,
Scene은 애초에 Inspector에서 할당이 안됨,
SceneAsset은 할당이 되지만 Editor에서만 사용 가능하므로,
이에 대응되는 scene 이름, 경로, 빌드 순서 등을 저장해놔야 함.
Addressable을 사용하면 씬 참조를 그대로 저장할 수 있다고는 하지만,
추가 패키지 의존성을 갖고 싶지 않았음.
그래서 그냥 씬 참조는 포기.
생각해보니 유니티 이벤트에 필요할 것 같아서 저장을 알아본 거였는데,
ScriptableObject를 사용하게 된 시점에서 유니티에서 알아서 관리하니 상관이 없음.
이벤트를 씬에 종속시키지도 않으면 더 유연하고 좋을 것.

ScriptableObject로 바꾼 이후 변화

  • 단순히 자료형을 해당 SO로 선언하는것 만으로 Inspector 할당 및 검색 종류 제한 가능
  • dictionary에서 키로 참조를 찾아내는게 아니라 참조를 바로 들고 있을 수 있다. (하지만 key는 유지함. 이유는 후술.)

Unity 직렬화 시스템은 일반 C# 객체 참조를 추적하지 않는다고 함.
객체 안에 다른 객체의 참조를 넣으면 실제 참조로 저장하는게 아니라 데이터를 복사하는 형식으로 저장한다고 함.
(MonoBehaviour, ScriptableObject, GameObjectUnityEngine.Object 계열은 데이터가 아니라 직접 참조 저장.)
의도하진 않았지만, Dictionary<string,TextNodeData>로 이 문제를 회피해오고 있었던 것.
ScriptableObject로 넘어오면서 참조를 넣을 순 있게 되었지만 기존 검색 구조는 유지하기로.
추가로, [SerializeReference]를 붙이면 값 복사가 아니라 참조 복사 형태가 된다고는 하는데, 이러면 Inspector 편집이 어려워짐.
gpt가 한 말이라 믿을 수 없어서 직접 붙여서 확인해봤는데, 역시 편집이 되지 않았음.
근데 생각해보니까 Inspector 편집이라는게 필요한가? 어차피 EditorWindow에서 직관적으로 이으면 스크립트가 참조를 연결해주는 방식인데?
이론상은 맞는 말이지만, 유니티가 이 Attribute를 어떤 식으로 구현했는지, 어떤 문제가 발생할지 모르는 상황에서 굳이 코드 구조를 바꿀 이유 없음.

Dictionary<string, TextNodeData>를 SO에 저장하려고 했는데 컴파일 후 다시 열어보니 데이터가 사라짐.
유니티 직렬화는 이런거 안 저장해준다고 함. 다행히 TextNodeData에 key 저장해놨었으니
저장할 땐 List로 저장하고, 로드할 땐 다시 Dict를 만들면 됨.

배운 것

Convert.ChangeType(value, targetType)은 실패 시 exception을 던지고 null이나 false 반환하진 않는다. 그래서 try catch문 써야됨

struct, float같은 value type은 메모리에 저장될 때 바로 메모리에 저장하는데
class의 인스턴스같은 reference type은 메모리에 저장될 때 참조에 대한 포인터가 또 저장됨

그래서 복사할 때 value type은 깊은 복사되고, reference type은 얕은 복사됨.
class 변수에 null 넣어도 실제 instance data는 그대로임.



🎨 Art Practice : Drawing


어깨 : 생각보다 아래, 생각보다 좁다
허리 : 생각보다 더 안으로
다리 : 생각보다 더 굽혀지고 얇게



profile
너 정말 **핵심**을 찔렀어

0개의 댓글