Unity가 리플렉션을 사용하여 업데이트 방법을 얻는 이유는 무엇입니까?


12

왜 액세스하기 위해 유니티 사용의 반사를 수행 MonoBehaviour같은 메시지 방법 Awake, Update, Start, ...?

반사를 사용하는 것이 느리지 않습니까? 왜 다른 접근 방식을 활용하지 Template Method않습니까? MonoBehaviour기본 클래스 에서 메소드를 추상으로 정의 하고 서브 클래스가 강제로 구현하도록 할 수 있습니다.

답변:


20

그렇지 않습니다

업데이트 호출 방법

아니요, Unity는 System.Reflection을 사용하여 호출 할 때마다 마법 메서드를 찾지 않습니다.

대신, 주어진 유형의 MonoBehaviour에 처음 액세스 할 때 스크립트 방법 (Mono 또는 IL2CPP)을 통해 기본 스크립트를 검사하여 매직 메소드가 정의되어 있고이 정보가 캐시되는지 여부를 검사합니다. MonoBehaviour에 특정 메소드가있는 경우 적절한 메소드에 추가됩니다. 예를 들어 스크립트에 Update 메소드가 정의되어 있으면 매 프레임마다 업데이트해야하는 스크립트리스트에 추가됩니다.

게임 중에 Unity는 이러한 목록을 반복하고 간단한 목록에서 메소드를 실행합니다. 또한 이것이 Update 메소드가 공용인지 개인용인지 중요하지 않은 이유입니다.

이 방법으로 수행 되는 이유대해서는 DMGregory의 답변 을 크게 참조 할 것입니다.이 두 가지 경쟁 항목의 균형으로 요약됩니다.

  1. 성능 최적화
  2. 새로운 개발자 활용의 용이성

새로운 개발자는 그냥 작동하기를 원하고 "이벤트 시스템에 어떻게 연결합니까?"를 알아 내고 싶지 않습니다. 그러나 최소한의 오버 헤드로 여전히 빠르게 실행됩니다.

이 두 가지 제약 조건에서 달성 할 수있는 최상의 솔루션 일 것입니다 . 또는 적어도 Unity 개발자 팀이 그 당시에 생각해 낸 최고의 능력. 우리는 알지 못할 수도 있습니다.


2
tl; dr 동일한 프로세스, 다른 빠른 API. 그러나 OP의 요청에 따라 다른 방법을 선택하지 않은 이유는 무엇입니까?
wondra

10
우리는 평범한 오래된 "나쁜 디자인"이유의 가능성을 부정해서는 안됩니다. C # 소스 코드 가 릴리스 된 후 사용자는 수많은 실수와 설명 할 수없는 디자인 결정을 발견했습니다 . 일부 게임 개발자들은 마침내 몇 년 동안 싸우던 예기치 않은 행동을 이해할 수있었습니다.
Exerion

이를 제외한 기술은 초보자가 처음 배우는 것 중 하나이므로 쉽게 추가하거나 건너 뛸 수 있어야합니다.
Nikaas

6
이 디자인에 대한 역사적인 이유가있을 수도 있습니다. 유니티는 자체 스크립팅 언어로 시작하여 점차 C #에 유리하게 단계적으로 폐지했습니다. 그들이 속임수를 쓰려고하더라도 동일한 패턴을 계속 사용하고 싶었던 것은 당연합니다.
Philipp

3
"유니티가 무엇을 통해 달성 하는가"와 같은 유용한 답변을 얻을 수 있다고 생각합니다. 모두 구현해야하는 추상 공개 메소드 모음보다 장점이 있습니다. "Unity 개발자들은 어떻게 생각하고 있었습니까?"라고 대답 할 수 없습니다. "이 접근 방식이 엔진 사용자에게 유용한 이유는 무엇입니까?"
DMGregory

10

MonoBehaviour 기본 클래스에서 메소드를 추상으로 정의하고 서브 클래스가 강제로 구현하도록 할 수 있습니다.

Unity가 사용하는 시스템의 장점 중 하나는 모든 MonoBehaviour 메시지를 구현할 필요가 없으며 60 개가 넘는 메시지 가 있습니다 .

일반적으로 이러한 방법 중 하나 또는 소수만 필요합니다. 일부는 카메라 또는 파티클 시스템에 고유 한 2D / 3D 물리에 고유하기 때문에 스크립트 하나에 모두 필요한 것은 거의 없습니다.

필요하지 않은 메시지를 구현되지 않은 상태로두면 런타임에 "이 객체에서 OnCollisionStay2D를 호출하는 것을 귀찮게하지 않아도됩니다"라는 신호를 명확하게 알릴 수 있습니다.

이것은 실질적인 효율성 승리 일 수 있습니다. 이제 엔진은 모든 장면을 구성하거나 물리 이벤트에만 반응하는 ~ 200 개의 오브젝트가 아니라 내 프레임에서 ~ 20 개의 오브젝트에만 커스텀 업데이트 로직이 필요한 오브젝트에서만 Update를 호출하도록리스트를 필터링 할 수 있습니다.


한가지 질문은 ... 개인적으로 아는 한, Update 메서드와 함께 스크립트를 사용하는 수천 개의 GameObject가 있다면 성능에 큰 영향을 미칩니다. 대안은 목록을 사용 하고 관리자 스크립트에서 하나의 Update 메소드 만 사용하여 목록을 반복 하는 것입니다. 여전히 그렇습니까, 아니면 이미 변경 되었습니까? -아무것도 변경되지 않으면 Unity의 수행 방식이 성능과 관련하여 최적의 위치에 있지 않다는 것을 의미합니다.
Battle

4
@ 당신이 묘사 한 것은 2015 년 Draco18s가 인용 한 링크와 일치하며 여전히 사실이라고 생각합니다. 수천 개의 개체에 대해 Update 메서드를 정의하지 않은 상태로두면이 최적화가 제대로 작동합니다. 모든 MonoBehaviour가 내가 인용 한 질문의 섹션에 설명 된대로 추상 기본 클래스를 통해 정의 된 Update 메소드를 가지고 있다면, 업데이트 호출을 관리자의 목록 반복으로 제한 할 수는 없습니다. 이 Q & A는 "Unity의 접근 방식이 최적입니까?"를 다루지 않습니다. 그러나 현재의 접근 방식이 어떻게 이익이 될 수 있는가.
DMGregory

아, 알겠습니다. 답변 해주셔서 감사합니다!
전투

@Battle 그것은 여전히 ​​사실입니다. 유니티가하는 대안은 다른 대안보다 성능이 뛰어나지 만 일반 함수 호출보다 여전히 오버 헤드가 많습니다.
Draco18s는 더 이상

@ Draco18s-예. 오래 전에 그 최적화를 담당하는 프로젝트에 이미 UpdateManager를 구현했습니다. 나는 그것이 여전히 필요 / 유용하다는 확인을 원했습니다.
Battle
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.