유니티 에셋으로 코드를 이쁘게 짤 수 있다고?! 에셋만으로...내 코드 실력이 향상?! 대박..이건 못참지! #SOAP

제목이 다소 요란하죠? 그만큼 이 에셋을 사용하면 유니티 개발자들은 "나 코드좀 짠다!" 라는 말을 할 수 있습니다.

왜냐고요? 이 에셋은 Scriptable Object를 효율적으로 사용할 수 있게 아키텍쳐를 제공해주기 때문입니다! 

 

SOAP는 에셋이기 때문에 다른 Asset에서 참조할 수 있고 런타임 및 에디터에서 접근할 수 있습니다.

 

SO를 사용하면 뭐가 좋냐고요?! 리소스 관리, 메모리 관리, 유니티에서 권장하는 Enter Play Mode까지 가능하다고요!!!

 

유니티 답답한 에디터 실행으로부터 해방! #Enter Play Mode Settings

움짤을 보시면 차이가 느껴지십니까? 좌측 움짤의 경우 컴파일 시간이 굉장히 긴 데 반면에, 우측 움짤은 에디터 플레이 시작 버튼을 누름과 동시에 바로 플레이 되고 있습니다. Enter Play Mode란? U

wlsdn629.tistory.com

 


SOAP란?

Soap은 Unity 게임 개발자의 역량을 강화하고 게임 제작 프로세스에 혁명을 일으키겠다는 사명으로 제작되었다고 합니다.

더보기

Wow..정말 멋지죠? 제가 SOAP에게 빠져든 이유랍니다... 저는 코드 작성 능력이 아직 초보수준이라 SOAP를 통해 발전시키고 싶어서 65달러를 투자했습니다! 이정도면 제 인생의 투자대비 나쁘지 않죠!😁

게임 개발을 간소화하려는 초보자이든 특정 문제를 해결하는 노련한 개발자이든 Soap은 개발자의 요구 사항을 충족하도록 설계되었습니다. 

 

Soap은 개발을 시작하는 데 필요한 포괄적인 리소스를 제공하며 단계별 안내를 제공하는 YouTube 튜토리얼, 예시장면, 자세한 문서가 존재합니다.

 

Soap Tutorials (Make a Roguelite Game)

In this tutorial series, you will learn how make a roguelite game from scratch using Soap (Scriptable architecture pattern).

www.youtube.com

 

 

Soap의 가장 큰 장점이라고 생각되는 부분은 Editor Play Mode 옵션과 호환되는 유일한 스크립트 가능 아키텍처 패키지라는 점입니다! 플레이 모드 진입 대기 시간이 최대 90% 감소하여 귀중한 개발 시간이 절약할 수 있습니다.

 

또한 Soap은 Odin, Fast Script Reload 및 Playmaker와 같은 Asset들과 원활하게 통합됩니다.

 

속도를 넘어, Soap은 "품질"을 최우선으로 생각합니다. 이는 에셋 스토어에서 가장 성능이 뛰어난 ScriptableObject 아키텍처 프레임워크라는 타이틀을 자랑합니다. 개발자는 Soap을 활용하여 개발 속도를 높이고 클래스 분리를 통해 깔끔한 코드스타일을 얻을 수 있습니다.

 

진짜... 코드를 작성할 때 답답함을 느끼면 SOAP를 한 번 사용해보시는 거... 정말 추천드립니다!


Soap 사용법

soap사용법은 몇 차례 걸쳐서 블로그 작성을 하고자 합니다. 이 글에서는 대략적인 개요에 대해서만 소개하고자 합니다.

 

Scriptable Variables

출처 - https://docs.google.com/document/d/1jPuuy8XS2DvnLzoxjW81DA4oXilPScGrEyiTwSrd60Y/edit?pli=1

 

Scriptable Variables는 값(value)을 포함하는 특정 타입의 scriptable object입니다. 

  1. 카테고리(Category)
    • 태그와 유사합니다. Soap Wizard에서 조직화할 때 도움이 됩니다.
  2. 값(Value)
    • 변수의 현재 값입니다.
    • 인스펙터(Inspector), 런타임(runtime), 코드 또는 유니티 이벤트를 통해 변경할 수 있습니다.
    • 값이 변경되면 "OnValueChanged" 이벤트가 작동되며, 코드에서 해당 이벤트에 등록할 수 있습니다. 
  3. 디버그 로그 활성화(Debug Log Enabled)
    • 값이 변경될 때 콘솔에 메시지를 기록할지 여부를 결정합니다.
  4. 저장(Saved)
    • 값이 변경될 때 Player Prefs에 변수의 값이 저장될지 여부를 결정합니다. 
    • 기본값(Default Value):
      • 처음에 PlayerPrefs에서 로드할 때 사용되는 초기 값입니다.
      • Save Guid: 기본적으로 변수에 대해 고유한 Guid가 생성됩니다. 사용자가 이를 재정의하려는 경우, 이 설정을 'Manual'로 변경하고 사용자 지정 Guid를 할당하면 됩니다.
  5. Reset On: 변수가 언제 리셋되는지(또는 저장된 경우 로드되는 경우)를 지정합니다.
    1. Scene Loaded : 씬이 로드될 때마다 변수가 리셋됩니다. 이 옵션은 변수가 단일 씬에서만 사용되는 경우에만 리셋되도록 원하는 경우에 사용합니다. (참고: 추가적인 씬을 로드할 때는 리셋되지 않습니다.)
    2. Application Start : 게임이 시작될 때 한 번만 리셋됩니다. 변수의 변경 내용이 씬 간에 유지되기를 원하는 경우 유용합니다.
  6. Is Clamped : FloatVariable 및 IntVariable에만 해당되며, 값을 클램핑하는 기능을 제공합니다. 

 

에디터에서는 저장되지 않은 ScriptableVariables가 플레이 모드를 종료할 때 자동으로 초기 값(플레이 모드에 진입하기 전에 인스펙터에 표시된 값)으로 되돌아갑니다. 또한, 'Reset to Initial Value(초기 값으로 재설정)'이라는 편리한 유틸리티 버튼이 있습니다. 이를 사용하면 인스펙터에서 변수를 빠르게 초기 값으로 재설정할 수 있습니다.

 

출처 - https://docs.google.com/document/d/1jPuuy8XS2DvnLzoxjW81DA4oXilPScGrEyiTwSrd60Y/edit?pli=1

 

새 ScriptableVariables를 생성하려면 프로젝트 창에서 마우스 오른쪽 버튼을 클릭하고 필요한 ScriptableVariable을 선택하시면 됩니다.

다른 방법으로는 클래스 내에서 Scriptable Variable에 대한 참조를 직접 노출할 수 있습니다. 그런 다음, 인스펙터(Inspector)에서 'Create' 버튼을 클릭하여 프로젝트 창에서 현재 선택된 폴더에 해당 Scriptable Variable의 새 인스턴스를 생성할 수 있습니다. 

 

출처 - https://docs.google.com/document/d/1jPuuy8XS2DvnLzoxjW81DA4oXilPScGrEyiTwSrd60Y/edit?pli=1

 

플레이 모드에서는 Scriptable Variable의 OnValueChanged 이벤트에 등록된 객체(및 해당 컴포넌트)가 인스펙터에 표시됩니다.

 

위의 스크린샷에서 볼 수 있듯이, 세 개의 객체가 이 변수(example_float_playerCurrentHealth)에 등록되어 있습니다. 이 변수에 응답하는 첫 번째 요소를 검사하면, "BindTextMeshPro" 컴포넌트를 가진 "HealthText"라는 GameObject가 hierarchy에서 발견됩니다. 첫 번째 버튼을 클릭하면 해당 객체가 hierarchy에서 강조됩니다. "Select" 버튼을 클릭하면 hierarchy에서 해당 객체가 선택됩니다. 

 


Scriptable Lists

 

스크립터블 리스트는 클래스 간에 "매니저"가 필요하지 않도록 의존성을 해결하는 데 유용할 수 있습니다.

출처 - https://docs.google.com/document/d/1jPuuy8XS2DvnLzoxjW81DA4oXilPScGrEyiTwSrd60Y/edit?pli=1

 

해당 리스트의 속성을 살펴보겠습니다.

  • Reset On: 이 리스트가 언제 비워지는지를 지정합니다.
    • Scene Loaded(씬 로드될 때): 씬이 로드될 때마다 리스트가 비워집니다. 추가 씬 로딩은 무시됩니다.
    • Application Start(애플리케이션 시작): 게임이 시작될 때 리스트가 비워집니다.
  • List content: 플레이 모드에서는 리스트를 구성하는 모든 요소를 볼 수 있습니다. 첫 번째 버튼(객체 이름과 함께 있는 버튼)을 클릭하면 해당 객체가 hierarchy에서 강조됩니다. "Select" 버튼을 클릭하면 해당 객체가 hierarchy에서 선택됩니다.

 

출처 - https://docs.google.com/document/d/1jPuuy8XS2DvnLzoxjW81DA4oXilPScGrEyiTwSrd60Y/edit?pli=1

 

에디터에서는 플레이 모드를 종료할 때 ScriptableLists가 자동으로 자기 자신을 비웁니다. 새로운 리스트를 생성하려면, 간단히 프로젝트 창에서 필요한 ScriptableList를 만드시면 됩니다.

또는 클래스 내에서 Scriptable List에 대한 참조를 직접 노출할 수 있습니다. 그런 다음, 인스펙터(Inspector)에서 'Create' 버튼을 클릭하여 프로젝트 창에서 현재 선택된 폴더에 해당 Scriptable List의 새 인스턴스를 생성할 수 있습니다. 

 


Scriptable Events

(좌) Events without parameters / (우) Events with parameters /  출처 - https://docs.google.com/document/d/1jPuuy8XS2DvnLzoxjW81DA4oXilPScGrEyiTwSrd60Y/edit?pli=1

 

스크립터블 이벤트에는 다음과 같이 두 가지 유형이 있습니다.

  1. 매개변수 없는 이벤트
  2. 매개변수를 가진 이벤트

이벤트의 속성은 다음과 같습니다.

  • Debug Log Enabled: 만약 true로 설정되면, 해당 이벤트가 발생할 때 호출된 메서드들과 관련된 게임 오브젝트에 대한 정보를 콘솔에 기록합니다.
  • Debug Value: 인스펙터에서 디버깅에 사용할 수 있는 값입니다.
  • Raise: 이 버튼은 플레이 모드에서만 활성화됩니다. 이 버튼을 통해 인스펙터에서 이벤트를 발생시킬 수 있습니다.

 

출처 - https://docs.google.com/document/d/1jPuuy8XS2DvnLzoxjW81DA4oXilPScGrEyiTwSrd60Y/edit?pli=1

 

이벤트는 코드, 유니티 액션 또는 인스펙터에서(raise 버튼을 통해) 발생시킬 수 있습니다. 인스펙터에서 이벤트를 발생시키는 것은 게임을 빠르게 디버깅하는 데 유용할 수 있습니다. 이벤트를 생성하려면 프로젝트 창에서 생성하거나 클래스 내에서 Scriptable Event에 대한 참조를 직접 노출할 수 있습니다. 그런 다음, 인스펙터(Inspector)에서 'Create' 버튼을 클릭하여 프로젝트 창에서 현재 선택된 폴더에 해당 Scriptable Event의 새 인스턴스를 생성할 수 있습니다.

 

출처 - https://docs.google.com/document/d/1jPuuy8XS2DvnLzoxjW81DA4oXilPScGrEyiTwSrd60Y/edit?pli=1

 

이벤트가 발생했을 때 이를 수신하려면, GameObject에 해당 이벤트 유형의 이벤트 리스너(Event Listener) 컴포넌트를 연결해야 합니다.

 

이벤트 리스너의 속성은 다음과 같습니다. 

  • Binding
    • Until_Destroy(파괴될 때까지): Awake()에서 등록하고 OnDestroy()에서 구독을 취소합니다.
    • Until_Disable(비활성화될 때까지): OnEnable()에서 등록하고 OnDisable()에서 구독을 취소합니다.
  • Disable after subscribing: true로 설정하면, 이벤트에 등록한 후에 GameObject를 비활성화합니다. UI 요소에 유용합니다.
  • Event responses: 이벤트가 발생한 후 호출되는 각 응답입니다.
    • Delay: 응답이 호출(Invoke)되기 전의 지연 시간(초)입니다.
    • Scriptable Event: 수신하려는 이벤트입니다.
    • Response: 트리거된 유니티 액션입니다.

 

출처 - https://docs.google.com/document/d/1jPuuy8XS2DvnLzoxjW81DA4oXilPScGrEyiTwSrd60Y/edit?pli=1

 

이벤트에 대한 등록을 코드에서 직접 처리할 수도 있지만(OnRaised 액션을 통해) 자체 플레이 모드용 커스텀 인스펙터를 가지고 있습니다. 플레이 모드에서는 해당 이벤트에 등록된 모든 GameObject를 검사할 수 있습니다.

 

여러분의 스크립트 중 어떤 이벤트가 특정 메서드를 호출하는지 기억하지 못한다면, 이벤트 디버그 창(Events Debug Window)을 사용할 수 있습니다.
이벤트 디버그 창(Event Debug Window)에서 메서드의 이름을 입력하면, 해당 메서드를 호출하는 모든 객체를 검색하여 찾습니다. (참고: 대소문자를 구분합니다.) 메서드를 찾게 되면(또는 찾지 못한 경우), 콘솔에 메시지가 기록됩니다. 이 메시지를 클릭하면 계층구조에서 해당하는 객체가 강조됩니다. 

 


Bindings

출처 - https://docs.google.com/document/d/1jPuuy8XS2DvnLzoxjW81DA4oXilPScGrEyiTwSrd60Y/edit?pli=1

 

바인딩은 GameObject에 부착되는 컴포넌트로, 변수에 바인딩되어 해당 변수의 값이 변경될 때 간단한 동작을 수행할 수 있습니다. 바인딩을 사용하면 색상, 텍스트, 이미지 및 기타 요소를 변경하는 것과 같은 작은 조정에 대한 별도의 스크립트를 작성하는 필요성을 제거하여 개발을 단순화하기 위해 설계되었습니다.

 


Soap Wizard

 

Soap 위저드는 Soap의 모든 스크립터블 오브젝트를 관리하기 위해 설계되었으며 편리한 기능들을 제공하는 사용자 정의 창입니다.

출처 - https://docs.google.com/document/d/1jPuuy8XS2DvnLzoxjW81DA4oXilPScGrEyiTwSrd60Y/edit?pli=1

 

  1. 폴더 변경: 이 곳에서 위저드가 모든 스크립터블 변수, 이벤트 및 리스트를 찾을 루트 폴더를 지정할 수 있습니다. 기본적으로 'Assets'로 설정되어 있으며, 프로젝트 내의 모든 Soap 스크립터블 오브젝트로 위저드를 채웁니다.
  2. 카테고리: 카테고리별로 필터링합니다. 레이어 마스크처럼 작동합니다(다중 선택 가능). 이 필터의 레이아웃을 변경하고 카테고리를 편집할 수 있습니다.
  3. 타입 필터: Soap 스크립터블 오브젝트의 유형별로 필터링합니다 (All, 변수, 이벤트, 리스트 등).
  4. 검색 바: 특정 스크립터블 오브젝트를 필터링하고 검색합니다. 
  5. 콘텐츠: 필터와 선택한 폴더에 따라 Soap 스크립터블 오브젝트를 표시합니다. 별 버튼을 클릭하여 SO를 즐겨찾기 설정할 수 있습니.
  6. 유틸리티: (왼쪽에서 오른쪽으로) 프로젝트 창에서 SO 선택, SO 이름 변경, SO 복제 (프로젝트 창의 CTRL+D와 유사), SO 삭제.
  7. 선택된 SO 뷰: 선택된 스크립터블 오브젝트를 표시하는 인스펙터입니다.

"Create New Type" 팝업을 사용하면 새로운 종류의 Soap 스크립터블 오브젝트를 생성할 수 있습니다. 예를 들어, 'Player' 유형의 사용자 정의 변수를 생성하려면 이 기능이 해당 C# 클래스를 생성하고 선택한 폴더에 저장합니다. 생성하려는 클래스를 선택하면 됩니다.

출처 - https://docs.google.com/document/d/1jPuuy8XS2DvnLzoxjW81DA4oXilPScGrEyiTwSrd60Y/edit?pli=1

 

 


Enabling Editor fast play mode

 

 

이거 때문에 Soap를 사용한다고 해도 과언이 아니죠! 이 기능을 활성화하는 방법입니다!

출처 - https://docs.google.com/document/d/1jPuuy8XS2DvnLzoxjW81DA4oXilPScGrEyiTwSrd60Y/edit?pli=1

 

단축키 (CTRL + L)를 사용하거나 도구(Tool) 메뉴를 통해 이동할 수 있습니다.

 

 


구매 링크

 

여기 까지 Soap에 대해 간단하게 알아보았습니다! 

위에서 본 사용 방법만으로도 코드가 깔끔해지는 소리 들리지 않으신가요? 

 

다음시간에는 더 자세히 Soap 사용법에 대해 알아보겠습니다!

 

우리 모두 클린 코드하는 그 날을 위해! 빠샤!!!😎🤗🫡

 

 

이 글은 어필리에이트 링크를 포함하고 있습니다. 

위 링크를 클릭하셔서 애셋을 구매하시면 저에게 수수료가 제공됩니다.
링크를 클릭하는 것으로는 수익이 발생하지 않습니다!
감사합니다!