프로그래밍. 참조


파이어베이스 플러그인 참조

https://www.youtube.com/watch?v=709LvIXq6NE

https://github.com/danielhampikian/firebase-unity/blob/master/testapp/Assets/LoginToDatabase/DatabaseHandler.cs


도움받은 Udemy 강좌 

Wilmer Lin Game Developer / Visual Effects Artist 

https://www.udemy.com/level-management-in-unity/learn/v4/overview 

https://www.udemy.com/make-a-puzzle-match-game-in-unity/  



그래픽. UI 스프라이트, 그래픽 모델링

UI sprite

low Poly UI Kit - v.1.1c, Purchased from (Unity Asset Store)

https://assetstore.unity.com/packages/2d/gui/low-poly-gui-kit-104144


3D character model    

KUBIKOS - Cube Mini Animals,  Purchased from (Unity Asset Store)

https://assetstore.unity.com/packages/3d/characters/animals/kubikos-22-animated-cube-mini-animals-100696


 Tile Block Model  

LowPolyWooden Pack nature-kit, (CC0 1.0) license

https://kenney.nl/assets/nature-kit


Block items

LowPoly_Pixel_RPG_Assets_DevilsGarage_v01.unitypackage, (CC BY-NC 3.0) license

https://devilsworkshop.itch.io/low-poly-3d-and-pixel-2d-rpg-game-assets



폰트. 출처 & 라이센스

  

Pixel-Miners

low Poly UI Kit - v.1.1c, Purchased from (Unity Asset Store)

https://assetstore.unity.com/packages/2d/gui/low-poly-gui-kit-104144


VCR OSD Mono by Riciery Leal, (100% free) dafont.com 

https://www.dafont.com/vcr-osd-mono.font


College by Matthew Welch, (100% free) dafont.com 

https://www.dafont.com/college.font


Visitor by Enigma(100% free) dafont.com 

https://www.dafont.com/visitor.font


True Crimes by Walter Velez(100% free) dafont.com 

https://www.dafont.com/true-crimes.font


Edo SZ  by Vic Fieger(100% free) dafont.com 

https://www.dafont.com/edo-sz.font



사운드. 출처& 라이센스

BGM-


Ending  엔딩 테마  

GroundWork by Kevin MackLeod, (CC BY 3.0) license

https://soundcloud.com/kevin-9-1/groundwork

               


Failure  스테이지 실패 효과음 

Sad Fanfare by Kevin MackLeod, (CC BY 3.0) license

https://soundcloud.com/kevin-9-1/sad-fanfare



bgm-Play 게임 플레이 배경음 

Rainbows by Kevin MackLeod, (CC BY 3.0) license

https://soundcloud.com/kevin-9-1/rainbows



bgm-Intro  인트로 씬 배경음

Old Music Box 1 by Soughtaftersounds, (CC BY 3.0) license

https://freesound.org/people/Soughtaftersounds/sounds/145434/  

Copyright © 2011 Varazuvi™ www.varazuvi.com


bgm-Lobby  메인화면 배경음

Happy_Theme.wav by maxmakessounds, (CC BY 3.0) license

https://freesound.org/people/maxmakessounds/sounds/353543/


bgm-Login   로그인 화면 배경음  

electronic-music-loop-001-Accurate time by frankum, (CC0 1.0) license

https://freesound.org/people/frankum/sounds/387440/


bgm-Success 스테이지 클리어 효과음 

Super Dialogue Audio Pack v1 - miscellaneous_4_karen

https://stuckeast.itch.io/sdap 


UI-


ui-swith  유아이 버튼 스위치

click by Taira Komori, CC BY 3.0 license

https://freesound.org/people/Taira%20Komori/sounds/212520/


ui-SoundCheck  

new recordings 2013 2014 » click 1.WAV by milton, (CC0 1.0) license

https://freesound.org/people/milton./sounds/244450/


ui-loginSuccess (Royalty Free Music)

Sms alert 3 daniel simon

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


ui-Access 

Menu1C

UI and Item Sound EffectsPurchased from (Unity Asset Store)

https://assetstore.unity.com/packages/audio/sound-fx/ui-item-sound-effect-jingles-30508


ui-Interrupt

Super Dialogue Audio Pack v1 - miscellaneous_2_meghan

https://stuckeast.itch.io/sdap


ui-ButtonNext


MenuMove by UI and Item Sound EffectsPurchased from (Unity Asset Store)

https://assetstore.unity.com/packages/audio/sound-fx/ui-item-sound-effect-jingles-30508


ui-buttonError 

Computer Error by Mike Koenig, (CC BY 3.0) license

http://soundbible.com/1127-Computer-Error.html  


ui-buttonClick 

Knive Blade Vibrations ANd Glitches by shnur_, (CC0 1.0) license

https://freesound.org/people/shnur_/sounds/337015/


ui-MenuBack

MenuBack by UI and Item Sound EffectsPurchased from (Unity Asset Store)

https://assetstore.unity.com/packages/audio/sound-fx/ui-item-sound-effect-jingles-30508


SFX


sfx-allClear 

success by grunz, (CC BY 3.0) license

https://freesound.org/people/grunz/sounds/109662/


sfx-BlockDrop 

Memu selection Click by NenadSimic, (CC0 1.0) license

https://freesound.org/people/NenadSimic/sounds/171697/


sfx-ClickNegative 

hint by dland, (CC0 1.0) license

https://freesound.org/people/dland/sounds/320181/


sfx-ClickPositive 

Beep 05 Positive by PaulMorek, (CC0 1.0) license

https://freesound.org/people/PaulMorek/sounds/330052/


sfx-coinDrop 

coin2 by Skirox, (CC0 1.0) license

https://freesound.org/people/Skirox/sounds/167564/


sfx-coinPickup

Collect normal coin by Cameeno Rossley, (CC BY 3.0) license 

https://freesound.org/people/Cabeeno%20Rossley/sounds/126412/


sfx-Failure 

negative_beeps by themusicalnomad, (CC0 1.0) license

https://freesound.org/people/themusicalnomad/sounds/253886/


sfx-GameReady

Super Dialogue Audio Pack v1 - miscellaneous_9_meghan 

https://stuckeast.itch.io/sdap


sfx-InformSign 

Hit2 by Triper, (CC0 1.0) license

https://freesound.org/people/Triper/sounds/115792/


sfx-ItemDrop 

Drip2 by kwahmah_02, (CC BY 3.0) license 

https://freesound.org/people/kwahmah_02/sounds/260620/


sfx-ItemTouch 

CollectCoin by bradwesson, (CC0 1.0) license

https://freesound.org/people/bradwesson/sounds/135936/


sfx-MoverCrash 

Selection_04 by distillerystudio, (CC BY 3.0) license 

https://freesound.org/people/distillerystudio/sounds/327739/


sfx-MoverEnter

beeps-18 1 by Greencouch, (CC BY 3.0) license 

https://freesound.org/people/Greencouch/sounds/124899/


sfx-MoverSpawn 

toy button by fins, (CC0 1.0) license

https://freesound.org/people/fins/sounds/191590/


sfx-MoverTurn

sfx_3_mo by deleted_user_2195044, (CC BY 3.0) license 

https://freesound.org/people/deleted_user_2195044/sounds/164705/


sfx-Success 

Success 03 by rhodesmas, (CC BY 3.0) license 

https://freesound.org/people/rhodesmas/sounds/322930/






이 프로젝트에선 위 두가지 경우(이메일/익명)에 대해 다룹니다. 초기 세팅 작업은 ( http://ongoing-yang.tistory.com/category/Programming/SDK )

블로그 SDK 카데고리에 소개되어 있습니다.




Firebase.Auth


toggle code

LoginCanvas - 이메일 로그인/ 익명 로그인 / 이메일 형식 오류 체크


Firebase.Database



toggle code 데이터 쓰기

SetRawJsonValueAsync - NewResistration() 신규 계정 등록


toggle code 핸들러 구독

ValueChanged += 데이터가 변경되었을 때의 이벤트 수신


toggle code 리더보드 기록 갱신

RunTransaction - 다중 업데이트시 비손실 정보 처리 


toggle code 데이터 읽기

GetValueAsync -  snapShot -> jsonData -> 로컬 저장 


게임 개발 과정에서 수시로 추가되고 수정이 빈번한 사운드 resource 같은 경우 처음부터 다수의 자원을 효과적으로 다룰 관리방법이 중요하다

모바일 포트폴리오 정도를 다루는 간소한 프로젝트에서는 리소스가 많아봐야 100개를 넘을리 없지만 실제 대규모 프로젝트에서는 그보다 훨씬

많은 분량을 고려해야하기 때문에 사운드 리소스를 식별하는 해시맵을 작성해야 할 것이다. 


지금 프로젝트에서는 그와 유사한 개념으로 유니티 친화적인 scriptableObject를 사용하여 사운드 타입을 BGM과 UI, SFX 별로 구별하였습니다.

확장메서드로 enumType을 인덱스화하면 오디오메니저에서 식별할 수 있는 타입을 인자로 받아 사운드를 재생하고 관리되도록 설계하였습니다.


오디오매니저에는 Volume Fade In/Out을 구현하여 씬 시작시 필요한 부분에서 부드러운 사운드 전환을 연출할 수 있도록 하였고, 

게임 pause Canvas를 열 때 Backgroud music 에 대해서만 중지 속성값을 주어 보다 자연스러운 UI 반응 구성하도록 하였습니다.




Sound.source


toggle code

SoundSource - ScriptableObject


toggle code - BGM / SFX / UI


toggle code - None 예외 처리 사용 이유


Sound.AuidoManager


toggle code

AudioManger - 사운드 관리 매니저 클래스 (사운드 타입 접근 인덱스화, 볼륨 Fade in /out 구현)

musicSource(BGM)와 soundSource(SFX , UI) 구분 -  SoundSource pause Ignore // pause canvas 활성화 시 BGM만 pause






캔버스의 형태는 단순한 이미지 요소의 집합체가 아닌 씬의 흐름과 그 맥락을 같이하며, 이미지 속성이 일종의 정보 역할을 하는 그룹화된 객체 영역이기도 합니다. 이것은 공통된 방법으로 손쉽게 꺼내쓰고 언제든 재활용할 수단이 제공되어야 함을 말합니다.

이것에 가장 알맞은 자료구조는 Stack이라고 생각하여 UI Canvas 구조를 Stack을 활용해 설계하였습니다.


미리 참조된 Canvas List로부터 해당하는 Canvas를 찾아야 할 때 (for문이나 foreach문을 사용해 순회하지 않고) index로 바로 접근하는 게 최적화 측면에서 유리하다고 생각하기에 Stack에 저장되고 식별하는 정보로 클래스 참조가 아닌 Canvas들에 부여된 고유 식별 인덱스 넘버(int 자료형)를 사용했습니다.


CanvasManager에서 canvas 객체들은 인스턴스되고 초기화 이후, 참조 리스트에 enumType에서 지정한 순서대로 재정렬됩니다. 

(Linq와  Extension메서드 사용)  

유니티 에디터 상에서 순서없이 프리팹을 리스트에 넣어도 실행이후 Type 순서에 맞게 정렬이 되고 검색 후 매칭에서 올바르게 작동하도록 합니다.

(작업 내용이 변경되거나 추가될 경우 보다 유연하게 대처할 수 있고 협업에 어울리는 방식이라고 생각했습니다.)


또한 캔버스들은 On/Off 시키는 과정이 매번 빈번하게 일어나므로 최적화를 위해 하나의 캔버스가 켜질 때 다른 모든 캔버스를 꺼지게 하는 방법은 

(모든 오브젝트를 순회하여 일일이 gameObject.SetActive(false);하는 게 아닌) deligate Event로 처리하였습니다.

즉 하나의 캔버스가 새롭게 켜지는 과정에서 다른 캔버스가 enable 되어 있다면 그 당사자만이 이벤트를 듣고 이후 스스로  disable 상태가 됩니다. 


Canvas panel 내부 이미지 버튼에 대한 인터렉션은 에디터 상에서 메서드와 직접적으로 연결시키지 않고 버튼 필드와의 연결점만 열어놓았습니다.

_playButton.onClick.AddListener(() => OnClickPlay());  이후 이와 같은 방식으로 실제 구현에 대한 정보는 스크립트를 통해 알 수 있도록 하였는데

이것은 버튼과 관련한 메서드 내용에 대해 리펙토링을 쉽게 하고 스크립트를 확인했을 때 정보에 대한 가독성을 높일 수 있다고 생각합니다.


* UI 파트 최적화 (모바일 빌드 후 테스트해보니 발열이 엄청 심하다)  

UGUI Text -> Unity 2018에 기본 플러그인으로 들어온 TextMeshPro로 전환 , string.Format() 사용

UI sprite -> packing Tag 꼭 지정해줄 것 , Mip Maps 설정 해제  등 


UserInterface.Cnavas


toggle code

CanvasUI - UI Canvas의 부모 클래스 


toggle code

CanvasManager - canvas stack 자료구조로 관리


toggle code

LobbyCanvas - 메인메뉴 캔버스 


toggle code

OptionCanvas- 유저 게임 옵션 세팅 캔버스


toggle code

ScoreCanvas - 유저 점수와 리더보드 디스플레이 캔버스


toggle code

PlayCanvas - 게임 플레이 씬 HUD 정보 디스플레이 캔버스


toggle code

Pause - 게임 일시 정지 캔버스


toggle code

Success - 스테이지 클리어 후 미션 성공  디스플레이 캔버스


toggle code

ClearedCanvas - SuccessCanvas의 부모



Scene.level Mangement


toggle code

LevelSceneManager - 게임의 Scene Load 와 종료를 담당 / 모든 씬 로드는 Fade Animation 효과를 주기 위해 코루틴 메서드 안에서 동작합니다.





GameLevelManager.levelProperty 와 레벨 아이템 로드


VertexBlock.충돌 체크 옵저버

<오브젝트 풀 구현>


오브젝트 풀에 들어가는 개체는 (나중에 새롭게 추가될 여지가 다분한 ) 게임 리소스의 일종이라 생각하기 때문에 

리소스 관리에서의 편리성을 도모하였습니다. (에디터 상에서 쉽게 프리펩 샘플을 할당 시키고 동일한 방식으로 접근이 가능하도록 함)

즉 모든 GameObject 타입에 대해 enumType으로 세부 분류가 정해지면 동일한 방식으로 모든 오브젝트에 대한 PoolList가 만들어 집니다.


유니티 에디터 상에서 오브젝트풀 매니저 클래스에 컨테이너 (scriptableObject)의 형태로 순서에 상관없이 컨테이너 리스트에 끼워 넣기만 하면 -> 

컨테이너의 스펙(enumType과 그에 해당하는 분류 index, size , size에 따른 컨테이너 저장소)에 따라 초기화 구간에서 희망하는 PoolSize에 맞게 

게임 오브젝트가 컨테이너 안 저장소(List)에 적재됩니다.




BodyMover 전용의 poolController 에서 pool에 적재된 오브젝트를 꺼내오는 명령어를 실행하여 해당 게임 오브젝트를 언제든 사용할 수 있습니다.



ObjectPool. 관련 클래스


toggle code

PoolItem 


toggle code

PoolContainer 


toggle code

SpawnPoolList 


toggle code

ObjectPoolManager 



Mover. 오브젝트 스폰 컨트롤러 / 스폰 오브젝트 대상


toggle code

SpawnController - 오브젝트는 게임 시작 시점 또는 게임 중간에 스폰하게 되는데 부드러운 움직임의 등장 효과를 주기 위해 포물선 회전 등 다양한 코루틴 메서드 구현


toggle code

BodyMover - 매카님 애니메이션 전환 처리와 주로 enable과 disable 사이에 초기값 설정에 대한 변수할당을 다룬다.




Title. 스폰 이후 움직이기 직전까지의 과정


Spawn 컨트롤러는 초기화 과정에서 모서리에 해당하는 부분 -> rotatorBlock의 Transform을 배열로 참조합니다.

(이들 transform의 자식객체로 면의 ClockWise 방향과 CounterClockWise를  가리키는 방향 벡터가 포함되어 있습니다.)

어느 쪽이든 물체 스폰 이후, random으로 위치하여야 할 포지션이 정해지면 스폰(Vector3.zero) 지점에서 해당 포지션으로 

포지션 이동과 로테이션 회전을 다루는 코루틴이 실행됩니다. 

Quaternion.Lerp() 메서드에서 사용되는 파라미터 값인 time은 미리 정의해둔  int 형 확장 메서드에 의해 계산 되어 리턴됩니다.

(SmoorherStep과 Exponential 그리고 PalabolaMethod 등을  적절히 혼용하여 자연스러운 움직임을 구사하도록 하였습니다.)

스폰 직후에는 충돌을 감지하는 센서가 반응하면 안되기에 센서인 본체 active 직후 자식객체가 활성화 되기 까지 약간의 시간딜레이를 두었습니다.


애니메이션을 다루는 메카님 전환 상태는 enumType Propoerty를 사용해 타입 값을 입력했을 때 SetTrigger하여 해당 전이가 손쉽고 

코드상에서는 가독성있게 보여지도록 구현했습니다. 최적화를 위해 애니메이터 파라미터 접근은 string이 아닌 Animator.StringToHash("")로 하였고

mover 객체의 이동속도에 대한 애니메이션 전이를 (walk-run)블렌드 트리로 구성하여 속도 변화에 따른 모션 또한 부드럽게 연결되도록 하였습니다.



holeBlock 관련 클래스 다이어 그램

 

유저의 조작감과 관련된 내용으로 그룹으로 분리되어 떨어져있는 HoleBlock두개가 On 되었다는 표시가 되면 물체를 양쪽 어느 한 관문으로 

보내어 연결된 다른 HoleBlock으로 텔레포트시키는 것이 주 목적입니다. 이것을 구현하기 위해 큐 자료구조를 사용했습니다. 

 

기본 사항은 클릭과 활성화 변화 상태가 징검다리 식으로, 새로운 hole을 클릭 할 때마다 기존 클릭 된 두 곳에서 먼저 클릭된 것이 사라져야 합니다.

 

<일반적인 경우>

 

<기존 선택 재클릭>

 

<나중 선택된 곳 -> 같은 그룹 내 위치 변경 (큐 순서 변경 없음>

 

<이전 선택된 곳 -> 같은 그룹 내 위치 변경 (큐 순서 변경 있음) >

 

 

씬이 실행되고 초기화 과정 이후 유저의 플레이 조작 단계에서는 가비지컬렉터 유발을 최대한 억제하도록 하고 최적화 효율을 높이고자 하였습니다.

이를 위해 supervisor에서는 하위 controller에 대한 접근 방법으로 개별 인덱스(int 자료형) 값을 사용하며 

controller 역시 그룹내의 holeBlock에 접근 가능한 방법으로 인덱스(int 자료형)를 사용합니다. 

enqueue와 dequeue 가 이루어 질 때 메서드 내부에서 각 holeBlock 정보에 접근하고 정보를 교환하는 작업은 모두 int 인덱스를 통해 검색이 되며

Supervisor - Controller - holBlock 트리개념에 의하여 각 하위에 해당하는 활성 비활성 상태의 block 정보를 모두 탐색할 수 있기 때문에 

보다 빠르고 효율적인 반응을 기대할 수 있습니다.

 

hole을 클릭하면 이벤트로 결합된 holeContrller에 신호를 보냅니다. 이 컨트롤러들 끼리의 통신을 다시 상위개념인 Supervisor 클래스에서 관리합니다. 

 

 

그림에서의 경우처럼 그룹으로 분리된 두 영역의 Block이 하나씩 체크가 되면 -> (isSelected == true)  서로 링크로 연결된 것으로 간주되어 

물체가 해당 selected된 곳 중 어느 한곳에 도착 시  다른 한 곳으로 텔레포트 할 수 있는 조건이 성립합니다. 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

큐브 면 위를 이동하는 개체는 단지 앞방향으로만 이동되며,  transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime); 

특정 collider를 만나 센서의 trigger 조건에 부합하면 개체의 회전을 변경하여 다음 방향을 컨트롤하게 됩니다. 


개체의 방향이 변경되는 경우의 수는 다음과 같습니다.


<holeBlock> 


  • 텔레포트 이후 -> 해당 holeblock 으로 이동  -> 이동 지점 holeblock이 바라보는 단일 방향
  • 텔레포트 실패 -> 이동 전 지점 holeblock이 바라보는 단일 방향 ==  들어왔던 방향과 반대방향 (back으로 이동)
<rotatorBlock>


  • 안쪽 면 모서리 부근을 지날 때 -> 물체가 향하는 방향의 down 방향 (단일 방향)

<PlaneBlock 의 방향 요소>


  • planeBlock(우회전)을 만나면 물체가 향하는 방향의 right 방향  (단일 방향)
  • planeBlock(우회전)을 만나면 물체가 향하는 방향의 left 방향  (단일 방향)


  • Slash  ---> ? 단일 방향이 아니다 -> 물체가 들어가는 진입 방향에 따라 달라진다.)
  • backSlash  ---> ? 단일 방향이 아니다 -> 물체가 들어가는 진입 방향에 따라 달라진다.)


case 5 까지는 목표가 되는 쿼터니언 회전이 단일 방향이므로 Quaternion.LookRotation(회전해야 할 단일 방향) <- 이것으로 쉽게 다음 방향을 

예측할 수 있습니다. 하지만 결국 6,7과 같은 경우에 대하여 변하는 방향에 대한 처리를 원하는대로 해주기 위해서는 진입 시 오브젝트가 가지는 방향성을 기술하여 표현할 수 있어야 하고 이것은 boolean 변수 2개를 추가하여 각 변화에 대한 모형을 4가지 타입별로 제시해야 함을 의미합니다.



움직이는 오브젝트 객체는 큐브 공간에서 매우 많은 충돌 조건에 노출되어 있고 빈틈없이 모든 일들을 처리해야 하므로 회전운동에 관여하는

모든 trigger 조건은 효율을 높이기 위한 방편으로 compareTag가 아닌 layer로 감지할 수 있도록 하였습니다. 

또한 한 프레임이 돌아가는 찰나에 block 요소들의 충돌 조건을 움직이는 개체쪽에서 감지하게 될 텐데 이 감지를 구별하는 

조건을 한곳에 모아두지 않고 각 타입별 조건을 전용 센서에서만 담당하도록 Sensor 역할의 자식객체를 하위에 여러개로 분업화해

부하를 최대한 분담하도록 하자는 논리로 설계하였습니다. 



TriggerSensor.회전 충돌 감지 (모든 상속 센서는 이동 코루틴 메서드와 회전 코루틴 메서드를 사용)

부모센서 클래스에는 해당 중심 좌표까지 물체를 이동하도록 하는 포지션 이동 코루틴 메서드와

해당하는 회전으로 물체를 회전하도록 하는 트랜스폼 로테이션 코루틴 메서드가 구현되어 있습니다. 

코루틴 진입 이전에 mover의 translate 이동은 잠시 제한될 것이며 모든 과정이 끝났을 때 다시 이동을 재개합니다.



toggle code

RotatorSensor  -

Quaternion.LookRotation(bodyTransform.TransformDirection(Vector3.down), bodyTransform.forward); 

- 아래로 회전 할 때 객체의 위 방향은 직전의 앞방향이 기준이 됩니다.



toggle code

HoleSensor

Quaternion.LookRotation(bodyTransform.TransformDirection(Vector3.back), bodyTransform.up); 180도 뒤로 회전할 곳을 바라보고 회전합니다. 



toggle code

PlaneSensor  plane면상에서 방향을 결정하는 directionItem 을 만났을때 -> (시계방향 반시계방향 Slash, BackSlash) 각 경우에 대한 회전 방향 결정 메서드


구현 메서드의 실제 동작 모형 예시




#레벨 디자인 - 초기 컨셉






#레벨 디자인 - 확장성을 고려한 설계


LevelDesiner. Block 요소 배열 배치


toggle code:

보다 확장성 있는 디자인을 위하여 원하는 size 별로 큐브의 전체 크기를 조정할 수 있어야 하며, 배열 배치 reference를 통해 접근의 용이성 마련



#레벨 디자인 - Block 타입의 상속 개요




Block. 부모 추상 클래스




구현 코드에 전체적으로 사용 될 enum Type과 Extension Method에 관내용입니다.


Extenstion.Method


toggle Extension Method


Enumeration.type


toggle 레벨 디자인, movement , lerpType


toggle 유저인터페이스 , 씬/오디오 매니저


+ Recent posts