Unity 프로덕션 패턴: 제네릭과의 일관된 연결하는 방법
더 나은 솔루션을 제공하는 결함 있는 접근 방식 살펴보기

Unity로 개발하는 동안 두 가지 이상의 유형의 자식 간에 일대일 관계를 유지하려는 상황이 발생하는 것은 드문 일이 아닙니다. 이것은 많은 응용 프로그램에서 매우 일반적인 상황입니다.
예를 들어, 모든 카드가 괴물을 소환하는 카드 게임에서 모든 유형의 카드는 특정 유형의 괴물과 연관될 수 있습니다. 예를 들어 우리가 게임을 할 때마다 DragonCard
드래곤을 소환합니다.
모든 유형의 첫 번째 유형에 대해 자식 클래스를 구현한다고 가정합니다(예: Card
) 및 두 번째 유형의 모든 유형에 대한 하위 클래스(예: Monster
), 명시적으로 연결하는 방법과 강력한 설정과 깨끗하고 디버그 가능하며 확장 가능한 프로덕션 코드를 만드는 데 유용할 수 있는 방법을 배울 것입니다.
더 간단한 접근 방식의 변형으로 시작하여 이 패턴이 구현을 정리하는 데 도움이 되는 이유를 살펴보겠습니다.
다음과 같이 가정합니다. Enemy
유형은 다음과 연결됩니다. EnemyAnimator
참조.
내가 많이 본 일반적인 접근 방식은 필수 EnemyAnimator 유형에 해당하는 Enemy 클래스의 모든 자식에 대해 직렬화된 필드를 갖는 것입니다. (때로는 기본 클래스가 전혀 없으며 모든 어린이는 완전히 고유하게 작동합니다)
이게 왜 나쁜거야?
이 구조가 단기적으로는 좋아 보이지만 실제로는 장기적으로 생산 속도를 늦출 수 있는 여러 가지 이유가 있습니다.
우선, 당신은 어떤 규칙도 설정하지 않습니다. 따라서 다른 사람과 함께 작업할 때(미래에서 온 자신을 포함하여)..그들은 새로운 적 유형을 추가하고 싶지만 원하는 아키텍처에 대해 알지 못하거나 완전히 잊어버릴 수 있습니다. 따라서 EnemyAnimator에서 상속하지 않는 새 애니메이션 클래스를 만들 수 있습니다. 이 많이 일어난다 구조를 설정하지 않을 때.
이로 인해 훨씬 더 많은 비보편적 버그가 발생하고 코드를 디버그 및 추적하기가 더 어려워지며 이해하거나 확장하기가 더 어려워집니다.
당신은 또한 상속을 잘 활용하지 않습니다. Enemy 참조의 애니메이터에 액세스할 수 있다면 자식 클래스에서 반복되는 코드를 저장하는 훨씬 더 일반적인 기본 클래스 논리를 가질 수 있습니다.
그러나 또한 특정 작업을 수행할 때 모든 EnemyAnimator를 즉시 중지하고 재설정해야 한다고 갑자기 결정하면 어떻게 될까요?
이 작업이 수행되는 또 다른 방법은 기본 클래스에서 보호된 EnemyAnimator를 사용하는 것입니다.
이제 클래스의 모든 자식 Enemy
말하다 EnemyGoomba
가질 것이다 EnemyAnimator
인스펙터를 통해 설정할 수 있는 참조를 다음으로 캐스팅할 수 있습니다. EnemyAnimatorGoomba
.
이것은 실제로 훨씬 낫습니다. 하지만 다시 말하지만, 모든 자식에 참조를 캐스팅할 필요는 없습니다.
하지만 내 경험에서 가장 큰 문제는 이제 다음을 할당할 수 있다는 것입니다. EnemyAnimatorGoomba
에게 EnemyKoopa
. 게임에 많은 적 유형이 있고 특히 조립식 설정을 만드는 다른 사람들과 함께 작업하는 경우 이러한 설정을 가능한 한 명확하게 해야 합니다. 그리고 어떤 복용 EnemyAnimator
참조가 너무 느슨합니다. 다른 사람이 볼 때 EnemyAnimator
, 설정하는 동안 어떤 스크립트를 사용해야 하는지 알려주지 않습니다. 설정에서 혼란과 사고를 줄이는 것은 항상 가치가 있습니다.
명시적 연관을 확인하는 것은 매우 간단합니다.
간단히 말해 클래스 제네릭을 사용할 수 있습니다. 즉, 새로운 enemy
유형, 우리는 상속받은 클래스를 제공해야 합니다. EnemyAnimator
그리고 다음에서 상속받는 또 다른 EnemyConfig
(세 가지 유형 간의 연결을 만드는 예).
상속받는 것이 무의미해 보일 수 있습니다. Enemy<AT,CT>
일반적이지 않은 기본 클래스 Enemy에서 가져온 것이지만, 예를 들어 어딘가에 Enemies 배열을 갖고 싶을 때 유용하게 될 것입니다.
그리고 그게 다야. 우리의 EnemyGoomba
클래스는 이제 다음과 같이 보일 수 있습니다.
더 적은 코드, 더 많은 설정 일관성 및 일반 논리 작성 기능. 그것이 좋은 건축에 대한 보상입니다.
이것은 더 높은 일관성을 위해 언급된 패턴과 결합될 수 있는 유용하다고 생각하는 또 다른 패턴입니다.
Unity로 작업할 때 해결해야 하는 매우 일반적인 아키텍처 문제는 다음과 같습니다. 공통 참조를 전달하려면 어떻게 해야 합니까?
예를 들어 컷신을 재생하는 동안 컷신이 카메라, 시각 처리 클래스, 오디오 관리자 및 플레이어에 액세스할 수 있기를 원합니다.
이러한 참조를 할당할 수 있는 두 가지 일반적인 방법이 있습니다.
- 검사 배정 — 순진한 접근 방식은 인스펙터에서 이러한 공통 참조를 필요로 하는 모든 스크립트에 할당하는 것입니다. 이것은 때때로 유효한 접근 방식이지만 일반적으로 프로덕션 또는 더 큰 프로젝트에서는 나쁜 생각입니다.
많은 경우에 동일한 참조를 너무 많이 할당하기 때문입니다. 예를 들어 장면을 설정하는 데 걸리는 시간이 늘어나고 오류가 발생할 가능성이 높아집니다. 그러나 그것은 또한 매우 불필요합니다. - 참조 잡기 — 여기에는 때때로 사용하는 것이 포함됩니다.
GetComponent
또는GameObject.Find()
. 특히 모바일에서 많은 성능 오버헤드를 추가할 수 있습니다. 그러나 이를 수행하는 일반적인 방법은 공통 컨트롤러 클래스를 싱글톤으로 사용하는 것입니다. 이것은 많은 경우에 대체로 신뢰할 수 있고 매우 현실적입니다.
일부 시나리오에서 매우 적합할 수 있는 세 번째 방법은 매개변수와 제네릭을 사용하여 이러한 참조를 전달하여 스크립트에 필요한 정확한 참조를 제공하는 것입니다.
이것은 진입점이 일종의 최상위 게임 시스템을 초기화한 다음 매개변수를 사용하여 다른 기능을 초기화하는 계층에서만 작동할 수 있습니다.
참고: 이것은 모든 경우에 최선의 아이디어는 아닙니다.
- 규칙을 설정하면 일관성이 생깁니다.
- 관련 클래스를 함께 연결하면 관련 기능을 구현, 디버그 또는 설정해야 하는 수고가 명시적으로 줄어듭니다.
- 이와 같은 패턴은 작업 흐름을 더 잘 계획하는 데 도움이 되는 도구일 뿐입니다.
'Coding' 카테고리의 다른 글
이더리움 다크 포레스트에서 살아남는 방법 (0) | 2022.04.17 |
---|---|
Pandas 데이터 프레임을 Snowflake로 업데이트하는 방법 (0) | 2022.04.16 |
Context-less Go — 쉽게 HTTP 서비스 작성하는 방법 (0) | 2022.04.14 |
Parcel을 사용하여 Phaser 3 게임 묶는 방법 (0) | 2022.04.13 |
프로덕션 전 대량 테스트 API - Azure Durable Functions가 포함된 Azure DevOps 릴리스 게이트하는 방법 (0) | 2022.04.12 |
댓글