타지않는 놀이터

PackedScene으로 저장할 때 알아둘 것 본문

잡것들/Godot Engine

PackedScene으로 저장할 때 알아둘 것

김메가 2022. 5. 11. 23:33

이 글은 _get_property_list()에 대한 이해가 필요함


변수들이 저장되는 방식은 _get_property_list에서 지정하는 type(TYPE_~~~~)에 따라서 달라진다.


현재 씬의 PackedScene에 원래 있던 것이 아닌 동적으로 추가한 Node들은 owner속성을 설정해줘야 pack()할 때 저장된다.


PackedScene의 pack()을 이용하여 씬을 저장할 때, 저장되는 노드들의 속성은 _get_property_list()에서 usage가 PROPERTY_USAGE_STORAGE를 포함하고 있어야 저장된다.

 

PROPERTY_USAGE_STORAGE는 usage의 기본값이기 때문에 어떤 속성에 대하여 _get_property_list()가 작성되어 있을 경우 일부러 PROPERTY_USAGE_STORAGE를 제외한게 아닌 이상 _get_property_list()에서 usage의 설정을 빼먹어도 저장 가능하다.

 

export를 붙인 변수 또한 알아서 PROPERTY_USAGE_STORAGE로 취급되기 때문에 얘도 pack()할 때 저장된다.

 

*저장 안되는 경우 : var로 변수를 선언했는데,

export안붙이고 _get_property_list()에도 내용을 작성하지 않은 경우에는 pack()할 때 저장되지 않는다.


Object나 Reference, 또는 둘 중 하나를 extends한 클래스의 객체도 pack()할 때 저장할 수 있다. 방법은 다를 것 없이 해당 객체를 담은 변수의 usage를 _get_property_list()에서 지정해주면 된다.

 

다만 얘네들은 _get_property_list()에서 type을 TYPE_OBJECT로 설정해줘야 하는데 ⓐ에서도 말했듯이 type의 설정에 따라 저장되는 방식이 다르다. TYPE_OBJECT의 경우 저장하려는 변수(이하 A)에 들어있는 해당 객체의 모든 속성(과 변수)들을 다 저장한다. 

 

이 부분에서 주의해야할 사항이 두가지 생긴다.

 

첫째, 정말로 모든 속성(과 변수)를 다 저장하기 때문에 ⓒ에서 말한 *저장 안되는 경우에 해당되더라도 TYPE_OBJECT로 저장할 때는 전부 다 저장된다.

 

둘째, 깊은 복사의 방식으로 저장된다. 예를 들어보겠다. 우리가 씬트리에 들어있는 어떤 Node를 저장한다고 치자.

이 Node에는 변수 A가 있고 변수 B가 있다. 그리고 이 두 변수는 둘 다 @라는, Reference를 extends한 객체를 담고 있고 @는 i라는 정수 속성을 가진다. i의 기본값은 0이다. 이때 A.i += 1을 하면 @의 i값이 1증가할 것이고 B도 @를 참조하고 있으므로 B.i의 값은 A.i와 같이 1이 될 것이다. 그런데 이 Node를 pack()으로 저장하면 A의 객체의 값과 B의 객체의 값을 별개로 저장한다. A에는 A의 i값이 들어가고 B에는 B의 i값을 저장한다. 그럼 이렇게 저장한 씬을 instance()하던지 change_scene_to()를 하던지 해서 다시 불러오면, A와 B에는 i의 값은 같지만 서로 다른 객체가 들어가 있게 되는 것이다. 더이상 A.i += 1을 해도 B.i가 변하는 일은 없다. 즉 TYPE_OBJECT인 속성을 pack()으로 저장하게 되면 같은 객체를 공유하고 있던 얕은 복사가 깊은 복사로 변하게 된다.

 

둘째 사항에 대해서 특히나 주의해야하는 상황은 씬에 있는 어떤 Node를 get_node()로 가져와서 변수에 박아둔 경우이다. 이 경우 해당 씬을 PackedScene으로 저장하고 다시 불러오면 그 변수는 씬에 있는 노드를 가리키지 않는다. 대신 씬에 연결되지 않은 새로운 Node(저장한 값들이 들어있는)를 가리키게 된다.

 

Resource는 예외다. Resource도 _get_property_list()에서 TYPE_OBJECT으로 설정해야 저장할 수 있지만 Resource클래스와 이를 extends한 클래스들은 고도에서 특별취급을 해주는지 저장 방식이 다르게 굴러가서 참조가 깨지지 않는다. PackedScene을 메모장으로 까보면 알 수 있다.

 

그리고 내부 클래스(스크립트내에서 class써서 다른 클래스 만든거)의 객체는 저장하지 말자. 이 경우 스크립트를 함께 저장하질 못해서 불러올 때 쌩 Reference나 Object로 불러오기 때문에 사용자 정의 변수를 불러올 수가 없다. 저장해야하는 클래스는 내부 클래스로 작성하지 말고 따로 .gd파일로 작성해야한다.

'잡것들 > Godot Engine' 카테고리의 다른 글

고도 4.0 멀티 윈도우 테스트  (0) 2023.03.05