[Unity3D] 객체 미리 생성 후 재활용 - Memory pool [Part 0]
※ 주의
이 글은 아마추어가 개인적으로 생각하여 작성하는 것으로, 이곳에 나오는 내용을 맹신하지 않는것을 당부드립니다.
Menu
0. 미리보기
1. 오브젝트를 미리 생성.
- 프리팹 제작.
- 싱글톤 제작.
- 오브젝트를 생성시킬 함수 제작.
- 오브젝트를 찾을 함수를 제작.
2. 만들어진 오브젝트 활용하기.
0. 미리보기
메모리 풀을 활용하여 만든 오브젝트는 총알이며, 활성화 및 비활성화를 통한 오브젝트 재활용을 실시할 것이다.
※ 메모리 풀을 사용하는 이유
많은 양의 객체들을 실시간으로 생성하고, 삭제하면 메모리가 빠르게 고갈되면서
쌓인 가비지로인해 가비지 컬렉터가 호출되고, 가비지를 처리하는 과정에서 버벅거리는 현상이 발생한다.
이러한 현상을 방지하기 위해서 메모리 풀 시스템을 활용하는 것이 좋다.
'Unity3D > Project' 카테고리의 다른 글
[Unity3D] 객체 미리 생성 후 재활용 - Memory pool [Part 2] (0) | 2017.03.21 |
---|---|
[Unity3D] 객체 미리 생성 후 재활용 - Memory pool [Part 1] (0) | 2017.03.20 |
[Unity3D] UI - HP, MP 에너바 조절하기. [Part 2] (1) | 2017.03.17 |
[Unity3D] UI - HP, MP 에너바 조절하기. [Part 1] (1) | 2017.03.16 |
[Unity3D] UI - HP, MP 에너바 조절하기. [Part 0] (0) | 2017.03.15 |
[Unity3D] UI - HP, MP 에너바 조절하기. [Part 2]
※ 주의
이 글은 아마추어가 개인적으로 생각하여 작성하는 것으로, 이곳에 나오는 내용을 맹신하지 않는것을 당부드립니다.
Menu
0. 미리보기
1. HP,MP껍데기 및 기능 만들기.
2. HP,MP 조절을 위한 데미지, 리커버리 만들기.
2. HP,MP 조절을 위한 데미지, 리커버리 만들기.
에셋 스토어에서 무료 파티클을 받아서 하이러키창에 배치하자.
하나는 데미지 또 하나는 리커버리라고 명명하면 된다.
왼쪽이 데미지, 오른쪽이 리커버리 파티클이다.
두개의 오브젝트에 Rigidbody와 BoxColider를 부착하자.
※ 파티클 오브젝트 인스펙터창 정보.
각각에 오브젝트에 일어난 충돌들을 체크하여 플레이어에게 적용할 것이다.
충돌이 일어났을 때 플레이어가 가진 정보를 가져와서 그 정보를 이용하여 HP,MP에 영향을 준다.
충돌을 체크하는 방법에는 2가지가 있다.
OnCollision( 물리현상 O ) | OnTrigger( 물리현상 X ) | ||
OnCollisionEnter() | - 처음 한 번 충돌 시 한 번 호출. - 다시 호출 하려면 충돌 영역을 벗어난 뒤에 다시 부딪히면 된다. | OnTriggerEnter() | 기능은 같다. |
OnCollisionStay() | - 충돌 영역에 존재하는동안 게속 하여 호출한다. | OnTriggerStay() | 기능은 같다. |
OnCollisionExit() | - 충돌 영역에 들어온 후 그 영역을 벗어나면 호출된다. | OnTriggerExit() | 기능은 같다. |
OnCollision을 사용할 시에는 앞에 벽이 존재하는것처럼 충돌을 수행 하지만,
OnTrigger는 충돌만 체크할뿐 통과해 버린다.
이중 우리는 OnTrigger를 사용할 것이다.
OnTrigger를 사용하려면 각 오브젝트에 붙어있는 BoxCollider의 is Trigger를 체크해줘야 한다.
※ 충돌에 의한 움직임이나, 중력은 사용하지 않을 것이므로 Rigidbody에 Is Kinematic을 체크 하도록 하자.
각 기능이 다르기 때문에 2가지의 스크립트로 작성해 보도록 하자.
각각의 스크립트 이름은 Damage, Recover이다.
데미지 스크립트.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | using System.Collections; using System.Collections.Generic; using UnityEngine; public class Damage : MonoBehaviour { private PlayerInfo pInfo; // 플레이어의 스크립트가 저장될 변수. // 지속적으로 플레이어의 HP 감소. IEnumerator StartDamage() { while (true) { // 플레이어가 가지고 있는 UIUpdate호출. pInfo.UIUpdate("Damage", "HP", 0.1f); yield return null; } } // 충돌 했을 때. void OnTriggerEnter(Collider _Col) { if (_Col.transform.CompareTag("Player")) { // 플레이어의 스크립트 컴포넌트를 가져온다. pInfo = _Col.GetComponent<PlayerInfo>(); StartCoroutine("StartDamage"); } } // 충돌이 끝났을 때. void OnTriggerExit(Collider _Col) { if (_Col.transform.CompareTag("Player")) { // 코루틴을 멈춘다. StopCoroutine("StartDamage"); // 충돌이 끝난 후 정보를 플레이어의 정보를 게속 가지고 있을 필요가 // 없기 때문에 null로 초기화 해준다. pInfo = null; } } } | cs |
리커버리 스크립트.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | using System.Collections; using System.Collections.Generic; using UnityEngine; public class Recover : MonoBehaviour { private PlayerInfo pInfo; // 플레이어의 스크립트가 저장될 변수. // 지속적으로 플레이어의 HP회복. IEnumerator StartRecover() { while (true) { pInfo.UIUpdate("Recover", "HP", 0.1f); yield return null; } } // 충돌 했을 때. void OnTriggerEnter(Collider _Col) { if (_Col.transform.CompareTag("Player")) { pInfo = _Col.GetComponent<PlayerInfo>(); StartCoroutine("StartRecover"); } } // 충돌이 끝났을 때. void OnTriggerExit(Collider _Col) { if (_Col.transform.CompareTag("Player")) { // 코루틴을 멈춘다. StopCoroutine("StartRecover"); // 충돌이 끝난 후 정보를 플레이어의 정보를 게속 가지고 있을 필요가 // 없기 때문에 null로 초기화 해준다. pInfo = null; } } } | cs |
결과.
'Unity3D > Project' 카테고리의 다른 글
[Unity3D] 객체 미리 생성 후 재활용 - Memory pool [Part 1] (0) | 2017.03.20 |
---|---|
[Unity3D] 객체 미리 생성 후 재활용 - Memory pool [Part 0] (0) | 2017.03.20 |
[Unity3D] UI - HP, MP 에너바 조절하기. [Part 1] (1) | 2017.03.16 |
[Unity3D] UI - HP, MP 에너바 조절하기. [Part 0] (0) | 2017.03.15 |
[Unity3D] 조이스틱으로 캐릭터 조종하기. [Part 2] (10) | 2017.03.13 |
[Unity3D] 배칭 & 드로우콜
1. 드로우 콜(Draw Call)
- CPU가 GPU에게 어떠한 물체를 그리라고 요청하는 것.
- 드로우 콜의 개수가 적을수록 가벼운 게임이라 할 수 있다. 기기의 성능에 따라 특정 개수를 넘어가면 프레임 저하가 나타난다.
- 모바일의 경우 100개정도를 상한선으로 잡고있다. (VR은 절반 이하다.)
- 일반적으로 오브젝트를 그릴 때, 오브젝트 단위로 한 개씩 증가한다. 그 외에도 쉐이더에 따라서 추가로 증가 할 수 있다.
2. 배치(Batches)
- Draw Call과 혼용하여 사용하지만, 사실 드로우 콜을 포함하는 상위 개념이다.
- Draw Call + Set VB/IB + Set Transform + Set Pass Call
※ Set Pass Call = Set Shader + Set Texture 0 ~ 7 + Set Blending + Set Z enable . . .
※ 배치 개수는 어떻게 결정되는가?
1. 매쉬의 개수 * 라이트의 개수 + 재질의 개수 - 동적 배칭으로 절약된 개수.
2. 파티클은 Material이나 Mesh에 관계없이 개당 1개로 계산된다. (만약, 자식으로 달려있는게 있다면 자식 하나당 1개씩.)
3. Set Pass Call
마테리얼과 쉐이더와 관련된 것에 대한 배치를 말한다.
ex) 마테리얼을 공유하여 사용하는 오브젝트가 1개 있다고 하자.
이때, Batch : 10개, Set Pass Call : 1개
총 Batch : 11개.
ex) 마테리얼이나 쉐이더를 공유하지 않고 따로 사용하는 오브젝트 10개.
이때, Batch : 10개, Set Pass Call : 10개
총 Batch : 20개
이러한 이유 때문에 아틀라스를 활용하여 여러 오브젝트들을 한 개의 Material로 묶어서 Set Pass Call을 줄이는 것이 중요하다.
4. 배칭(Batching)
복수의 드로우 콜을 하나의 드로우 콜로 묶어서 처리하는 작업이다.
※ 동적 배칭 (Dynamic Batching)
- 동일한 마테리얼을 공유하고, 특정 조건들을 만족했을 때, 유니티에서 자동적으로 일어나는 배칭을 말한다.
- 정적 배칭에 비해서 조건도 까다롭고 눈에띄는 효율이 아니므로 사실 크게 신경쓰지 않아도 되는 부분이다.
- 동일한 모델의 모양일 필요가 없다.
- 큰 효율을 보이는 곳은 파티클과 메쉬쪽이다.
*특정 조건
1. -버텍스 개수가 총 900개 이하의 메쉬만 적용가능.
- 쉐이더가 정점 위치와 법선이나 다른 UV정보를 사용하면 300이하.
- 정점위치, 법선, UV0, UV1, 탄젠ㅌ트까지 사용하면 180이하.
- 해당 제한 값을 넘으면 배칭을 안하는 편이 이득이다.
2. 오브젝트가 Mirror의 Transform 값을 가지고 있으면 함께 배칭 되지 않는다. ex) 스케일 +1, -1
3. 마테리얼의 인스턴스가 다를경우(동일한 마테리얼일 경우도.) 배칭이 이루어 지지 않는다.
4. 동적으로 라이트 매핑된 오브젝트가 동일한 라이트 맵의 위치가 아닌 한 배칭이 이루어 지지 않는다.
5. 멀티 패스 쉐이더는 배칭이 이루어 지지 않는다. ex) 카룬 쉐이더의 아웃라인.
6. Skinned Mesh 사용불가.
7. 리얼타임 쉐도우의 영향을 받는 오브젝트는 배칭이 이루어지지 않는다. (Receive Shadow를 체크 했을 때)
※ 정적 배칭(Static Batching)
동일한 마테리얼을 공유하고, 움직이지 않는 오브젝트가 인스펙터창에서 Static을 체크해줄 경우 일어나는 배칭.
- 메쉬를 강제적으로 합쳐서 넘져누는 방식이기 때문에 메모리에 부담을 준다.
너무 규모가 크다면 렌더링 쪽을 희생시키는게 나을 수도 있다.
- 눈에 띄는 효과가 나오기 때문에 CPU파워를 줄일 필요가 있을 경우 꼭 정적 배칭을 사용해야 한다.
※ 드로우 콜이 중요하다면, 모든 배경을 하나로 합쳐 내보내는게 이득일까?
아니다. 배경 중 극히 일부분만이 보일 경우에도 전체를 무조건 그리게 된다.
하지만 모듈화 했을 경우에는 오클루전 컬링과 프러스텀 컬링을 통해 일부 메쉬를 그리지 않게 할 수 있다.
그렇다고 매우 세분화해서 나누면 합치는 과정에서 코스트가 많이 발생하기 때문에 적정한 선에서 시야각에 들어오는
구역별로 나누는 것이 중요하다.
'Unity3D > Tip' 카테고리의 다른 글
[Unity3D] AddExplosionForce(); - 폭발 시 여파 적용. (0) | 2017.04.27 |
---|---|
[Unity3D] 일정 범위내의 존재하는 Collider 객체를 추출. (0) | 2017.04.27 |
[Unity3D] 비균등스케일 (non-uniform scale) (0) | 2017.04.27 |
[Unity3D] 셰이더 및 물리 기반 셰이딩 (0) | 2017.04.25 |
[Unity3D] Sprite 동적할당. (0) | 2017.04.21 |