OBJECT POOLING in Unity

이 비디오에서는 많은 프로세서 성능없이 대량 생산하는 방법을 배웁니다 우리는 객체 풀 기술을 사용하여 우리는 즉시 그것을 알게되고 그것이 왜 효과가 있는지 이해할 것입니다

하지만 그 전에는 Skillshare가 후원했습니다 Skillshare는 18,000 개가 넘는 고급 기술 설계 과정을 갖춘 온라인 학습 커뮤니티입니다 그것은 실제로 내 개인적인 좋아하는 및 사용합니다 나는 최근에 게임을위한 픽셀 아트 기초를 만드는이 좋은 코스를 만났다 한 달에 $ 10 미만의 비용으로 모든 과정을 제한없이 볼 수 있도록 우수한 회원을 구입하는 것이 좋습니다

아래에 설명 된 링크를 클릭하기 만하면 상위 500 위는 99 센트 만에 처음 2 개월 동안 자격을 얻게됩니다 이 자습서에 들어가 봅시다 게임을 만들 때 종종 런타임에 객체를 생성해야합니다 물론 Unity는 내장 메소드 Instantiate를 가지고 있지만,이 방법을 사용하는 것은 어떤 상황에서는 그리 효율적이지 않습니다 객체 풀을 사용하는 것이 더 나은 경우가 있습니다

간단히 말해서, 게임이 시작될 때 우리는 일부 비활성 게임 객체를 생성합니다 즉, 우리는 개체를 직접 인스턴스화하는 대신 개체를 생성해야 할 때 풀에서 가져온 개체 풀을 만듭니다 우리는 단순히 수영장에서 물건을 가져 와서 사용 가능하도록하고 올바른 장소에 놓습니다 풀의 객체가 부족하면 모든 객체를 확장하거나 다시 사용할 수 있습니다 아무런 유익이 없다고 말하면서, 화합에 나서서 깨달으십시오

Unity에서는 매우 간단한 장면을 설정했습니다 1 개의 빛과 약간의 후 처리 효과를 가진 단 하나의지면과 빛 실행하면 블록 제작자를 설정했음을 알 수 있습니다 정사각형 객체를 많이 생성합니다 그게 전부 야 더 많은 사각형을 생성하고 천천히 계층을 채 웁니다

Unity가 충돌 할 때까지 계속됩니다 그것이 어떻게 작동하는지 보러 간다면 실제로는 매우 간단합니다 CubeSpawner 스크립트가있는 객체를 생성하는 상자가 있습니다 스크립트는 각 FixedUpdate에서 블록을 인스턴스화합니다 이 블록 개체는 큐브 스크립트에 연결된 강체입니다

모든 스크립트는 임의의 힘을 계산 한 다음 강체에 작용합니다 좋은 예입니다 개체 풀을 추가하여 더 효율적으로 만들 수 있습니다 그러나 스크립트를 작성하기 전에 이해해야 할 사항이 몇 가지 있습니다 우리는 서로 다른 개체 풀을 생성하는 방법을 이해해야합니다

여기 우리는 세 개의 풀, 1, 2, 3을 가지고 있습니다 각 풀이 특정 유형의 객체를 저장하는 역할을하도록합니다 어쩌면 첫 번째 것이 둥글고 두 번째 네모 이 아이디어를 이해하면 가장 좋은 방법은 사전 (사전)을 사용하는 것입니다 Dictionary는 우리가 원하는 풀을 만들 수있게 해주기 때문에 각 풀은 다른 태그로 구분됩니다 우리의 경우에는 매우 간단합니다

첫 번째 풀을 원과 결합 할 수 있습니다 두 번째는 사각형과 결합하고, 세 번째는 두 번째와 결합합니다 xx 우리는 태그를 통해 풀에서 풀을 검색 할 수 있습니다 상자를 검색하려면 여기에 입력하십시오 그것은 우리에게 사각형의 풀을 줄 것이고, 그런 다음 큐를 통해이 객체들을 저장할 것입니다

Queue를 사용하는 이점은 그것이 List와 매우 흡사하다는 것입니다 그러나 첫 번째 객체를 매우 빨리 가져옵니다 Queue의 꼬리에 새 객체를 추가하기 만하면됩니다 이것이 왜 유용한 지 상상할 수 있습니다 왜냐하면 우리가 객체를 계속 생산하기를 원한다면 우리는 단순히 Qeueu 머리에서 선택하고 우리의 세계에 넣어 수 있습니다

수영장이 비게 될 때까지 항상이 작업을 수행 할 수 있습니다 이 예제에서 대기열 사용에 관한 영리한 점은 모든 객체가 활성 상태 인 경우 우리는 여전히 대기열에서 첫 번째 것을 계속 얻을 수 있습니다 이것은 처음에 찍은 대상입니다 따라서 풀에서 세계로 이동할 때마다 대기열에 추가합니다 새 객체를 추가하려면 우리는이 가장 오래된 물건 만 가져 가면됩니다

해당 위치에서 새 위치로 이동하십시오 우리는 항상 이것을 할 수있다 이제 사전과 대기열이 어떻게 사용되는지 잘 이해하게되었습니다 이제 스크립트 작성을 시작하겠습니다 이렇게하려면 계층 구조에 빈 개체를 새로 만들어야합니다

오브젝트 풀 (Object Pool)이라고 불리는 변형 (Transform)을 다시 설정해 보겠습니다 우리는 그것을 볼 수 있도록 그것을 위로 끕니다 구성 요소를 추가하고 object pool이라는 새 스크립트를 만듭니다 그런 다음 두 번 클릭하고 Visual Studio에서 엽니 다 Update 메서드를 제거합니다

우리는 그것을 사용하지 않을 것이다 그런 다음 사전으로 가기 위해 위로 이동합니다 우리는 사전에 두 가지 유형이있는 공개 사전을 작성합니다 첫 번째 것은 각 풀과 연결하려는 태그입니다 이것을 키라고도합니다

이것은 문자열 유형입니다 둘째, 우리는 실제 풀에 대기열로 저장하려고 함을 기억해야합니다 여기에 대기열을 만듭니다 대기열을 만들 때 우리가 대기열에 저장하려는 것을 단일 화해야합니다 게임 개체 큐를 저장하려고합니다

이 사전을 poolDictionary라고 부릅니다 사전과 대기열을 사용할 때마다 SystemCollectionsGeneric 네임 스페이스를 사용해야합니다

이제 Start 메소드에서 PoolDictionary를 새 사전과 동일하게 설정할 수 있습니다 여기서 자동 완성을 사용하여 모든 유형을 채울 수 있습니다 이제 우리는 새로운 빈 사전을 가지고 있습니다 이제 개체 풀에서 개체를 채울 차례입니다 하지만 수동 코드가 아닙니다

관리자 내부에서 원하는 풀을 구성 할 수있는 방법을 찾아 보겠습니다 이렇게하려면 여기로 이동하여 Pool이라는 클래스를 만듭니다 우리는 public 클래스를 생성 할 것이고, 우리는 그것을 Pool이라고 부릅니다 이제 우리는 각 수영장에 저장할 것을 선택합니다 먼저 문자열을이 풀의 태그로 사용합니다

그런 다음이 풀에있는 개체의 미리 설정을 저장하는 공용 게임 개체가 있습니다 마지막으로 풀의 전체 크기를 저장하는 공용 int 유형이 있습니다 즉, 새 객체를 생성하는 대신 객체를 다시 사용하기 시작합니다 검사기에 나타나는지 확인하십시오 System

serializable이라는 속성으로 표시해야합니다 이제이 클래스를 만들었습니다 계속해서 목록을 만들자 pools라는 공개 풀 목록을 만들자 우리가 지금 저장하면 Unity로 돌아갑니다

이제 풀 목록을 볼 수 있습니다 항목을 계속 추가 할 수 있습니다 나는 하나만 추가한다 이제 첫 번째 요소에 대해 레이블을 정의 할 수 있습니다 나는 이것을 큐브로 표시했다

난 조립식을 끌어 야해 여기가 크기이고 150으로 설정하고 싶습니다 따라서 한 번에 최대 150 개의 활성 큐브 만 가질 수 있습니다 이제 풀 목록이 생겼어 사전에 추가해야합니다

이렇게하려면 모든 풀을 반복해야합니다 foreach를 사용하여 풀 목록의 각 풀을 호출합니다 객체 큐를 생성하기 위해 여기에 게임 객체의 큐를 생성하고자합니다 우리는 그것을 객체 풀 (object pool)로 명명했고, 그것을 새로운 게임 객체 큐로 설정했습니다 이제 각 객체를 탐색하고 만들어야합니다 우리는 여기에 또 다른 루프를 만들고 있습니다

여기서 우리는 poolsize보다 작 으면 루프를 유지하려고합니다 즉, 우리는 모든 객체를 인스턴스화하여 풀 전체를 채우고 싶습니다 이제 각각의 팻 – 온 (pre-on) 프리셋이 인스턴스화 될 것입니다 방금 만든 게임 개체에 대한 참조를 저장합니다

우리는 이것을 객체라고 부릅니다 이제 SetActive 객체를 False로 설정하여 비활성화되도록 선택할 수 있습니다 그래서 우리는 여전히 그것을 볼 수 없습니다 마지막으로 큐의 끝에 추가 할 수 있습니다 이렇게하려면 객체 풀 지점과 대기열을 작성하기 만하면됩니다

그런 다음 객체를 입력합니다 이것은 우리가 만들고자하는 객체의 풀입니다 객체로 가득 찬 대기열을 만들고 대기열에있는 모든 객체를 추가해야합니다 마지막으로이 풀을 사전에 추가하려고합니다 그래서 우리는 풀 사전에 있습니다

추가 여기서는 먼저 레이블을 지정해야하므로 pooltag 그런 다음 객체 풀이 있으므로 objectPool 아주 좋아 이제 우리는 이것을 저장하면 Unity로 가서 재생을 클릭해야합니다 계층 구조에서 사용할 수없는 150 개의 큐브가 즉시 생성됩니다 이것들은 확실히 지금 우리가 보는 큐브가 아닙니다

그것들은 CubeSpawner에 의해 맨 위에 추가됩니다 그러나 곧 바뀔 것입니다 먼저 이러한 InActive 큐브를 가져와 Active world에 생성 할 수있는 기능을 추가해야합니다 이를 위해 우리는 새로운 public void 메쏘드를 생성하고 SpawnFromPool 첫 번째는 레이블이있는 문자열입니다 물론 레이블은 파생하려는 객체의 레이블입니다

또한 Vector3를 사용하여 위치를 저장하려고합니다 이것은 우리가 객체와 회전의 쿼터니언을 도출하기를 원하는 곳입니다 이제 우리는 간단한 풀 사전을 통해 생성하고자하는 프리셋을 얻을 수 있습니다 상자 예제에서 보여 주듯이 레이블에 지정하십시오 이것은 올바른 큐브를 얻습니다

그럼 우리가해야 할 일은 대기열의 첫 번째 요소를 가져 오는 것입니다 그런 다음이 객체를 저장 한 다음 게임 객체를 만듭니다 objectToSpawn의 이름을 지정하고 해당 객체에 할당합니다 이제 개체를 Spawn으로 구성 할 수 있습니다 활성으로 설정할 수 있습니다

위치를 설정할 수도 있습니다 objectToSpawntransformposition = position objectToSpawntransform

rotation = rotation 이제 우리는 생성하고자하는 객체를 가져 왔습니다 활성으로 설정하고 세계의 적절한 장소로 이동하십시오 그래서 그것은 잘 나타나야하고 잘 작동해야합니다 그러나 우리는 또한 그것을 우리 큐에 추가해야한다는 것을 기억해야합니다 나중에 다시 사용할 수 있도록 우리는 사전에 간다

레이블을 Enqueue로 전달해야합니다 생성 할 객체를 지정합니다 더 안전하고 간단하게하기 위해 여기에 추가 할 수있는 것들이 몇 가지 있습니다 그 중 하나를 사용하려면 여기에서 확인할 수 있습니다

전체 사전 점에 키가 포함되어있는 경우, 이는 풀이없는 레이블을 우리가 확인하면 오류를 확인하지 않을 것입니다 이것이 사실이 아니라면, 우리는 계속 될 것입니다 태그가있는 풀을 나타내는 DebugLogWarning 그런 다음 존재하지 않는 태그를 입력합니다 그런 다음 함수에서 인스턴스화 된 객체를 반환 할 수 있습니다

좋은 기능을 가지고 자주 사용합니다 객체를 인스턴스화하면 방금 만든 객체가 반환됩니다 우리는 여기서 같은 것을하고 있습니다 우리는 리턴 타입을 GameObject로 표시 할 것입니다 이 함수의 끝에서 우리는 생성 될 객체를 반환 할 것이다

이제 우리는 생성 된 장소에서 그것을 얻을 수 있습니다 여기서 우리는 단지 null을 반환하고자합니다 여기에는 객체가 없으므로 실제로 객체 풀 스크립트의 주요 기능을 완료해야합니다 그러나 큐브 생성기에서 쉽게 액세스 할 수있는 방법이 필요합니다 이를 위해 우리는 매우 간단한 싱글 톤 패턴을 사용할 것입니다

이것은 진정한 싱글턴이 아닙니다 이전에 싱글 톤 모델에 대해 들어 본 적이없는 경우이 방법은 빠른 솔루션입니다 또는 더 알고 싶다면 설명에 링크가 있는지 확인하겠습니다 여기서 우리가하는 일은 단순히 입방체의 산란관에있는 물체의 풀을 잡는 것입니다 인스턴스라고 부르는 public static 객체 풀을 작성하고 싶습니다

그런 다음 Awake 메소드를 작성합니다 여기서 인스턴스 할당을 간단히이 값으로 설정합니다 모든 사람이 이것이 시도라는 것을 알기 위해서는 여기에 싱글 톤을 쓰십시오 우리는이 지역을 여기에서 끝낼 것입니다 그것은 아무것도하지 않으며, 우리는 이처럼 코드를 접을 수 있습니다

우리는 더 이상 그것을 보지 않아도됩니다 이제 큐브 생성기에 들어가면 그래서 우리는이 변수를 삭제할 수 있습니다 Instantiate 호출을 삭제하려면 객체 풀을 사용하여 객체를 인스턴스화 할 수 있습니다 이제 여기서 함수를 호출 할 수 있습니다 풀에서 스폰를 호출하고 레이블을 추가합니다

우리는 그것을 포지션이라고 부르기 위해 큐브 라벨을 사용할 것입니다 변환 된 위치와 회전을 사용합니다 나처럼 그것을 부르고 싶다면 변수에 저장하는 것이 좋습니다 우리는 그것을 빨리 할 수 ​​있습니다 우리는 객체 풀 (object pool)이라는 객체 풀을 생성 할 것입니다

그런 다음 Start 메소드에서 객체 풀 싱글 톤을 할당 할 수 있습니다 이제 간단하게 여기에서 인용 할 수 있습니다 이것은 조금 더 효율적입니다 이제 이것을 저장하면 Unity로 가서 재생을 클릭하십시오 우리는 150 큐브를 생성 한 후에 멈추는 것을보아야합니다

그러나 실제로 멈추지 않았습니다 아직 큐브를 재사용하고 있지만, 어떤 이유로 그들은 실제로 움직이지 않습니다 그들은 모두 함께 쌓여 있습니다 그 이유는 큐브 스크립트가 현재 Start 메서드에서 한 번만 적용되도록 설정되어 있기 때문입니다 개체가 인스턴스화 될 때 Start 메서드가 한 번만 호출됩니다

그래서 우리는 객체가 재사용되었다는 것을 알려주는 방법을 만들어야합니다 다른 말로하면, 우리는 우리 자신의 Start 메소드를 생성하고 우리가 인터페이스라고 부르는 것을 사용할 필요가 있습니다 이것은 매우 간단한 메소드입니다 이제 프로젝트에 들어가면 C # 스크립트를 계속 만들 수 있습니다 이 인터페이스 때문입니다

먼저 I에서 인터페이스를 확인해 봅시다 그럼 내가 IPool 개체라는 우리는 Visual Studio에서 엽니 다 이것이 Monobehavior로부터 상속 받기를 원하지 않습니다 이 두 가지 기능을 제거하고 싶습니다 기본적으로 모든 네임 스페이스를 삭제할 수 있습니다

클래스가되기를 원하지 않습니다 우리는 그것이 인터페이스가되기를 원한다 이제 기본적으로 인터페이스는 일부 유형과 함수를 지정할 수있게 해 주며이 인터페이스에서 파생 된 모든 객체를 구현해야합니다 여기서는 void OnObjectSpawn 메서드를 작성할 수 있습니다 그런 다음 이걸 닫으십시오

이것은 우리가 인터페이스에 작성해야 할 것입니다 우리가 지금 그것을 저장하고 우리의 큐브 스크립트에 들어가면 우리는 큐브가 MonoBehavior에서 상속 받도록하고 싶습니다 다음 쉼표, 더하기 인터페이스 이제 빨간색임을 알 수 있습니다 그 이유는이 클래스가 인터페이스를 상속하기 때문입니다

그러나 해당 메서드를 구현하지 않습니다 그래서 우리는 여기에 들어가야합니다 시작을 사용하는 대신 OnObjectSpawn을 사용하려고합니다 나는 또한 공개로 표시하고 싶다 더 이상 빨간색으로 강조 표시되지 않습니다

이제이 함수를 구현 중이므로이를 저장하면됩니다 개체 풀 입력 우리가 실제로 풀에서 객체를 생성하는 곳 이제 인터페이스 메소드에 대한 응답으로 인스턴스 객체의 구성 요소를 가져올 수 있습니다 예, 인터페이스 구성 요소를 검색 할 수 있습니다 우리는 그것을 변수에 할당합니다 모든 개체가 인터페이스에서 상속되지는 않습니다

선택 사항입니다 그래서 우리는 여기에서 판단한다 이 인터페이스에서 함수를 호출 할 수 있습니다 우리는 변명의 방법을 확실히 원합니다 따라서 이것은 인터페이스 검색입니다

그것이 0이 아닌지 확인하십시오 이 메소드의 구현을 찾아내는 액세스 인터페이스를 입력합니다 그런 다음 큐브 내부의 모든 코드를 호출하고 실행합니다 이제 이것을 저장하면 Unity로 가서 재생을 클릭하십시오 큐브가 현재 올바르게 재활용되고 있음을 알 수 있습니다

Ouye ! @ # $ % ^ & * 여러 개의 풀을 쉽게 입력하고 추가 할 수 있습니다 우리는 이곳을 300으로 증가 시키려고 노력할 수 있습니다

또한 결과를 살펴보십시오 물론이 객체 풀의 성능을 향상시킬 수 있습니다 한 가지해야 할 일은 GetComponent 호출을 제거하는 것입니다 그러니 그걸 가지고 놀아야 만합니다 지역 사회의 멋진 남자가 저에게 대본을 보냈습니다

github에서 확인할 수 있습니다 또는 자산 저장소를 빠르게 검색하고이 플러그인을 찾을 수 있습니다 현재 무료이며 필요한 대부분의 기능이있는 것 같습니다 물론 설명에 링크가 있습니다 이 섹션은 여기에 있습니다

Skillshare를 확인하고 설명의 링크를 클릭하면 할인을받을 수 있습니다 보고 주셔서 감사합니다 다음 비디오를보십시오 1 월에 기부 한 모든 애호가 지지자들 덕분에