반응형

 

 

 

 

오클루전 컬링

- 오클루전 컬링은 어떤 게임 오브젝트가 다른 게임오브젝트에 의해 카메라 뷰에서 완전히 가려진 게임 오브젝트에 대한 렌더링 계산을 수행하지 못하도록 하는 프로세스이다.

- 기본적으로 카메라 컴포넌트에 있는 Clipping planes의 값을 설정해 절두체 컬링을 할 수 있지만 절두체 컬링은 렌더러가 다른 게임 오브젝트에 가려져있는지 확인하지 않으므로 유니티에서 최종 프레임에 표시되지 않는 렌더러에 대한 렌더링 작업에 CPU 및 GPU 시간을 낭비할 수 있기때문에 오클루전 컬링으로 이러한 낭비를 방지한다.

 

 

 

오클루전 컬링의 작동 방식

- 유니티에서 씬에 대한 데이터를 생헝한 후 런타임 시점에서 해당 데이터를 사용하여 카메라가 볼 수 있는 요소를 결정한다. (베이크)

- 오클루전 컬링 데이터를 베이크하면 유니티는 씬을 셀로 나누고 셀 내 지오메트리와 인접 셀 간의 가시성을 설명하는 데이터를 생성한 뒤, 생성된 데이터의 크기를 줄이기 위해 가능한 경우 셀을 병합한다.

- 런타임 시점에서 유니티가 베이크된 데이터를 메모리에 로드하고, 오클루전 컬링 프로퍼티가 활성화된 각 카메라에 대해 해당 데이터에 대한 쿼리를 수행하여 카메라가 볼 수 있는 요소를 결정한다.

- 오클루전 컬링이 활성화 되면 카메라는 절두체 컬링과 오클루전 컬리을 둘 다 수행하게 된다.

 

 

 

오클루전 컬링 사용 시기

- 낭비되는 렌더링 작업을 방지하게 되면 CPU 및 GPU 시간 모두 절약할 수 있다.

- 유니티의 빌트인 오클루전 컬링은 CPU에서 런타임 계산을 수행하므로 절약되는 CPU 시간을 오프셋할 수 있다. 따라서 오클루전 컬링을 사용하면 오버드로우로 인해 프로젝트가 GPU 바운드일 떄 성능이 향상될 가능성이 매우 높다.

- 오클루전 컬링 데이터는 런타임 시점에서 메모리에 로드되므로 디바이스에 해당 데이터를 로드할 만큼 충분한 메모리가 있는지 확인해야한다.

- 오클루전 컬링은 작고 윤곽이 또렷한 영역이 견고한 게임 오브젝트에 의해 서로 명확하게 분리된 씬에서 잘 작동한다. (복도로 연결된 방을 예로 들 수 있다.)

- 오클루전 컬링을 사용하여 동적 게임 오브젝트를 가릴 수 있지만, 동적 게임 오브젝트는 다른 게임 오브젝트를 가릴 수 없다. 프로젝트가 런타임에 씬 지오메트리를 생성하는 경우에는 해당 기능이 프로젝트에 적합하지 않다.

 

 

 

오클루더(Occluder), 오클루디(Occludee), 동적 오클루전(Dynamic occlusion)

- 오클루더(Occluder) : 다른 렌더러를 가리는 게임오브젝트 (정적 게임 오브젝트)

- 오클루디(Occludee) : 다른 게임오브젝트에 의해 가려지는 렌더러 (정적 게임 오브젝트)

- 동적 오클루전(Dynamic occlusion) : 동적 게임 오브젝트인 경우 오클루더에 의해 컬링 되려면 렌더러에서 해당 플래그를 활성화 시켜야한다.

※※ 동적 게임 오브젝트의 경우, 오클루전 컬링 데이터에 베이크할 수 없다. 그렇기 때문에 동적 오클루전 플래그를 활성화하여 오클루더가 해당 렌더러를 가릴 때 컬링할 수 있도록 해준다.

※※ 동적 게임 오브젝트는 오클루디일 수는 있지만 오클루더일 수는 없다.

 

 

 

 

추가 문서

 

오클루전 컬링 - Unity 매뉴얼

오클루전 컬링은 Unity가 다른 게임 오브젝트에 의해 뷰에서 완전히 가려진(오클루전된) 게임 오브젝트에 대한 렌더링 계산을 수행하지 못하도록 하는 프로세스입니다.

docs.unity3d.com

 

 

[유니티] 오클루전 컬링 - 설정

기본 개념은 다음 글에서 참고 [유니티] 오클루전 컬링 - 기본 개념 오클루전 컬링 - 오클루전 컬링은 어떤 게임 오브젝트가 다른 게임오브젝트에 의해 카메라 뷰에서 완전히 가려진 게임 오브젝

srdeveloper.tistory.com

 

 

 

 

반응형
반응형

 

 

 

 

 

 

 

 

파티클 옵션

 

 

 

 

참고 사이트

- UnitychanKAGURA

 

ユニティちゃんKAGURA(URP) - ダウンロード - UNITY-CHAN! OFFICIAL WEBSITE

2018年末のイベントに登場した和装のユニティちゃんです。Unite In The Skyのリミックス曲と振り袖にあわせた新たなダンス、和風のステージデータも同梱されています。 Unity2019.4.16f1, Universal Ren

unity-chan.com

 

 

 

 

 

반응형
반응형

 

 

 

 

 

 

 

 

 

제작기간

- 약 8주

 

 

 

구현내용

  • UI

- Safe area를 활용하여 펀치홀(노치) 기종에 UI가 겹치지 않도록 조정

- 커스텀 버튼, 슬라이더 구현하여 적용

  • Game

- 제스처 기능(카메라 이동, 줌) 적용

- A* 알고리즘 적용 (OpenList에 Heap 적용)

- 싱글톤(Manager class), FSM(Unit) 디자인패턴 적용

  • Data

- Player data : JsonUtility를 사용해 저장

- Game data(보상, 유닛 레벨, 능력치 등) : 엑셀로 테이블을 만들어 CSV파일로 관리

- Encryption : JSON과 CSV 등 모든 데이터를 라인달(AES) 암호화를 통해 암호화, 복호화하여 저장하고 불러온다

 

 

 

최적화

- SpriteAtals를 활용하여 Batch 줄임

- A* 알고리즘에서 OpenList와 CloseList에 발생하는 GC로 인해 프레임 드랍 발생하여 각 리스트에서 발생하는 할당을 줄여서 프레임 드랍 완화

 

 

 

 

 

반응형

'Game > Personal development' 카테고리의 다른 글

[Unity] 두더지 잡기 게임 제작  (0) 2022.04.28
[Unity] 미로 게임 제작  (0) 2022.04.28
[WIN API] 서커스 찰리 게임  (0) 2022.02.05
[WIN API] 카드 맞추기 게임  (0) 2022.01.30
산성비 게임 제작 (C++)  (0) 2022.01.23
반응형

 

 

 

 

Mixamo에서 모델을 다운받아 유니티에 임포트해서 씬에 배치하면 텍스처 없이 모델만 보여진다. 해당 모델의 텍스처를 불러오고 추가로 생기는 문제를 해결해보자.

 

 

 

 

텍스처 불러오기

1. 모델을 클릭한 뒤, 인스펙터 창에서 Materials를 클릭한 뒤, Extract Textures버튼을 클릭한다.

 

2. Select Texture Folder 창이 뜨면 원하는 텍스처가 저장될 폴더를 지정한 뒤 폴더 선택 버튼을 누르면 텍스처가 추출된다.

 

3. 텍스처 추출이 완료되면 NormalMap Settings 창이 뜨는것을 볼 수 있는데, 해당 창에서는 Fix Now를 누르면 된다.

 

 

결과

 

 

 

 

 

텍스처가 비정상 적으로 보이는 현상

- 이 부분은 모델마다 다른데 텍스처가 비정상적으로 보이는 문제의 원인은 Material의 렌더모드가 Transparent로 되어있어서 생기는 현상이다. (Transparent로 괜찮은 모델이 있고 바꿔줘야되는 모델이 있는데 왜이러는지는 모르겠다.)

 

1. 모델을 클릭한 뒤, 인스펙터 창에서 Materials를 클릭한 뒤, Extract Materials를 클릭한다.

 

2. Select Materials Folder 창이 뜨면 Material을 추출 할 폴더를 선택한다.

 

3. 추출한 폴더를 확인해보면 해당 모델의 Material을 확인할 수 있는데, 여기서 (URP 기준)Surface Type

Opaque로 변경해주면 정상적으로 보이게된다. (레거시의 경우 Render mode에서 Opaque로 변경하면 된다.)

 

 

결과

 

 

 

 

 

 

반응형
반응형

 

 

 

 

유니티 엔진의 Input 클래스에는 touch라는 구조체가 존재한다. 이 touch라는 구조체의 정보를 바탕으로 모바일 환경에서의 제스처기능을 적용해 카메라를 이동하거나 줌 인/아웃 기능을 구현할 수 있다.

 

 

카메라 이동

using UnityEngine

enum GESTURE
{
    MOVE = 1,
    ZOOM,
}

private void MoveCam()
{
    if (Input.touchCount == (int)GESTURE.MOVE)
    {
        Touch touch = Input.touches[0];
        Camera.main.transform.position = new Vector3(
            Camera.main.transform.position.x - touch.deltaPosition.x,
            Camera.main.transform.position.y - touch.deltaPosition.y,
            Camera.main.transform.position.z);
    }
}
  • Touch 구조체에는 deltaPosition이 존재하는데 이전 프레임과 현재 프레임 사이의 움직인 벡터 값을 받을 수 있다.
  • 이 벡터 값을 이용해서 카메라의 위치를 변경해주면 된다.
  • deltaPosition을 바로 적용해주면 카메라가 엄청 빠르게 움직이니 해당 값에 speed(float) 값을 곱해서 적용해준다.
  • 간단하게 보여주기 위해 작성된 코드로, Camera.main의 카메라 클래스는 캐싱해서 사용하는게 최적화에 도움이 된다.

 

 

 

카메라 줌 인/아웃

private void ZoomCam()
{
    if (Input.touchCount == (int)TOUCH.ZOOM)
    {
        Touch touch_1 = Input.touches[0];
        Touch touch_2 = Input.touches[1];

        //이전 프레임의 터치 좌표를 구한다.
        Vector2 t1PrevPos = touch_1.position - touch_1.deltaPosition;
        Vector2 t2PrevPos = touch_2.position - touch_2.deltaPosition;

        //이전 프레임과 현재 프레임 움직임 크기를 구함.
        float prevDeltaMag = (t1PrevPos - t2PrevPos).magnitude;
        float deltaMag = (touch_1.position - touch_2.position).magnitude;

        //두 크기값의 차를 구해 줌 인/아웃의 크기값을 구한다.
        float deltaMagDiff = prevDeltaMag - deltaMag;

        Camera.main.orthographicSize += deltaMagDiff;
        Camera.main.orthographicSize = Mathf.Clamp(Camera.main.orthographicSize, 7, 30);
    }
}
  • 줌 기능은 카메라 이동 코드와는 다르게 조금 복잡한데, 결론적으로 이전 프레임과 현제 프레임의 두 터치 사이의 벡터 크기(Maginitude) 값을 이용해서 deltaMagnitude 값을 구한다.
  • 이렇게 구해진 deltaMagnitude 값을 Camera의 orthographicSize에 더해주면 줌 인/아웃 기능 구현이 가능하다.
  • orthographicSize가 너무 작아져서 음수로 내려가면 화면이 뒤집어져 보이므로 Mathf.Clamp로 적절하게 최소, 최대값을 고정해준다.
  • deltaMagnitude 값을 바로 적용하면 줌이 빠르게 적용되니 해당 값에 speed(float) 값을 곱해서 사용해준다.

 

 

 

결과

 

 

 

 

 

 

반응형

+ Recent posts