인프런 커뮤니티 질문&답변

샌즈님의 프로필 이미지
샌즈

작성한 질문수

[유니티 레벨 업!] 모듈식으로 개발하는 퀘스트&업적 시스템

Quest System 구현

스크립터블 오브젝트 Instantiate?

해결된 질문

작성

·

210

0

런타임에 스크립터블 오브젝트를 복사하는 것은 별로 좋지 않은 행위라고 들었습니다. 직렬화된 일반 클래스를 사용하는 것이 더 좋다고 여러 차례 들어왔는데, Task 클래스를 일반 클래스로 전환하는 것이 좋은 생각인지 궁금합니다.

답변 1

2

Developer G님의 프로필 이미지
Developer G
지식공유자

수강해주셔서 감사합니다.

말씀해주신 부분은 반은 맞고 반은 틀리다고 얘기드릴 수 있을 것 같습니다.
꼭 ScriptableObject뿐만 아니라 Instantiate 함수를 쓰는 것 자체가 성능에 좋지 않습니다. 정확한 통계는 아니지만 일반 Class를 생성하는 것보다 최소 20배정도 느리다고 알려져있습니다. Serialize된 Data를 Deserialize하는 작업을 해야하기 때문입니다.

즉, ScriptableObject를 Runtime에서 복사하면 좋지 않다는 말은 GameObject도 Runtime에서 복사하면 좋지 않으니 지양하라는 말과 같습니다. 만약 극단적으로 매 Frame마다 단일 GameObject를 Instantiate 함수로 5개씩 Clone을 만든다면 성능에 문제가 생길까요? GameObject가 계속 쌓이면 언젠가는 문제가 되겠지만, 보통은 Clone을 5개씩 생성한다는 그 자체로는 성능에 유의미한 영향을 주지못할겁니다. ScriptableObject도 마찬가지입니다. 심지어 ScriptableObject는 GameObjec에 비하면 일반적으로 Clone 생성이 빠르며(Component가 없으므로) 필요할 때 한번씩 생성하죠. ScriptableObject의 생성 비용이 두려워서 지양하겠다는 말은 기본 연산자는 성능에 좋지 않으니 모든 연산자를 비트 연산자로 바꿔 사용하자는 것과 같은 얘기입니다. 실제 프로그램엔 아무 영향이 없는걸 이론적으론 이러하니 바꾸자는 소리죠. "야, 비트 연산자를 쓰면 그냥 연산자를 쓰는 것보다 0.0000001초 빨라. 비트 연산자 쓰자"(물론 이런 극단적인 최적화가 필요한 분야도 있긴 합니다.)

ScriptableObject Architecture를 사용하지 말자고 얘기하는 여러 프로그래머들을 봐왔고 그들 나름의 주장이 있고 제가 그에 반박할 주장도 있지만 진지하게 Performance 비용 때문에 ScriptableObject를 쓰지 말자고 주장하는 프로그래머는 보지 못했던 것 같습니다. 그들도 개발자고 저도 개발자이기 때문에 그게 얼마나 의미없는 소리인지와 제대로 쓰면 Performance 문제가 생길 일이 없다는 것을 알기 때문입니다.

그와 별개로, 일반 class가 더 좋겠다 하시면 그렇게 전환하셔도 됩니다. ScriptableObject 같은 경우 직접 Destory 함수로 객체를 파괴해줘야하기 때문에 번거로움이 좀 있긴하죠. 하지만 반대로 편한 Data 관리와 다른 객체로 Drag and Drop을 통한 Serialize를 포기해야하는 등 여러 이점도 포기해야한다는 부분을 명심하셔야합니다.

결론적으로, 의미없는 Performance 문제가 아니라 '실용' 측면에서 스스로 다각도로 면밀히 판단하여 어떻게 할지 결정하시면 될 것 같습니다. 강의는 그저 길잡이일뿐 수강생분께서 더 낫다고 생각되는 방향으로 가시면 됩니다. 실제로 저도 상황에 따라서 어떤 것은 ScriptableObject로 만들고, 어떤 것은 그냥 Class List로 만드는 등 섞어서 사용합니다.

감사합니다.

샌즈님의 프로필 이미지
샌즈

작성한 질문수

질문하기