• 게임
  • 산업 분야
  • 리소스
  • 커뮤니티
  • 학습
  • 문의하기
개발
Unity 엔진
모든 플랫폼 위한 2D 및 3D 게임 제작
다운로드플랜 및 가격
수익화
인앱 결제/인앱 구매(IAP)
스토어 간 IAP 검색 및 관리
Mediation
수익 / 매출 극대화 및 수익화 / 수익 창출 최적화(하다)
Ad Quality
앱 유저. '광고 지면'의 타겟 고객 경험 보호
탭조이
장기적인 유저. '광고 지면'의 타겟 고객 충성도 구축
모든 수익화 / 수익 창출 제품
사용자 확보
사용자 확보
모바일 사용자를 검색하고 Acquire
Unity 벡터 AI
적합한 게임으로 플레이어 연결
Aura 디바이스 단위 광고
최대 참여/인게이지먼트 시 기기 내 사용자 도달률
모든 성장 제품
활용 부문
3D 협업
실시간 3D 프로젝트 빌드 및 검토
몰입형 교육
몰입도 높은 환경 제작
고객 경험
인터랙티브 3D 경험 제작
모든 업계 솔루션
산업 분야
제조업
운영 우수성 확보
리테일
상점 경험을 온라인 경험으로 전환
자동차
혁신 및 차량 내 경험 향상
전체 산업 분야
테크니컬 라이브러리
기술 자료
공식 유저. '광고 지면'의 타겟 고객 매뉴얼 및 API 레퍼런스
개발자 툴
릴리스 버전 및 이슈 트래커
로드맵
예정된 기능 검토
용어집
기술 용어 라이브러리
분석 자료
활용 사례
실제 성공 사례
베스트 프랙티스 가이드
전문가 팁
모든 리소스
새로운 기능
블로그
업데이트, 정보, 기술 팁
뉴스
뉴스, 스토리, 보도 센터
커뮤니티 허브
토론
토론, 문제 해결, 소통
이벤트
글로벌 이벤트 및 현지 이벤트
커뮤니티 사례
Made with Unity
Unity 크리에이터 소개
Livestreams
개발자, 크리에이터, Insider와의 소통
Unity Awards
전 세계 Unity 크리에이터 축하
모든 레벨 지원
Unity Learn
무료로 Unity 기술 마스터
전문 교육
Unity 강사와 함께 팀의 역량을 강화하세요
Unity 처음 사용하시나요
시작하기
학습 시작하기
Unity 필수 학습 길잡이
Unity 사용이 처음이신가요? 여정 시작하기
사용법 가이드
실용적인 팁 및 베스트 프랙티스
교육
학생용
커리어 시작하기
교육 담당자 대상 교육
교육 효율 극대화
교육 라이선스
교육 기관에 Unity 강력한 기능 도입
자격증
Unity 숙련도를 입증하세요
지원 옵션
도움 받기
성공을 위한 Unity
Success 플랜
전문가 지원을 통해 더 빠르게 목표 도달률 달성
FAQ
일반적인 질문에 대한 답변
문의하기
유니티 팀과 소통하기
플랜 및 가격
언어
  • English
  • Deutsch
  • 日本語
  • Français
  • Português
  • 中文
  • Español
  • Русский
  • 한국어
소셜
통화
구매
  • 제품
  • 유니티 애즈
  • 구독
  • Unity 에셋 스토어
  • 리셀러
교육
  • 학생
  • 교육 담당자
  • 기관
  • 인증 시험
  • 레벨업 아카데미
  • Skills Development Program
다운로드
  • Unity Hub
  • 다운로드 아카이브
  • 베타 프로그램
Unity Labs
  • Labs
  • Publications
리소스
  • Unity 학습 플랫폼
  • 커뮤니티
  • 기술 자료
  • Unity QA
  • FAQ
  • Services Status
  • 활용 사례
  • Made with Unity
Unity
  • 회사
  • 뉴스레터
  • 블로그
  • 이벤트
  • 채용 정보
  • 도움말
  • Press
  • 파트너
  • 투자자
  • 어필리에이트
  • 보안
  • 소셜 임팩트
  • Inclusion & Diversity
  • 문의하기
Copyright © 2025 Unity Technologies
  • 법적 고지 사항
  • 개인정보처리방침
  • 쿠키
  • 개인정보 판매 또는 공유 금지

'Unity', Unity 로고 및 기타 Unity 상표는 미국 및 기타 국가에서 유니티 테크놀로지스 또는 계열사의 상표 또는 등록상표입니다(여기에서 자세한 정보 확인). 기타 명칭 또는 브랜드는 해당 소유자의 상표입니다.

Hero background image
Last updated May 2019, 10 min. read

프로젝트가 확장될 때 코드 설계 방법

이 웹페이지는 이해를 돕기 위해 기계 번역으로 제공됩니다. 기계 번역으로 제공되는 콘텐츠에 대한 정확도나 신뢰도는 보장되지 않습니다. 번역된 콘텐츠의 정확도에 관해 의문이 있는 경우 웹페이지의 공식 영어 원문을 참고해 주시기 바랍니다.
여기를 클릭하세요.

이 페이지에서 얻을 수 있는 것: 성장하는 프로젝트의 코드를 설계하기 위한 효과적인 전략으로, 문제를 줄이면서 깔끔하게 확장할 수 있습니다. 프로젝트가 성장함에 따라 반복해서 설계를 수정하고 정리해야 합니다. 변경 사항에서 한 걸음 물러나고, 작은 요소로 나누어 정리한 다음, 다시 모두 함께 조립하는 것이 항상 좋습니다.

이 기사는 스웨덴 게임 스튜디오 Fall Damage의 CTO인 미카엘 칼름스가 작성했습니다. 미카엘은 20년 넘게 게임 개발 및 출시 관련 일을 해왔습니다. 이 모든 시간이 지나도 그는 프로젝트가 안전하고 효율적으로 성장할 수 있도록 코드를 설계하는 데 여전히 깊은 관심을 가지고 있습니다.

  • 단순한 것에서 복잡한 것까지
  • 인스턴스, 프리팹 및 스크립터블 오브젝트
  • 간단한 코드 예제의 파라미터
  • ScriptableObject 사용하기
  • 규모가 큰 MonoBehavior 분할하기
  • MonoBehavior에서 일반적인 C# 클래스로
  • 인터페이스 사용하기
  • 소프트웨어 아키텍처
  • 로직 및 프레젠테이션
  • 데이터 전용 클래스 및 헬퍼 클래스
  • 정적 메서드
  • 오브젝트 분리하기
  • 씬 로드하기
  • 깔끔하고 제어된 종료
  • 씬 파일 병합의 번거로움 줄이기
  • 코드 테스트 프로세스 자동화
  • 콘텐츠 테스트 프로세스 자동화
  • 자동화된 게임 플레이 만들기
프로젝트가 확장될 때 코드 설계 방법

단순한 것에서 복잡한 것까지

내 팀이 만든 매우 기본적인 Pong 스타일 게임의 코드 예제를 살펴보겠습니다. 이는 제 Unite Berlin 발표를 위한 것입니다. 위의 이미지에서 볼 수 있듯이, 두 개의 패들과 네 개의 벽이 있습니다. 위와 아래, 왼쪽과 오른쪽에 게임 로직과 점수 UI가 있습니다. 패들과 벽에 간단한 스크립트가 있습니다.

이 예제는 다음과 같은 몇 가지 핵심 원칙에 기반을 두고 있습니다.

  • 하나의 “항목“ = 하나의 프리팹
  • 하나의 “항목“에 대한 맞춤형 로직 = 하나의 MonoBehavior
  • 애플리케이션 = 상호 연결된 프리팹을 포함하는 씬

이러한 원칙은 이와 같은 매우 간단한 프로젝트에 적용되지만, 우리가 이것을 성장시키고 싶다면 구조를 변경해야 합니다. 그렇다면 코드를 구성하기 위해 사용할 수 있는 전략은 무엇인가요?

프로젝트가 확장될 때 코드 설계 방법_컴포넌트 파라미터

인스턴스, 프리팹 및 스크립터블 오브젝트

우선, 인스턴스, 프리팹 및 스크립터블 오브젝트 간의 차이에 대한 혼란을 없애봅시다. 위는 플레이어 1의 패들 게임 오브젝트에서 패들 컴포넌트를 인스펙터에서 본 것입니다:

그 위에는 세 개의 매개변수가 있습니다. 그러나 이 보기에서는 기본 코드가 나에게 기대하는 것이 무엇인지에 대한 어떤 표시도 없습니다.

왼쪽 패들의 Input Axis를 인스턴스에서 변경하여 바꾸는 것이 의미가 있나요, 아니면 프리팹에서 그렇게 해야 하나요? 입력축은 플레이어마다 다르므로, 아마도 인스턴스에서 변경해야 할 것입니다. Movement Speed Scale는 어떻습니까? 그것은 인스턴스에서 변경해야 할까요, 아니면 프리팹에서 변경해야 할까요?

패들 컴포넌트를 나타내는 코드를 살펴보겠습니다.

프로젝트가 확장될 때 코드 설계 방법_코드의 파라미터

간단한 코드 예제의 파라미터

잠시 멈추고 생각해보면, 서로 다른 매개변수가 프로그램에서 서로 다른 방식으로 사용되고 있음을 깨닫게 될 것입니다. 각 플레이어에 대해 InputAxisName을 개별적으로 변경해야 합니다: MovementSpeedScaleFactor와 PositionScale은 두 플레이어가 공유해야 합니다. 인스턴스, 프리팹 및 스크립터블 오브젝트를 사용할 시기를 안내할 수 있는 전략은 다음과 같습니다:

  • 무언가가 단 한 번만 필요합니까? 프리팹을 생성한 다음 인스턴스화합니다.
  • 무언가를 여러 번 필요로 하며, 인스턴스별 수정이 필요할 수 있습니까? 그렇다면 프리팹을 생성하고 인스턴스화한 다음 일부 설정을 재정의할 수 있습니다.
  • 여러 인스턴스에서 동일한 설정을 보장하고 싶습니까? 그렇다면 스크립터블 오브젝트를 생성하고 그곳에서 데이터를 소스합니다.

다음 코드 예제에서 패들 컴포넌트와 함께 스크립터블 오브젝트를 사용하는 방법을 확인하세요.

프로젝트가 확장될 때 코드 설계 방법_스크립터블 오브젝트 사용

ScriptableObject 사용하기

이 설정을 PaddleData 유형의 스크립터블 오브젝트로 이동했기 때문에, 우리는 패들 컴포넌트에서 해당 PaddleData에 대한 참조만 가지고 있습니다. 인스펙터에는 PaddleData와 두 개의 Paddle 인스턴스가 있습니다. 계속해서 개별적인 패들이 각기 가리키고 있는 공유 설정의 패킷과 축 이름을 변경할 수 있습니다. 새로운 구조는 다양한 설정 뒤에 있는 의도를 더 쉽게 볼 수 있게 해줍니다.

프로젝트가 확장될 때 코드 설계 방법_단일 책임 원칙

규모가 큰 MonoBehavior 분할하기

이것이 실제 개발 중인 게임이라면, 개별 MonoBehavior가 점점 더 커지는 것을 볼 수 있을 것입니다. 각 클래스가 하나의 것을 처리해야 한다고 규정하는 단일 책임 원칙(Single Responsibility Principle)에 따르면서 MonoBehavior를 분리하는 방법을 살펴보겠습니다. 올바르게 적용된다면, "특정 클래스는 무엇을 합니까?"와 "무엇을 하지 않습니까?"라는 질문에 짧은 답변을 할 수 있어야 합니다. 이것은 팀의 모든 개발자가 개별 클래스가 무엇을 하는지 이해하기 쉽게 만듭니다. 이 원칙은 모든 규모의 코드 기반에 적용할 수 있습니다. 위의 이미지에 표시된 간단한 예제를 살펴보겠습니다.

이것은 공에 대한 코드입니다. 많아 보이지 않지만, 자세히 살펴보면 공이 초기 속도 벡터를 설정하기 위해 디자이너에 의해 사용되고, 자작 물리 시뮬레이션에 의해 현재 공의 속도를 추적하는 데 사용되는 속도를 가지고 있음을 알 수 있습니다.

우리는 두 가지 약간 다른 목적을 위해 동일한 변수를 재사용하고 있습니다. 공이 움직이기 시작하면 초기 속도에 대한 정보가 사라집니다.

직접 만든 물리 시뮬레이션은 FixedUpdate()의 동작이 아닙니다. 여기에는 공이 벽에 부딪칠 때의 반응도 포함됩니다.

OnTriggerEnter() 콜백 내부 깊숙한 곳에 Destroy() 작업이 있습니다. 즉, 트리거 로직이 자체 게임 오브젝트를 삭제하는 곳입니다. 대규모 코드베이스에서는 엔티티가 스스로를 삭제하도록 허용하는 경우는 드물며, 대신 소유자가 자신이 소유한 것을 삭제하는 경향이 있다.

여기에서 사물을 더 작은 부분으로 나눌 기회가 있다. 이 클래스에는 여러 가지 책임 유형이 있다 - 게임 로직, 입력 처리, 물리 시뮬레이션, 프레젠테이션 등.

다음은 작게 나누는 방법입니다.

  • 일반적인 게임 로직, 입력 처리, 물리 시뮬레이션 및 프레젠테이션은 MonoBehavior, 스크립터블 오브젝트 또는 원시적인 C# 클래스 내에 있을 수 있습니다.
  • Inspector에서 매개변수를 표시하려면, MonoBehavior 또는 스크립터블 오브젝트를 사용할 수 있습니다.
  • 엔진 이벤트 핸들러와 GameObject의 수명주기 관리는 MonoBehaviors 내에 있어야 합니다.

많은 게임에 대해 가능한 한 많은 코드를 MonoBehaviors에서 빼내는 것이 가치가 있다고 생각한다. 그 방법 중 하나는 ScriptableObjects를 사용하는 것이며, 이 방법에 대한 훌륭한 자료가 이미 있다.

프로젝트가 확장될 때 코드 설계 방법_MonoBehavior를 C# 클래스로 이동

MonoBehavior에서 일반적인 C# 클래스로

MonoBehaviors를 일반 C# 클래스로 이동하는 것은 또 다른 방법이지만, 이 방법의 이점은 무엇인가?

일반 C# 클래스는 코드를 작고 조합 가능한 조각으로 나누는 데 있어 Unity의 객체보다 더 나은 언어 기능을 가지고 있다. 그리고 일반 C# 코드는 Unity 외부의 네이티브 .NET 코드베이스와 공유할 수 있다.

반면에 일반적인 C# 클래스를 사용하면, 편집기가 객체를 이해하지 못하고 Inspector에 네이티브 형식으로 표시할 수 없게 되는 등의 문제가 발생할 수 있습니다.

이 방법을 사용하면 책임 유형에 따라 로직을 나누고자 한다. 다시 공의 예제를 살펴보면, BallSimulation이라고 하는 간단한 물리 시뮬레이션을 C# 클래스로 옮겼습니다. 그것이 해야 할 유일한 작업은 물리 통합과 공이 무언가에 부딪힐 때 반응하는 것이다.

그러나 공 시뮬레이션이 실제로 부딪히는 것에 따라 결정을 내리는 것이 의미가 있는가? 이는 게임 로직에 더 가깝습니다. 결국 우리는 Ball이 어떤 방식으로든 시뮬레이션을 제어하는 로직 부분을 가지고 있으며, 그 시뮬레이션의 결과가 MonoBehavior로 피드백된다는 것을 알게 된다.

위의 재구성된 버전을 보면, 우리가 보는 중요한 변화 중 하나는 Destroy() 작업이 더 이상 여러 층 아래에 묻혀 있지 않다는 것이다. 현재 MoneBehavior에는 몇 가지 명확한 책임 영역만 남아 있다.

우리는 이 작업을 위해 더 많은 것을 할 수 있다. FixedUpdate()에서 포지션 업데이트 로직을 살펴보면, 코드를 한 위치에서 보내면 거기에서 새로운 포지션을 반환해야 한다는 사실을 알 수 있습니다. 공 시뮬레이션은 실제로 공의 위치를 소유하지 않으며, 제공된 공의 위치를 기반으로 시뮬레이션 틱을 실행하고 결과를 반환한다.

프로젝트가 확장될 때 코드 설계 방법_인터페이스 사용

인터페이스 사용하기

인터페이스를 사용하면 아마도 그 공 MonoBehavior의 일부를 시뮬레이션과 공유할 수 있을 것이다. 필요한 부분만 (위 이미지를 참조).

코드를 다시 살펴보자. Ball 클래스는 간단한 인터페이스를 구현합니다. LocalPositionAdapter 클래스를 사용하면 Ball 오브젝트에 대한 레퍼런스를 다른 클래스로 넘길 수 있습니다. 우리는 전체 Ball 객체를 전달하지 않고, 오직 LocalPositionAdapter 측면만 전달한다.

BallLogic은 GameObject를 파괴할 시간임을 Ball에 알려야 한다. 플래그를 반환하는 대신에 Ball은 BallLogic에 델리게이트를 제공할 수 있습니다. 이것이 재구성된 버전에서 마지막에 표시된 행이 하는 일입니다. 이것은 깔끔한 디자인을 제공합니다: 많은 보일러플레이트 로직이 있지만, 각 클래스는 좁게 정의된 목적을 가지고 있습니다.

이 원칙을 잘 사용하면 1인 프로젝트를 잘 구성할 수 있을 것입니다.

프로젝트가 확장될 때 코드 설계 방법_소프트웨어 아키텍처

소프트웨어 아키텍처

조금 더 큰 프로젝트를 위한 소프트웨어 아키텍처 솔루션을 살펴보겠습니다. 볼 게임의 예를 사용하면, 코드에 더 구체적인 클래스를 도입하기 시작할 때–BallLogic, BallSimulation 등–계층 구조를 구성할 수 있어야 합니다:

MonoBehaviours는 모든 다른 로직을 감싸기 때문에 모든 것을 알아야 하지만, 게임의 시뮬레이션 조각은 로직이 어떻게 작동하는지 알 필요는 없습니다. 시뮬레이션을 실행할 뿐입니다. 때때로, 로직은 시뮬레이션에 신호를 공급하고, 시뮬레이션은 그에 따라 반응합니다.

입력을 별도의 독립된 장소에서 처리하는 것이 유익합니다. 바로 이곳에서 입력 이벤트가 생성되며 로직에 이를 공급합니다. 다음에 일어나는 일은 시뮬레이션에 달려 있습니다.

이것은 입력과 시뮬레이션에 잘 작동합니다. 그러나, 특별 효과를 생성하는 로직, 점수 카운터를 업데이트하는 것 등과 같이 프레젠테이션과 관련된 모든 것에서 문제에 직면할 가능성이 높습니다.

로직 및 프레젠테이션

프레젠테이션은 다른 시스템에서 무슨 일이 일어나고 있는지 알아야 하지만, 모든 시스템에 대한 완전한 접근 권한이 필요하지는 않습니다. 가능하다면 로직과 프레젠테이션을 분리하세요. 로직만 있는 모드와 로직과 프레젠테이션이 모두 있는 모드에서 코드 베이스를 실행할 수 있는 지점에 도달하도록 노력하세요.

때때로 프레젠테이션이 적절한 시점에 업데이트되도록 로직과 프레젠테이션을 연결해야 할 필요가 있습니다. 하지만 이 경우에도 올바르게 표시하는 데 필요한 것만 프레젠테이션에 제공해야 합니다. 이렇게 하면, 당신이 구축하고 있는 게임의 전반적인 복잡성을 줄여줄 두 부분 간의 자연스러운 경계를 얻을 수 있습니다.

데이터 전용 클래스 및 헬퍼 클래스

때로는 데이터로 수행할 수 있는 모든 로직 및 연산을 같은 클래스에 통합하지 않고, 해당 데이터만 포함하는 클래스를 갖는 것이 좋습니다.

또한 데이터는 소유하지 않지만 부여된 객체를 조작하는 함수는 포함하는 클래스를 만드는 것이 좋습니다.

정적 메서드

정적 메서드의 장점은, 만약 그것이 어떤 전역 변수를 건드리지 않는다고 가정한다면, 메서드를 호출할 때 전달되는 인수만 보고 메서드가 잠재적으로 영향을 미치는 범위를 식별할 수 있다는 것입니다. 메서드의 구현을 전혀 살펴볼 필요가 없습니다.

이 접근 방식은 함수형 프로그래밍 분야에 관련됩니다. 여기서 핵심은 함수에 무언가를 보내면, 함수는 결과를 반환하거나 반환 파라미터 중 하나를 수정한다는 점입니다. 이 접근 방식을 시도해 보세요; 고전적인 객체 지향 프로그래밍을 할 때보다 버그가 적게 발생할 수 있습니다.

오브젝트 분리하기

객체들 사이에 접착 로직을 삽입하여 객체들을 분리할 수도 있습니다. Pong 스타일의 예제 게임을 다시 보면, 공 로직과 점수 프레젠테이션이 서로 어떻게 이야기할까요? 공과 관련하여 무언가가 발생하면 공 로직이 점수 프레젠테이션에 정보를 주는 것일까요? 점수 로직이 공 로직에 쿼리하는 것일까요? 그들은 서로 대화해야 할 필요가 있습니다, 어떤 식으로든.

로직이 데이터를 쓸 수 있는 저장 공간을 제공하고 프레젠테이션이 데이터를 읽을 수 있는 버퍼 객체를 생성할 수 있습니다. 또는, 그들 사이에 큐를 두어 논리 시스템이 큐에 항목을 넣고 프레젠테이션이 큐에서 오는 것을 읽을 수 있도록 할 수 있습니다.

게임이 성장함에 따라 논리를 프레젠테이션에서 분리하는 좋은 방법은 메시지 버스를 사용하는 것입니다. 메시징의 핵심 원칙은 수신자도 발신자도 상대방에 대해 알지 못하지만 메시지 버스/시스템은 인식하고 있다는 것을 양 쪽이 모두 안다는 것입니다. 따라서 점수 프레젠테이션은 점수를 변경하는 모든 이벤트에 대해 메시징 시스템에서 정보를 받아야 합니다. 그러면 게임 로직은 플레이어의 포인트 변화를 나타내는 이벤트를 메시징 시스템에 게시합니다. 시스템을 분리하고 싶다면 UnityEvents를 사용하여 시작하는 것이 좋습니다. 또는 직접 작성할 수도 있습니다. 그러면 별도의 목적을 위한 별도의 버스를 가질 수 있습니다.

씬 로드하기

LoadSceneMode.Single 사용을 중지하고 대신 LoadSceneMode.Additive를 사용하세요.

장면을 언로드하려면 명시적 언로드를 사용하세요. 언젠가는 장면 전환 중에 몇 개의 객체를 살아있게 유지해야 할 필요가 있습니다.

DontDestroyOnLoad 사용도 중지하세요. 이를 사용하면 오브젝트의 수명을 제어할 수 없습니다. 실제로 LoadSceneMode.Additive를 사용해 로딩할 경우, DontDestroyOnLoad를 사용할 필요가 없습니다. 오래 살아있는 객체를 특별한 오래 살아있는 장면에 넣으세요.

깔끔하고 제어된 종료

제가 작업한 모든 게임에서 유용했던 팁을 추가하자면, 깔끔하고 제어된 종료를 지원하는 것입니다.

애플리케이션이 종료되기 전에 사실상 모든 리소스를 해제할 수 있도록 하세요. 가능하다면, 전역 변수가 여전히 할당되지 않아야 하며, GameObject는 DontDestroyOnLoad로 표시되지 않아야 합니다.

특정한 순서로 종료하는 경우, 오류를 발견하고 리소스 누수를 찾기가 더 쉬워집니다. 이렇게 하면 플레이 모드를 종료할 때 양호한 상태로 Unity 에디터를 나갈 수 있습니다. Unity는 플레이 모드를 종료할 때 전체 도메인을 다시 로드하지 않습니다. 깨끗한 종료가 이루어지면, 에디터나 어떤 종류의 편집 모드 스크립팅이 게임을 에디터에서 실행한 후 이상한 동작을 보일 가능성이 줄어듭니다.

씬 파일 병합의 번거로움 줄이기

Git, Perforce 또는 Plastic과 같은 버전 관리 시스템을 사용하여 이를 수행할 수 있습니다. 모든 에셋을 텍스트로 저장하고 오브젝트를 씬 파일에서 프리팹으로 이동시킵니다. 마지막으로, 장면 파일을 여러 개의 작은 장면으로 나누되, 이는 추가 도구가 필요할 수 있음을 인식하세요.

코드 테스트 프로세스 자동화

10명 이상의 팀이 될 예정이라면 프로세스 자동화 작업을 해야 합니다.

창의적인 프로그래머라면 독창적이고 신중한 작업을 하고 가능한 반복적인 부분은 최대한 자동화하도록 해야 합니다.

코드에 대한 테스트를 작성하는 것부터 시작하세요. 특히 MonoBehaviour에서 일반 클래스로 이동하는 경우, 로직 및 시뮬레이션 모두에 대한 단위 테스트를 작성하기 위해서 단위 테스트 프레임워크를 사용하는 방법이 간단합니다. 모든 곳에서 의미가 있는 것은 아니지만, 나중에 다른 프로그래머가 코드를 접근할 수 있도록 만드는 경향이 있습니다.

콘텐츠 테스트 프로세스 자동화

테스트는 단순히 코드를 테스트하는 것이 아닙니다. 콘텐츠도 테스트가 필요할 수 있습니다. 팀에 콘텐츠 제작자가 있다면, 그들이 만든 콘텐츠를 신속하게 검증할 수 있는 표준화된 방법이 있다면 모두 더 나은 결과를 얻을 수 있습니다.

로직 테스트 - 예를 들어 프리팹을 검증하거나 커스텀 에디터를 통해 입력한 데이터를 검증하는 것은 콘텐츠 제작자에게 쉽게 제공되어야 합니다. 그들이 에디터에서 버튼을 클릭하고 빠른 검증을 받을 수 있다면, 곧 이것이 시간을 절약한다는 것을 인식하게 될 것입니다.

이 다음 단계는 유니티 테스트 러너를 설정하여 정기적으로 자동으로 테스트를 다시 수행하는 것입니다. 이때 Unity 테스트 러너를 빌드 시스템의 일부로 설정해 모든 테스트를 실행하도록 하세요. 좋은 방법은 알림을 설정하여 문제가 발생할 때 팀원들이 슬랙 또는 이메일 알림을 받도록 하는 것입니다.

자동화된 게임 플레이 만들기

자동화된 플레이스루는 당신의 게임을 플레이할 수 있는 AI를 만들고 오류를 기록하는 것을 포함합니다. 간단히 말해, 당신의 AI가 찾는 모든 오류는 당신이 찾는 데 시간을 덜 소비해야 한다는 것입니다!

우리의 경우, 우리는 같은 기계에서 약 10개의 게임 클라이언트를 설정하고 가장 낮은 세부 설정으로 모두 실행했습니다. 충돌을 확인한 후에 오류 기록을 보았습니다. 클라이언트 중 하나가 충돌할 때마다 버그를 찾기 위해 직접 게임을 하거나 QA팀을 배정하지 않아도 되므로 시간을 절약할 수 있었습니다. 그것은 우리가 실제로 게임을 테스트할 때 다른 플레이어와 함께 게임이 재미있는지, 시각적 결함이 어디에 있는지 등에 집중할 수 있음을 의미했습니다.