목차

반응형

열심히 일을 하다보면 aab 파일에 문제가 없는지 궁금할때가 있다.

유니티 build and run을 사용하지 않고 aab 파일을 핸드폰에 설치하는 방법에 대해서 알아보자

 

쉬운 방법은 없다 그냥 아래 써있는대로 따라하자

 

본인의 OS에 맞춰 bundletool을 설치하자

github.com/google/bundletool/releases

 

cmd 기준 bundletool을 사용하여 aab파일로부터 apk를 뽑아내는 명령어는 아래와 같다.

 

java -jar /Users/jim/Desktop/workspace/project/bundletool-all-1.3.0.jar  build-apks --bundle=/Users/jim/Desktop/workspace/project/Test/app.aab  --output=/Users/jim/Desktop/workspace/project/Test/result.apks --ks=/Users/jim/Desktop/document/keystore/key.keystore --ks-pass=qlalfqjsgh --ks-key-alias=mycompany --key-pass=qlalfqjsgh --mode=universal

 

빨간색에 해당하는 부분은 본인의 환경에 맞춰서 바꿔넣어야한다.

 

뽑아낸 apks 파일의 확장자를 zip으로 변경하자

 

확장자를 바꾼 파일의 압축을 풀면 한개의 apk가 나올것이다.

해당 파일을 설치하면 된다.

 

adb 설치 명령어까지 친절하게

./adb install /Users/jim/Downloads/reuslt.apk 

반응형
반응형

https://www.youtube.com/watch?v=4kVffWfmJ60

 

오늘은 네임드 개발자 오즈라엘님이 "성능 프로파일링과 최적화"라는 귀한 주제로 발표를 해주셨다. 두 시간짜리 영상을 열심히 보고 요약글을 올리는 나한테 감사하자

 

"쌍따봉 드립니다."

 

 

1.  프로파일링 유의사항

2. 유니티 프로파일러

2.1 다양한 병목현상

3. 프레임 디버거

4. 메모리 프로파일러

5. 텍스쳐 컴프레션

6. Xcode Instrument

7. 최적화 팁 & 트릭

 

 

 

 

 

 

 

 

 

 

 

 

1.  프로파일링 유의사항

타겟 플랫폼 선정

많은 팀이 간과하고 있는 것이 원래 최적화를 위해서 타겟 플랫폼과 타겟 디바이스를 정해야 한다.

무조건 좋은 퀄리티만 보여줄 수 없기 때문에 현실적으로 목표하고자 하는 디바이스와 플랫폼에 적합한 퍼포먼스를 보여줘야 한다.

사실 우리 회사도 타겟 플랫폼을 딱히 설정하고 개발을 시작하지 않는다. 하지만 가끔 게임 업계에서도 "ㅁㅁ게임은 동남아시아를 대상으로 한 게임이라서 저성능 기기를 타겟으로 개발을 한다...." 이런 말이 들려오는데 그런 환경이라면 합리적인 타겟 플랫폼 선정이 필수라고 생각이 든다.

 

최적화

최적화란 병목(다양한 원인)을 탐지하고 제거하는 반복 작업을 일컫는다.

 

위의 경우는 GPU 바운드 -> CPU는 할 일이 없지만  GPU에 할일이 많아서 렉걸림

따라서 이런 상황에서는 CPU를 최적화해도 개선이 전혀 안된다.

CPU 바운드 원인 : 로직, AI, 물리연산, 로딩, GC처리

GPU 바운드 원인 : 폴리곤, 텍스쳐, 필터링, 라이트, 프레임 버퍼, 쉐이더, 오버드로우

 

 

주기적인 최적화

프로파일링, 최적화는 개발 마지막 단계에서 하는 것이 아니라 정기적으로 하는 것이다.

그에 따른 빌드 및 QA 프로세스 정립은 필수다.

 

프로파일링 주의 사항

추측에 의한 최적화 금지

실제로 어떤 팀에서 자꾸 퍼포먼스가 안 나와서 어떤 개발자가 텍스쳐가 문제인 것 같아서 텍스쳐를 전부 하향평준화해달라고 아티스트한테 요청해서 적용했는데 해결이 안 됐다. 굉장히 비효율적인 업무방식이다.

 

디버거/프로파일러 툴의 적극적인 활용

결국 최적화는 최적화를 위한 툴들을 얼마나 잘 사용하느냐에 따라 달려있다.

적극적으로 툴을 사용해서 문제를 확인하고 처리하도록 하자.

스냅드래곤, xcode 프로파일러가 그렇게 좋다더라

 

유니티 에디터에서의 프로파일링은 단순 참고용

에디터에서 측정한 성능과 타겟 플랫폼에서 측정한 성능은 전혀 다르게 나올 수 있으니 맹신하면 안 된다.

 

자동화된 테스팅 환경 구축(ex:벤치마커)

매번 테스트할 때마다 빌드, 배포에 시간이 오래 걸리니까 프로젝트 초기에 자동화된 테스트 환경 구축을 하면 좋다.

 

쓰로틀링

모바일은 PC 달리 쿨러가 없어서발열 시 자체적인 하드웨어 성능 제한을 걸어서 성능 저하 발생

최신 휴대기기일수록 취약함(성능이 좋아지지만 사이즈는 그대로라서)

ex) 처음 빌드에는 괜찮았는데 몇번 테스트 다시해보니까 성능이 갑자기 저하되면 쓰로틀링일 있음

스마트폰 쿨러로 식혀주면서 한번 측정하고 몇분뒤에 측정하는 것이 좋다.

실제로 오지현 센세는 열감지기로 핸드폰 온도 측정하고 테스트한다고

 

2. 유니티 프로파일러

커스텀 프로파일러 태그 지정

다들 잘 모르는 기능인데 위와 같이 특정 코드에 대해서 태그를 지정해서 프로파일러에서 태그에 따라 결과를 확인할 수 있다.

 

프로파일러 사용 예시 1)

프로젝트에서 프로파일러 타임라인 찍어보고 오래 걸리는 부분을 제거해주는 예시를 보여주었음.

 

프로파일러 사용 예시 2)

샘플 프로젝트인데 FPS가 6이 나오고 딱 봐도 포스트 프로세싱에 GPU 쪽 부하가 심한 것 같다고 생각은 들지만...!

 

프로파일러를 찍어보면 드로우 콜 1300개 CPU 쪽 문제임을 알 수 있다.

드로우 콜과 CPU 관계 설명

https://funfunhanblog.tistory.com/301

 

Unity) 드로우콜 DrawCall

1. 드로우콜 이란 간단하게 CPU가 GPU에게 렌더링 작업을 수행하도록 명령을 하는것이다. 게임은 실시간 렌더링 어플리케이션이다. 실시간으로 렌더링을 수행하기에, 한 프레임의 렌더링은 오브��

funfunhanblog.tistory.com

 

Profile Analyzer라고 새로 나온 기능이 있는 데 사용을 추천해주셨다.

 

 

 

GPU 프로파일링은 특정 플랫폼에서만 가능하고 쉽지 않다고 하였다.

스냅 드래곤, Xcode의 GPU 프로파일링 툴을 사용하는 것을 추천해주셨다.

 

 

2.1 다양한 병목현상

 

Fillrate 병목 현상

요즘 기기 해상도가 너무 좋아서 Fillrate로 인한 부하가 많다. 확인해보도록 하자

 

오버드로우 병목 현상

오버드로우는 말 그대로 가려진 뒷부분까지 그리는 것을 말한다. 오버드로우를 하게 되면 수많은 파티클이 중첩되면서 성능 저하를 일으킬 수 있다.

평범한 상황에서는 오버드로우로 인한 병목현상이 발생하지 않는다.

 

 

하지만 파티클에서 자주 발생하는 현상이기도 하다. Scene에서 Overdraw로 보기를 해서 오버드로우가 과하게 발생하는지 확인하도록 하자.

 

포스트 프로세싱 부하

포스트 프로세싱도 필레이트에 많은 부하를 준다.

포스트 프로세싱의 원리 : 특정 픽셀의 주변 픽셀을 가져와서 변화를 주는 샘플링 처리를 하기 때문에 필레이트와 굉장히 밀접한 연관성이 있다.

 

업스케일링 샘플링

높은 해상도를 포기하기 힘들다면 업스케일링 샘플링 기법을 추천해주셨다.

 

UI 부분의 해상도만 높은 상태를 유지하고 인게임 해상도를 낮추는 것이다.

실제로 작은 기기에서 보기 때문에 유저들은 쉽게 눈치채지 못한다.

 

오지현님의 업스케일링 샘플링에 대한 샘플 프로젝트 주소

https://github.com/ozlael/UpsamplingRenderingDemo

 

업스케일 샘플링 때문에 해상도가 낮은거지 이미지가 안좋은것이 아님!

이번에 새로 나온 기능인 URP에서는 기본적으로 업스케일링 샘플링을 공식적으로 지원한다.

위 사진은 극단적인 차이를 보여주기 위해서 인게임 해상도를 10%로 낮춘 상황이다.

 

텍스쳐 병목 현상

텍스쳐 퀄리티를 조절해서 병목 확인이 가능하다.

텍스쳐를 1/8 줄여서 플레이 해봤더니 게임의 렉이 없어졌다. -> 텍스쳐 병목이다.

 

3. 프레임 디버거

프레임 디버거를 통해서 어떻게 드로우 콜이 발생하는지 순차적으로 하나하나 볼 수 있다.

게임에서 드로우콜이 많이 발생하는 경우 확인하기 좋다.

 

또한 Batcing처리가 안되었을 때 그 이유도 나온다. ( Batcing에 대한 글은 아래 글 참고 )

https://funfunhanblog.tistory.com/302?category=818491

 

프레임 디버거를 이용한 드로우 콜 최적화 예시) 타워 디펜스

위와 같이 샘플 프로젝트를 플레이하다가 프레임 디버거로 드로우 콜을 확인해보았다.

 

드로우 콜은 245며 캐릭터 하나를 그리는데 캐릭터 이미지, 그림자, 체력바, 체력바 백그라운드 총 4개의 드로우 콜이 발생한다.

배칭이 전혀 안되어있다.

 

똑같은 성질의 이미지에 레이어를 추가해서 똑같은 애들끼리 똑같은 레이어를 적용시켜서 드로우 콜을 줄인다.

기존에는 그림자 하나를 그릴때 하나하나 그렸지만 레이어를 적용하면 그림자가 전부 한번에 그려진다.

나아가서 스프라이트 패킹, 배경 레이어를 추가하게 된다면 드로우콜을 줄일 있다.

 

 

4. 메모리 프로파일러

메모리 관리는 항상 중요하지만 모바일에서는 특히나 중요하다.

PC에서는 특정 어플리케이션에서 물리적으로 수용 가능한 메모리의 범주를 벗어나도 가상 메모리를 통해서해결할 수 있다.

그러나! 모바일에서는 메모리 시스템이 PC와는 달라서 특정 어플리케이션의 메모리 점유율이 높아지면 다른 어플리케이션의 메모리를 빼앗아서 사용하도록 설계되어있어서 메모리가 너무 커지는 순간 해당 앱을 강제종료 시켜버린다강제 종료시켜버린다. (이와 같은 이유로 모바일에서는 로딩화면에서 크러시가 많이 난다.)

실제로 내 게임도 아직 최적화를 거치지 않았는데 아이폰 개발하다가 옛날기종에서 메모리 650mb 넘어가서 어플리케이션이 강제 종료당했다.

 

메모리 프로파일러 예시 1)

메모리 프로파일러를 사용하면 모든 힙 메모리 영역을 트래킹 할 수 있다.

텍스쳐에서 어떤 텍스쳐가 많이 차지하는지 확인 가능하다. 사운드, 폰트 전부다 가능하다!

 

위의 경우는 확인해보니 dude라는 텍스쳐가 사이즈가 4096으로 설정되어있었다.

 

메모리 프로파일러 예시 2)

샘플 프로젝트인데 별거 없는 프로젝트지만 메시 하나가 20MB를 차지한다.

 

Read/Write Enabled : 스크립트를 통해서 메시에 접근할 있는지 여부(메시 변형 가능)

이것을 키게 되면 GPU, CPU 양쪽에 해당 데이터가 적재된다.

스크립트를 통해서 메시를 변경할일이 없으면 반드시 끄도록 하자

 

오디오 클립도 메모리에 올라갔을 때굉장히 큰경우가 있는데 Decompress On Load 음악 압축을 풀어서 메모리에 올리기 때문에 바꾸자.

아이폰에서는 mp3 압축돼서 메모리에 적재 가능하기때문에 mp3 권장

 

5. 텍스쳐 컴프레션

보통 게임에서 텍스쳐가 많은 부하를 차지한다.

 

텍스쳐 이미지의 복잡도, 포맷별로 적재되는 텍스쳐의 용량의 차이가 발생한다.

위의 사진을 보면 PNG, JPG는 1메가가 안되지만 인게임에서는 해당 텍스쳐가 4MB를 차지한다.

그 이유는 PNG, JPG, PSD로 저장되는 텍스쳐의 용량은 단순히 PC에서 저장되기 위한 용량을 말하는 것이지 GPU에서 사용하기 위한 포맷이 아니다.

우리가 알고 있는 텍스쳐 이미지는 GPU에서 사용하기 위해 다시 ETC, ASTC 포맷으로 전환이 일어난다.

 

또한 텍스쳐 압축 방식에 따라 미세하게 다른 차이가 발생하기도 한다.

대표적으로 사용하는 텍스쳐 압축 방식에 대하여 간단히 알아보자

 

 

PVRTC : 원본 이미지를 소수 픽셀로 뽑아내서 압축 -> 이미지가 뭉개지는 현상 발생

 

ETC : 이미지를 색상과 밝기로 나눠서 색상은 낮은 해상도, 밝기는 높은 해상도로 압축하는 방식

(인간의 눈은 색상보다 밝기에 더 민감한 원리를 이용)

 

ETC1 ETC2 있는데 ETC2 좀더 블록현상이 완화됨

 

주의할 점 : 완전 옛날 기기에서 ETC2 포맷을 사용하면 메모리에 원본 텍스쳐가 올라가버린다.

동남아 시장을 타겟으로 하면 ETC2 포맷을 사용하면 안된다.

 

PVRTC 조금 번지고 블러링 되는 느낌이 있다

ETC 의도하지 않은 색상들이 발생한다.(색상과 밝기를 나눠서 처리하기 때문에 옷깃 부분에 검은색 부분이 유난히 더 많이 보인다.)

위와 같이 텍스쳐 압축에 따라 달라지는 특징을 알아둬야 메모리를 절약하면서 퀄리티를 살릴 있다.

 

ASTC(Adaptive Scalable Texture Compression)라는 자유롭게 압축 단위를 바꾸는 압축 기법도 있다.

 

 

좌측 이미지는 캐릭터 이미지라서 민감하기 때문에 최대한 압축을 덜하는 4x4 방식을 택한다면 오른쪽 블러 이미지는 압축을 크게 해도 눈치채기 힘들기 때문에 12x12로 크게 압축을 하는 전략을 말해주셨다.

 

텍스쳐의 해상도는 2의 제곱수로 만들어야 하는 이유도 설명해주었다.

200x200짜리 이미지를 만들어도 어차피 256x256으로 변환돼서 256x256 - 200x200만큼의 공간이 낭비된다는 것이다.

 

 

 

6. Xcode Instrument

유니티 프로파일러에서는 없던 세부 내용까지 있다.

어떤 과정을 통해서 네이티브로 할당되는것까지 확인이가능하다.

 

 

7. 최적화 팁 & 트릭

여태까지 말한 것을 토대로 타겟 플랫폼에 따라 에셋의 세팅도 달라져야 한다는 것을 충분히 이해하리라 생각한다.

이런 식으로 실수 없도록 모든 에셋에 대하여 임포트 옵션을 설정할 수 있다.

 

적절한 targetFrameRate

  • 퍼즐게임이면 굳이 60프레임을 찍을 필요가 없다. : 30으로 해도 된다. -> 발열을 낮출 있음
  • 인게임에서는 60하고 UI에서는 30으로 하는 전략도 있다.
  • Adaptive Performance 통해서 CPU, GPU 부하를 탐지해서 타겟프레임 레이트를 적절하게 바꿔주는 것도 가능하다.

 

에셋 비동기 로딩 사용

AssetBundle.LoadFromFileAsync()

AssetBundle.LoadAssetAsync()

끊김 없이 에셋을 부르기 위한 방법

 

사용하지 않는 Monobehaviors 메소드 제거

  • Start, Update, FixedUpdate 제거
  • Update안의 내용이 비어있더라도 함수를 계속해서 호출하기 때문에 사용하지 않으면 지워줘야 한다.

 

Update 1000개 vs 매니저 패턴 1개

  • 성능상의 차이가 없다고 생각할 수 있지만 유니티 에디터와 C++을 왔다 갔다 하면서 함수 자체만으로 발생하는 오버헤드가 있기 때문에 매니저 패턴을 이용하는 것이 좋다.

 

비싼 API 호출 주의

  • GameObject.Find, GetComponent, Camera.main, Debug.Log
  • 위의 함수들은 잦은 호출 시 성능 저하를 일으킬 수 있는 API라서 제한적인 상황에서 사용해야 한다.
  • 따라서 자주 쓰이는 변수의 경우 Awake나 Start에서 캐싱해놓고 사용하도록 하자

 

Allocating API 주의

  • GetComonents, Animator.parameters와 같이 List 형태의 데이터를 받아오는 API를 호출하게 되면 해당 데이터를 담아두는 변수를 그 즉시 생성하기 때문에 사용할 때마다 계속해서 리스트를 생성하는 것이기 때문에 유의해서 사용해야 한다. 

 

정적 데이터 파싱 주의

  • 인게임에서 필요할때마다 xml, json 불러오는것보다 so 바꿔서 처리하는게 좋다.
반응형
반응형

https://www.youtube.com/watch?v=Kel7NIP2AOg

유니티 데브윅스에서 발표한 주제 "유니티 워크플로 속도 향상을 위한 기능 소개"에 대한 간략한 요약을 하겠다.

 

발표 개요

1. 플레이 모드

2. 애셋 임포트

3. 애셋 관리

4. 디바이스 프리뷰

5. 패치 빌드

6. 기타

 

 

 

 

 

 

 

발표 개요

유니티로 개발을 하다보면 유니티의 자체적인 이슈로 개발자의 시간을 잡아먹는 부분이(애셋 임포트, 자체적인 빌드 타임 등) 존재한다.

특히 그중에서도 빌드와 관련된 부분에 대하여 발표자님께서 대안에 대하여 말씀하셨다.

모든 문제에 대하여 완벽한 대안은 아니더라도 앞으로 계속해서 고쳐나갈 것이고 유니티 내부 개발진들도 사용자에게 더욱 편한 환경을 제공하기 위하여 장기적으로 개발을 염두에 두고 있다고 한다.

여러 가지 대안들 중에서도 크게 다섯 가지의 대안과 개선안을 발표해주셨다.

 

 

 

1. 플레이 모드

에디터에서 플레이를 누르면 걸리는 시간(현재 프로젝트의 크기에 따라 수초~수십 초)을 단축

 

사용 방법은 Project Settings > Enter Play Mode Settings > Enter Play Mode Options를 체크하면 된다.

Reload Domain과 Reload Scene에 대한 설명은 아래 있다.

 

(실제로 실행을누르자마자 바로 실행이 될 정도로 엄청난 체감효과를 자랑한다.)

 

원리

유니티 에디터단에서 게임을 실행하면 위와 같은 단계를 거치게 되는데 특정 단계 중 도메인 리로드, 씬 리로드 부분에서 상당수 시간을 차지한다.

도메인 리로드 : 스크립트 연관, 스크립트의 deserialization, serialization, 물리 디스크 File IO, 어셈블 로드

씬 리로드 : 씬의 오브젝트 연관, 에디팅 모드에서 씬의 게임 오브젝트를 바로 사용하는 것이 아니라 전부다 destroy 하고 다시 생성

 

위의 두 단계를 최대한 생략, 단축해버리는 것이다.

해당 기능에서 Reload Domain과 Reload Scene를 체크하게 되면 해당 부분을 스킵하지 않게 된다.

 

주의사항

해당 기능은 Experimental 단계라서 무결성을 보장하지 않는다. 다음과 같이 알려진 부작용도 가지고 있다.

 - HDRP에서 버그가 많음

 - 써드파티를 고려하고 제작된 기능이 아님 : 써드파티에서 무수한 오류를 맛보게 될 수 있음.

 - 스태틱 필드 리셋 안됨 : 게임을 시작할때마다 스태틱 필드가 초기화돼야 하지만 그렇지 아니함.

 

질문

Enter Play Mode 사용시 UGUI 가 제대로 업데이트가 안됩니다!

아직 실험단계라서 유니티에서 제공하는 모든 부분이 검증되지 않았습니다. 버그 제보 시 처리하도록 하겠습니다.

 

Domain Reload와 Scene Reload 체크시 기존과 차이가 없나요?

완전히 똑같게 됩니다.

 

프로토타입 단계, 소규모 프로젝트에서 정말 유용하게 사용 가능하다고 생각한다.

 

 

 

2. 애셋 임포트

에셋 임포트 하는 시간을 단축, 개선

 

설정 방법(유니티 2019.3 버전부터는 자동으로 Version2로 설정된다.)

Project Settings > Editor > Asset Pipeline > Version 2로 설정

 

사실 해당 설정에 대한 기본값이 최신 버전을 사용하는 사람이라면 Version 2로 되어있어서 이미 사용 중이라는 것을 눈치채지 못하고 있을 수 있다.(내가 그렇다)

기존 방식에서는 타겟 플랫폼을 스위칭하면 기존 캐싱이 전부 다 사라지는데 Version 2부터는 플랫폼마다 캐싱 데이터가 남아있어서 빠른 타겟 플랫폼의 스위칭이 가능하다.

 

원리

유니티 앤젠 내부에서 리팩토링을 많이 한 기능이라고 한다. 유니티 사용자는 크게 눈치채지 못할 수 있다.

애셋을 임포트하는 알고리즘 또한 개선하였다.

 

주의사항

해당 기능을 사용하게 되면 디스크 용량을 더 크게 사용할 수 있다. 그래서 에디터를 재시작하면 안 쓰는 데이터는 자동으로 삭제하도록 개발하였다.

 

개발자 코멘트

앞으로도 계속해서 발전시켜나갈 부분이며 두 가지 개발중인 기능이 있다.

Background import

말그대로 지금은 애셋을 임포팅 하면 유니티 포커스를 프리징 해서 작업을 못하도록 막는데 백그라운드에서 해당 작업이 진행되도록 개발 중

On-demand import

백그라운드 임포트와 찰떡궁합인 기능인데 임포팅 하는 리소스의 우선순위를 현재 유저가 작업하고 있는 부분에 맞춰서 임포팅하는 기능이다.

 

 

3. 애셋 관리

애셋의 물리적인 위치에 구애받지 않고 자체적인 애셋의 경로를 등록함으로써 코드상에서 보다 일관성 있고 쉽게 애셋에 액세스

 

기존 애셋 시스템에서는 아래와 같이 주어진 상황마다 애셋에 도달하기 위한 주소가 바뀐다.

 - 애셋을 서버에서 리모트로 받은 경우

 - 애셋이 리소스 폴더에 있는 경우

 - 애셋을 애셋 번들로 접근하는 경우

...

 

 

어드레서블 애셋 시스템을 사용하면 애셋에 자체적인 접근 주소를 부여하여 맥락과 관계없이 애셋에 접근이 가능하다.

 

에셋 프로파일

에셋 프로파일을 통하여 애셋에 대한 상황을 설정하여 테스트해 볼 수 있는 기능이 생겼다.

 

애셋 프로파일러

이미지는 없지만 애셋 프로파일러라는 기능도 소개해주었는데 특정 애셋별로 몇 번 사용했고 언제 사용됐는지 확인하는 기능(최적화)

 

 

 

 

 

4. 디바이스 프리뷰

디바이스 별로 어떻게 렌더링이 되는지 확인하는 기능(해상도 대응, 노치 확인)

 

 

 

실제 내 프로젝트에도 적용시켜봤다. 뒷목;;

개발자뿐만 아니라 디자이너들도 알면 좋은 기능이라고 생각한다.

 

사용 방법은 아래 블로그 글에 잘 나와있다.

https://skuld2000.tistory.com/79

 

[Unity] 유니티에 새로 추가되는 디바이스 시뮬레이터(Device Simulator) 소개

1. 유니티 디바이스 시뮬레이터 (Unity Device Simulator) 유니티 디바이스 시뮬레이터(Unity Device Simulator)는 유니티 에디터에서 개발중인 게임을 실행했을 때 Game 윈도우에서 실행되는 대신 Game XCode 나..

skuld2000.tistory.com

 

 

주의사항

CPU, GPU와 같이 성능적인 부분은 재현되지 않는다.

 

 

5. 패치 빌드

변경된 스크립트 부분만 업데이트 형태로 디바이스에 설치하며 빌드 시간을 단축시키는 기능

 

Scripts Only Build > Patch And Run을 하게 되면 프로젝트의 스크립트 중에서도 변경이 발생한 부분만 빌드하여 디바이스에 패치 형태로 빌드를 한다.

 

위와 같이 빌드 시간을 크게 단축할 수 있다.

 

주의사항

Scripts Only Build는 안드로이드만 지원한다. (망해라 ios ^^)

 

 

 

6. 기타

안드로이드 로그 캣을 유니티에서 지원한다.

 

이전에 Unity Remote라는 기능이 있었는데 해당 기능을 계승하는 Unity Live Link라는 기능을 개발하고 있다.

유니티 에디터에서 디바이스에 연결하여 디바이스에 구동 중인 프로젝트를 수정 

 

ㅋㅋㅋ 발표 중에 자꾸 오지현 님이 강사님 놀려서 개 웃겼다. ㅋㅋㅋㅋㅋㅋ

자꾸 놀려서 마지막에는 결국 관리계정이 그만하라고 했다 ㅋㅋㅋㅋ 개웃 ㅋㅋㅋㅋ

반응형
반응형

1. 개요

2. ASLR : 메모리 주소는 항상 바뀐다

3. 게임 가디언 VS 유니티 앱

3-1. 메모리 주소 접근 unsafe 코드

4. 게임 가디언 VS 안티 치트 변수 암호화 기능

4-1. 안티 치트 obscured 변수 암호화 원리

5. 게임 가디언 VS 안티 치트 변수 암호화 기능 강화 버전

5-1. 개발 도중 이상한 점(슈뢰딩거의 변수)

6. 게임 가디언 VS 메모리 변조 디텍터

7. 결론

 

 

 

 

 

 

 

1. 개요

와 목차만 봐도 양이 굉장히 많다.

근데 실제로 회사에서 이것만 연구하느라 거의 2일 정도 시간을 소비했다.

회사에서 안티치트라는 무려 50$짜리 해킹 방지 에셋을 사용하는데 쓰는 것은 좋은데 어떤 원리로 작동하는지 그리고 실제로 해커 입장에서 테스트해보면서 해킹 방지가 되는지 누군가는 확인해보고 연구해볼 필요가 있다고 생각이 되어서 연구를 하게 되었다.

유니티 게임 개발자들도 이 글을 읽고 많은 도움이 되었으면 좋겠다.

재밌게 탐구하기도 했고 안티 치트를 뚫어서 메모리 변조를 해보고 싶다는 생각이 들었다. 언젠가 시간이 나보면 해볼 거다.

해킹 개깐지

 

계속해서 언급할 안티 치트 에셋(꼭 없어도 괜찮다. 어떤 식으로 암호화를 하는지 세세하게 보여줄 것이기 때문에 이해만 하면 되겠다.)

https://assetstore.unity.com/packages/tools/utilities/anti-cheat-toolkit-152334

 

Anti-Cheat Toolkit - Asset Store

🌎 demo ▶ videos 💬 forum 📄 API reference 💌 support 🕵 Anti-Cheat Toolkit (ACTk) 🕵 is here to add some extra pain to the guys who cheat / hack / crack something in your game. Includes various anti cheat tricks and techniques in one place, easy to use, with fu

assetstore.unity.com

 

2. ASLR : 메모리 주소는 항상 바뀐다

먼저 본격적으로 실험에 들어가기 전에 한 가지 알아둬야 하는 개념이 있다.

Address Space Layout Randomization

 

간단히 말하자면 앱이 실행될 때마다 메모리 주소가 랜덤 하게 배정되어서 내가 만든 게임에서 gold 변수가 가지는 메모리가 앱을 실행할 때마다 다른 메모리 주소를 갖게 되는 것이다.

이렇게 함으로써 앱의 보안을 강화시킬 수 있다고 한다.

그렇기 때문에 앞으로 있을 메모리 해킹에서 해킹할 변수는 동일하지만 메모리 주소는 계속해서 바뀐다는 것을 알아두도록 하자.

 

ASLR에 대한 자세한 내용은 아래 위키에 잘 나와있다.

https://en.wikipedia.org/wiki/Address_space_layout_randomization

 

Address space layout randomization - Wikipedia

Address space layout randomization (ASLR) is a computer security technique involved in preventing exploitation of memory corruption vulnerabilities. In order to prevent an attacker from reliably jumping to, for example, a particular exploited function in m

en.wikipedia.org

 

좀 특이한 점이라면 생각보다 고안되고 적용된 지 오래된 기술은 아니라는 점

안드로이드는 2015년도에 본격적으로 채택, MAC, 리눅스, 윈도우 전부 2000년대에 본격적으로 도입되었다.

 

 

3. 게임 가디언 VS 유니티 앱

자 그럼 이제 본격적으로 유니티 앱에서 게임 가디언을 통해 메모리 변조를 해볼 건데 간단하게 정말로 게임 가디언이 해킹하는 변수의 주소가 실제 변수의 주소가 맞는지 확인해볼 것이다.

 

해킹할 변수는 InGameGold 인게임 골드다.

코드를 보면 

inGameGold라는 private 변수의 메모리 주소를 받아와서 출력해준다.

이 주소를 유니티의 텍스트에다가 넣어줘서 핸드폰에서 확인이 가능하도록 하였다.

 

그리고 평범하게 게임 가디언으로 쉽게 뚫어서 변수의 주소를 찾았다.

 

게임의 한가운데에 보면 텍스트가 하나 있는데 인게임 골드 변수의 주소다. 둘이 일치하는 것을 확인할 수 있다.

 

그렇다면 궁금증은 풀렸다. 게임 가디언이 접근하는 변수의 주소와 실제 앱에서 할당받는 주소는 동일하구나!

 

3-1. 메모리 주소 접근 unsafe 코드

메모리 주소 접근하는 코드를 사용하기 위해서는 unsafe와 fixed 기능을 사용해야 한다.

 

아래 게시물을 참고하자

https://ajh322.tistory.com/223

 

유니티 오류 Unsafe code may only appear if compiling with /unsafe. Enable "Allow 'unsafe' code" in Player Settings to fix this error.

유니티에서 메모리 주소에 접근하는 코드를 사용하면 unsafe 관련하여 아래 에러가 발생한다. Unsafe code may only appear if compiling with /unsafe. Enable "Allow 'unsafe' code" in Player Settings to fix..

ajh322.tistory.com

 

4. 게임 가디언 VS 안티 치트 변수 암호화 기능

이제 본 게임 시작 안티 치트에서 제공하는 변수 암호화 기능을 사용하고 게임 가디언으로 뚫으려고 하면 어떻게 될지 확인해보자

 

먼저 변수 암호화 기능(obscured)에 대하여 알아보자

그냥 기존에 쓰던 데이터 타입에 Obscured를 붙여주면 된다. 그러면 알아서 암호화가 된다. 암시적 형 변환도 되기 때문에 불편함 없다.

그러면 코드가 위에처럼 int에서 ObscuredInt로 바뀐다.

그것뿐이다.

얼마나 간편한가!

 

그러면 이제 암호화를 했는데 게임 가디언으로 한번 메모리 변조를 시도해보겠다.

암호화를 하면 해커들이 못 찾을 거라고 하는데 과연...

 

오... 정말로 못 찾는다!

 

하지만 게임 가디언의 암호화된 값 검색을 하면 어떻게 될까?

 

 

검색 결과가 하나 나온다. 특이한 점은 80을 검색했는데 444,492라는 값을 찾아온다.

 

뚫린다... 조금 허무하네...

일단 그냥 검색이 막히기는 하지만 여전히 게임 가디언에 손쉽게 뚫린다.

 

여기서 안티 치트의 말도 한번 들어보자

대략 unknown value 검색에 의하여 암호화가 뚫릴 수 있다고 경고한다. 그렇기 때문에 암호화된 값을 바꿔줘야 한다는 말이다.

암호화 된 값을 바꾸는 기능은 Obscured 객체에 딸려있는 RandomizeCryptoKey 함수를 이용하면 된다.

 

4-1. 안티 치트 obscured 변수 암호화 원리

암호화 값을 바꿔주는 기능을 사용해보기 전에 obscured 변수 암호화에 대한 간단한 원리를 짚고 넘어가 보자

암호화란 평문을 특정 알고리즘에 의하여 암호화된 값으로 바꿔주는 것을 의미한다.

 

실제로 안티 치트에서 실 데이터에 대하여 암호화를 시키면 특정 알고리즘에 의하여 값이 바뀌고 메모리에는 암호화된 값이 저장된다. 그리고 필요할때만 복호화하여 원래 값으로 되돌려서 사용하고 다시 암호화 시켜서 암호화 된 값으로 저장해놓는 것이다.

 

 

444536이라는 암호화 된 값이 100이라는 실제 값을 가지고 있다.

그리고 해당 값을 가지고 있는 변수에는 암호화 된 값을 들고 있다.

 

게임 가디언에서는 아래와 같은 방법으로 암호화 된 값을 찾아낸다고 한다.

게임 가디언 개발자인데 호그와트에서 배운 마법으로 찾는다고 설명한다. 대단하다.

원리는 암호화가 보통 xor 연산으로 이루어지는데 그 방법을 뚫는 방법이 있다고 한다.

구글에 how game guardian detect encrypted value라고 검색하면 내용이 많이 나온다.

 

5. 게임 가디언 VS 안티 치트 변수 암호화 기능 강화 버전

그러면 단순 암호화로는 게임 가디언에게 쉽게 뚫린다는 것을 감안하여 암호화 값을 랜덤으로 바꿔주는 기능을 사용해보도록 한다.

이렇게 되면 1초마다 inGameGold의 암호화 값이 랜덤 하게 값을 가지게 된다.

즉 게임 가디언 입장에서 암호화 키가 되는 값이 확실하지는 않지만 특정 값이라고 가정하여 값을 찾다가 암호화 값이 완전히 바뀌어버리면 데이터를 놓치게 되는 것이다.

 

RandomizeKey를 사용할 때마다 실제로 암호화된 값이 계속해서 바뀐다.

 

그리고 게임 가디언에서 암호화 된 값 검색을 하여도 도중에 찾지 못한다고 나온다.

오... 안티 치트의 승리다.

 

하지만 메모리 주소에 대한 직접적인 변조는 막지 못한다.

아마 더 고도화된 메모리 변조 방지 기법은 직접 메모리 변조하는 것까지 막아야 한다고 생각한다.

 

5-1. 개발 도중 이상한 점(슈뢰딩거의 암호화)

상자 안에 1시간 뒤 50%의 확률로 죽을 수 있는 고양이가 있는데 고양이는 1시간 뒤 살았을까 죽었을까?

갑자기 뭔 개소리냐 싶은데 ㄹㅇ 슈뢰딩거 고양이 뺨치는 상황이 발생했다.

 

5번의 랜덤 암호화 기능을 구현하고 있는데 RandomizeKey 함수를 통하여 암호화 값을 랜덤 값으로 바꾸고 나서 암호화 값이 바뀌었는지 안 바뀌었는지 확인하기 위해 encrypt 값을 받아와서 라벨에 표출해주었다.

 

일단 먼저 GetEncrypted 함수를 통하여 hiddenValue(암호화 값) 값을 가져온다.

그러면 ApplyNewCrpytoKey 함수를 거치는데...

 

ApplyNewCryptoKey 함수의 내용은 위와 같다.

currentCryptoKey와 cryptoKey가 다르면 암호화 값을 cryptoKey로 암호화한 값을 넣어버리는 것이다.

currentCryptoKey는 randomizeKey를 하면 새로운 값으로 바뀌는데 cryptoKey는 바뀔 일이 절대 없다. 다시 말해서 if문은 항상 참이라는 것이다.

아마도 에셋 개발자가 암호화 값 확인을 할 때 헷갈리지 않도록 암호화 값을 받아오면 무조건 원래 암호화 키로 다시 암호화를 해주는 것 같다.

즉 암호화 값을 확인하고 싶어서 확인하는 순간 랜덤 암호키로 바꾼 암호화 값이 랜덤 하지 않은 단 하나의 암호키로 바꾼 암호화 값으로 초기화되는 것이다.

실제로 내가 테스트하면서 GetEncrypted를 계속해서 호출했는데 랜덤 암호화가 제대로 되지 않아서 랜덤 암호화 기능을 사용하였음에도 불구하고 게임 가디언에 뚫렸다.

관측하지 않은 상태에서는 암호화가 제대로 되고 있지만 관측하려는 순간 암호화가 풀려버리는 그런 것이다. 중요하지는 않지만 나중에 테스트한답시고 나처럼 허튼짓 하지 않기를 바란다.

 

6. 게임 가디언 VS 메모리 변조 디텍터

안티 치트에서 제공하는 기능 중에 메모리 변조를 시도를 탐지하는 기능이 있다고 한다.

 

원리는 암호화되지 않은 변수 값을 일부러 노출시키고 유저가 그 값을 바꾸면(해당 값을 바꿔도 실제 값은 바뀌지 않음) 메모리 변조를 시도했다고 판단하는 것이다.

가짜 덫을 만들어 놓는 것이다.

 

게임 오브젝트에 Obscured Cheating Detector를 만들어두고 Detection Event에 함수를 달아놓는다.

게임 매니저에 GotchaBitch 라는 함수를 달아놓았다.

 

이 함수를 발동시키면 텍스트를 GotchBitch!로 바꾸게 된다.

 

한번 이 기능을 넣어보고 게임 가디언으로 메모리 변조를 시도해보겠다.

 

암호화하지 않고 검색을 하면 가짜 값을 찾을 줄 알았는데 못 찾는다.

 

Randomize를 돌리지 않고 Obscured만 사용한 뒤, 암호화 검색을 하면 가짜 값이 나온다. 그래서 가운데 보면 텍스트가 바뀐 것을 알 수 있다. 근데 진짜 값도 탐지가 가능해서 해킹도 되고 해킹 감지도 된다. 좋지 않은 상황이다.

 

암호화된 상태에서 Randomize까지 작동시키면 아무것도 못 찾는다. 차라리 이게 나은 것 같다.

 

7. 결론

 

기본 Int

ObscuredInt

ObscuredInt + RandomizeKey

변조 가능

O

O

X

디텍터 반응

 

O

X

각 상황별로 게임 가디언으로 해킹을 시도했을 때 결과는 위와 같다.

 

 

메모리 변조와 관련된 게시물

게임 가디언 설치, 사용 방법

게임 가디언 사용 방법 - 실제 게임 해킹

유니티 메모리 변조 방지 - 안티 치트

반응형
반응형

유니티 프로젝트를 공유하거나 버전관리를 하다보면 한가지 의문이 생기는 부분이 있다.

라이브러리 폴더가 왜 그렇게 용량을 많이 먹는거고 꼭 있어야하는건지, 라이브러리 폴더는 어떻게 해야할지 의문이 생겨서 확인해보고 결과를 찾았다.

결론만 얘기하자면 라이브러리 폴더는 반드시 있어야한다.

 

목차

1. 유니티 오피셜

2. 웹상의 의견

3. 본인 경험, 회사 상사 의견

 

 

1. 유니티 오피셜

라이브러리 폴더가 무엇을 하는 것인지는 유니티 오피셜을 인용하자면

"Unity는 에셋 폴더에 추가하는 파일을 읽고 처리하여 파일 콘텐츠를 데이터의 내부 게임 레디 버전으로 변환합니다. 실제 에셋 파일은 수정되지 않은 상태로 유지되고 처리 및 변환된 데이터 버전은 프로젝트의 Library 폴더에 저장됩니다.

이 폴더는 캐시 폴더와 유사하다고 생각할 수 있습니다. 사용자는 라이브러리 폴더를 수동으로 변경하지 않아도 되며, 변경하려고 하면 Unity 에디터에서 프로젝트의 기능에 영향을 미칠 수 있습니다. 하지만 프로젝트가 열려 있지 않은 라이브러리 폴더를 Unity에서 언제든지 안전하게 삭제할 수 있습니다. 이 폴더의 데이터는 모두 에셋 및 ProjectSettings 폴더에 저장된 데이터로부터 생성되기 때문입니다. 따라서 라이브러리 폴더를 버전 관리에 포함시켜서도 안 됩니다."

간단하게 생각하면 프로젝트의 캐시데이터를 저장하고 라이브러리 폴더를 굳이 버전관리에 포함 안해도 ProjectSettings나 Asset폴더에 세팅값이 있어서 캐시데이터가 다시 생성되기 때문에 버전 관리에 포함 시켜서 안된다(왜 안해도 된다가 아니라 하면 안되는것처럼 표현했지)고 적혀있다.

https://docs.unity3d.com/kr/current/Manual/BehindtheScenes.html

 

씬의 기반 작업 - Unity 매뉴얼

Unity는 에셋을 자동으로 임포트하고, 에셋을 임포트하는 데 사용할 임포트 설정과 프로젝트 전반에서 에셋이 사용되는 위치 같은 에셋에 대한 다양한 추가 데이터를 관리합니다. 아래에는 이 프로세스가 진행되는 방법이 설명되어 있습니다.

docs.unity3d.com

여기까지 보면 Library 폴더는 없어도 무방한 것처럼 보인다.

라이브러리 폴더가 겁나 크기 때문에 걸리적 거리기도 한다. 나 같은 경우는 라이브러리 폴더만 2~3GB한다.

 

2. 웹상의 의견

대충 찾아보면 웹상 의견도 없애도 되고 어차피 알아서 생성되니까 필요없다고 한다.

Library 폴더에 대한 웹상의 의견

대부분은 삭제해도 괜찮음, 버전관리에서 포함시킬 필요없음.

이라고 한다.

 

3. 본인 경험, 회사 상사 의견

사실상 이 글의 핵심인데 내가 말하고자 하는 것은 다르다.

일단 나의 경험상으로는 분명히 Library를 삭제해도 된다고 나와 있어서 프로젝트의 Library 폴더를 삭제하고 다른 팀원한테 프로젝트를 공유해봤더니 특정 데이터의 Inspector의 값이 제대로 안들어가져 있어서 프로젝트가 정상적으로 돌아가지 않았다. 그래서 Library 문제가 맞는지 다시 한번더 전부다 압축해서 보낸뒤 구동해봤더니 정상적으로 구동됐다.

따라서 Library 폴더를 삭제하면 Cache 데이터가 100% 일치하지 않음을 확인했기 때문에 유니티의 공식 답변, 웹상의 의견과 다르게 항상 Library 폴더를 공유해야함을 확인했다.

 

이와 더불어서 회사 상사분께 내가 겪은 문제와 웹상에서 찾아본 내용으로 질문을 하니 본인도 항상 Library 폴더를 같이 공유하고 있다고 하였다.

 

결론 : 라이브러리 폴더는 필요하다.

 

ps : 근데 라이브러리 폴더 압축안하면 2~3gb지 압축하면 수백mb로 용량 줄어드니까 그냥 하자

반응형
반응형

문제

문제의 메인 씬

자꾸 특정 씬으로 넘어갈 때 지연이 발생했다.

하지만 해당 씬에서는 문제가 될만한 스크립트도 없고 별 이유가 없어서 프로파일러를 켜서 확인해봤다.

 

프로파일러 내용

프로파일러로 확인해봤더니 File.Read에서만 2000개의 인스턴스가 생성되어서 지연되는 것으로 확인되었다.

하지만 나는 스크립트 상에서 파일을 읽는 부분은 전혀 넣지 않았는데 전혀 짚이는 것이 없었다.

 

게임에서 세이브 로드하는 부분을 전부다 주석 처리해봐도 효과는 없었고, 프로파일러 자세하게 돌려봐도 딱히 나오는 거 없었다.

결국 모든 오브젝트, 스크립트를 하나씩 삭제를 하면서 원인을 찾았다.

 

원인

원인은 특정 오브젝트에서 ScriptableObject(이하 SO)를 매우 많이 불러서 발생하는 문제였다.

이 SO를 엄청나게 많이 부르는 것도 문제지만 씬을 로드할 때마다 해당 오브젝트도 새로 생성되어서 약 1초 이상의 지연이 발생하는 것이었다.

헷갈릴만한 것이 유니티에서 인스펙터로 끌어다가 넣어주는 SO는 저렇게 잡혀서 잘 몰랐던 것이다.

 

이런 식으로 SO가 SO를 불러오고 그 SO가 또 다른 SO를 불러오고... 엄청난 지연이 발생할 만하다. 멍충아

렉이 저것밖에 안 걸리는 게 더 신기하다.

 

해결

SO를 대량으로 부르는 게임 오브젝트를 인스턴스, 싱글턴화, DontDestroyOnLoad 하여 게임을 시작할 때만 불러오고 이후로는 계속해서 오브젝트를 유지하는 방식으로 대체하였더니 해결되었다.

그리고 해당 문제를 겪어보니 게임에서 불러와야 하는 대량의 데이터가 있는 경우 게임을 로딩하거나 시작할 때 일괄적으로 불러오고 메모리에 항상 저 데이터를 들고 있다가 필요할 때 바로바로 꺼내와서 사용해야 한다고 생각이 들었다.

요즘 최적화와 오브젝트 풀링에 대해서 공부하고 있는데 좋은 경험이 되었다.

반응형
반응형

목차

1. 개요

2. 차이점

2.1 불러오는 이미지 차이

2.2 Sprtie Packer 비활성화 여부

2.3 카메라의 2D뷰 3D뷰

2.4 Directional Light 오브젝트

2.5 카메라 위치와 시점

2.6 환경 변경

3. 참고자료

 

 

 

1. 개요

유니티에서 프로젝트를 새로 생성할 때 2D 프로젝트와 3D 프로젝트를 고르는 옵션이 있다.

항상 어떤 차이가 있는지 정확히는 모르고 주변 사람들한테는 '아 그거 어차피 비슷하니까 뭘로 해도 상관없어요 그냥 3d로 하세요' 이런 식으로 말하곤 했는데 이번 기회에 정확하게 차이가 무엇인지 알아보고자 한다.

미리 결론을 말하자면 차이는 없으나 기본적인 세팅 정도만 달라진다.

 

 

2. 차이점

2D 프로젝트와 3D 프로젝트 차이점에 대하여 유니티에서 공식적으로 올라와 있는 내용

이미지를 불러올 때 텍스쳐로 불러올지 스프라이트로 불러올지 카메라 시점이 다르다 등의 내용

더욱 구체적으로는 아래와 같이 차이가 발생한다고 적혀있다.

 

2D vs 3D mode settings

2D or 3D mode determines some settings for the Unity Editor. These are listed below.

In 2D Project mode:

  • Any images you import are assumed to be 2D images (Sprites
    ) and set to Sprite mode.

  • The Sprite Packer
     is enabled.

  • The Scene View
     is set to 2D.

  • The default game objects do not have real time, directional light.

  • The camera
    ’s default position is at 0,0,–10. (It is 0,1,–10 in 3D Mode.)

  • The camera is set to be Orthographic. (In 3D Mode it is Perspective.)

  • In the Lighting Window:

    • Skybox
       is disabled for new scenes
      .

    • Ambient Source is set to Color. (With the color set as a dark grey: RGB: 54, 58, 66.)

    • Precomputed Realtime GI is set to off.

    • Baked GI is set to off.

    • Auto-Building set to off.

In 3D Project mode:

  • Any images you import are NOT assumed to be 2D images (Sprites).

  • The Sprite Packer is disabled.

  • The Scene View is set to 3D.

  • The default game objects have real time, directional light.

  • The camera’s default position is at 0,1,–10. (It is 0,0,–10. in 2D Mode.)

  • The camera is set to be Perspective. (In 2D Mode it is Orthographic.)

  • In the Lighting Window:

    • Skybox is the built-in default Skybox Material.

    • Ambient Source is set to Skybox.

    • Precomputed Realtime GI is set to on.

    • Baked GI is set to on.

    • Auto-Building is set to on.

 

 

더욱 자세하게 알아보도록 하자

 

2.1 불러오는 이미지의 차이

왼쪽 2D 오른쪽 3D

두 프로젝트 똑같은 이미지를 Asset 폴더에 넣었는데 2D에서는 기본적으로 Sprite로 불러오고 3D에서는 Default로 지정된다.

2D에서는 매우 편리하게 드래그하면 2D 이미지로 사용하는 등 스프라이트로 바로 사용이 가능하다.

 

2.2 Sprtie Packer 비활성화 여부

Sprite Packer

스프라이트 팩커는 스프라이트를 효율적으로 사용할 수 있도록 해주는 것인데 2D에서는 기본적으로 활성화되어있고 3D에서는 기본적으로 위의 이미지처럼 비활성화되어 있다고 한다.

하지만 확인해보니 둘 다 비활성화 처리되어있었다.

 

2.3 카메라의 2D뷰 3D뷰

왼쪽 2D 오른쪽 3D

2D의 경우 2D버튼이 눌려있어 기본적으로 2D뷰가 활성화되어있고 3D는 꺼져있어서 기본적으로 3D뷰로 보인다.

시각적인 차이라서 큰 차이는 없어서 2D 프로젝트 3D 프로젝트 둘 다 번갈아가며 사용하는 기능이다.

 

2.4 Directional Light 오브젝트

왼쪽 2D 오른쪽 3D

3D에서는 기본적으로 Directional Light 오브젝트가 생성되어있다.

 

2.5 카메라 위치와 시점

왼쪽 2D 오른쪽 3D

2D의 카메라는 기본적으로 Y값이 0이고 3D 카메라는 1이다.

또한 2D는 Projection이 Orthographic이고 3D는 Perspective이다.

Perspective는 기본적으로 현실적으로 원근감이 반영되는 것으로 대부분의 3d 게임에서 사용하는데 위의 말대로 3D 프로젝트 환경에서 2D 게임을 만들기 위해서 카메라 시점을 Orthographic으로 바꾸어서 사용하기도 한다.

 

2.6 환경 변경

왼쪽 2D 오른쪽 3D

프로젝트를 잘못 만들었거나 설정의 변경이 필요하다면 Edit > Project Settings > Editor > Default Behavior Mode를 바꿔주도록 하자.

 

 

3. 참고자료

https://forum.unity.com/threads/difference-between-2d-and-3d-projects.554728/

 

Difference between 2d and 3d projects

hi guys i know the difference between 2d and 3d obviously but what implications does this have on creating a project for either? the space shooter...

forum.unity.com

https://unity3d.com/difference-between-2d-and-3d-games

 

Create 2D and 3D games with Unity - Unity

You have a full-featured professional toolset in Unity to create both 2D and 3D games. Get an intro to how to do it.

unity3d.com

 

반응형