레이어(Layer) : 오브젝트를 시스템적으로 분리하는 기능(피직스, 레이캐스트 등등)
레이캐스트(Raycast) : 보이지 않는 빛(Ray)을 투사해 닿는 물체를 파악하는 기능
태그 : 특정 오브젝트를 식별하기 위한 기능
🔨Layer
를 이용하여 Collider
가 있음에도 충돌을 무시시킬 수있다.
🔨 비트 연산자를 이용하여 Layer
를 좀 더 가볍게 탐색할 수 있다.
private void OnTriggerEnter2D(Collider2D coll)
{
if (Layer.value == (Layer.value | 1 << coll.gameObject.layer))
return;
}
/*
1. 'Layer.value'는 선택된 레이어의 비트 자릿수를 1로 반환 후 10진수 변환
(0번 ..0001 = 1 | 1,3번 ..1010 = 10)
2. 'gameObject.layer'는 인덱스를 반환한다. (0번 0, 1번 1)
*/
-- 레이어 충돌 --
if. 조건 1개 if. 다중 조건 | if.&(And)일 경우
조건 0010 0111 | 0111
타겟 | 0100 | 0010 | & 0010
or = 0110 = 0111 | = 0010
== 0010 == 0111 | == 0111
false true | false
// &(And)를 사용 할 경우 레이어가 다중으로 설정될 경우 오류가 발생한다.
🔨 레이캐스트를 이용한 해당 오브젝트 탐색.
RaycastHit2D[] tagets = Physics2D.LinecastAll();
= Physics2D.CircleCastAll();
= Physics2D.RaycastAll();
// 인자 값으로는 보통 '시작 위치, 거리, 방향, 레이어'를 전달한다.
// 타켓을 하나만 반환받을지 배열로 받을지도 중요한 선택지!
// 다양한 오버로딩을 지원하니 F12로 둘러보자!
📌 앞에 물체를 파악하고 피하는 것도 레이 캐스트를 사용한다.
오브젝트에 눈을 달아주는 기능이라고 생각하면된다.
📌 UI의 클릭을 인식하거나 스크린 좌표를 월드 좌표로 바꿔주는 것도 레이 캐스트를 이용한다.
🎉 한 장 요약
MVC패턴(Model, View, Controller) : 소프트웨어 디자인 패턴 중 하나로, 쉽고 편리한 유지보수를 위해 크게 컨트롤러, 모델, 뷰어로 나누어 구성하는 방법이다.
📌 컨트롤러 : 유저가 모델을 변경하기위해 입력하는 행위들
모델 : 데이터와 처리 로직들
뷰 : 스크린으로 볼 수 있게 출력하는 것들
📌 뷰어가 모델의 이벤트에 등록하여 관찰하는 것을 옵저버라고 한다.// 간단한 예시 string text = "Input : "; // 모델 text += Console.ReadLine(); // 컨트롤러 void print(string newtext) // 뷰 { Console.Clear(); Console.Write(newtext); } 우리는 컨트롤러를 통해 모델을 수정하고, 수정된 모델은 뷰를 갱신하고 우리는 본다.
🔨 그리하여 MVC를 이용한 프로젝트 UI구도 잡아보기
✅ MVC는 컨트롤러에서 모델 값을 수정하는 개념? 컨트롤러가 모델에게 요청하는 개념?
후자, 각자의 역할에 맞게 내부에서 처리해야한다.
🎉 내일에서 보낸 한 장 요약
Cocoa MVC패턴 : 어제 했던 게 알파이자 오메가인 줄 알았다..😔
하지만Cocoa MVC
가 오메가라는 거 ~ 무려 🍎 Inc에서 제시한 방법이다 깔깔~
다른 점은 모델과 뷰는 서로 알지못한 상태에서 컨트롤러를 통하여 소통한다.
🔨 그리하여 이번엔 Cocoa MVC
를 적용하여 인벤토리 UI를 만들어볼 것이다
컨트롤러에서 모델의 함수를 불러 리턴 값을 받아 뷰를 갱신하는 방법으로 코딩해볼 예정
MVC 패턴의 단점 중 하나인 컨트롤러의 비대화를 몸소 체험해보자!
🔨 기존 MVC패턴에서 Model
에서 View
로 인자를 전달하는 방식으로 수정
📌 기존 MVC패턴에서는 Model
이 커지면 View
와의 결합도를 주의해야한다는 것이
걱정이 되었다.
get { return gold; }
set
{
gold = value;
HUD.I.updateGoldHUD(); // Gold의 값을 필요로하는 'View'가 늘어난다면?
}
✅ Manager
, Controller
, Handller
등등 자주 쓰는 스크립트의 이름의 의미는?
🎉 한 장 요약
📌 먼저, 시퀀스 다이어그램은 객체간에 어떻게 상호 작용을 하고 있는지 나타내는 도표이다.
📌 시각화하면 뭐든지 그럴싸해보이는데 솔직히 MVC 패턴에 맡게 잘한 듯 🤭
📌 도표의 표기법은 틀렸을 수도 있지만 화살표는 정확하게 그렸다.
📌 확실히 유지보수를 하는데 있어 편리했다. 코드를 통째로 옮겨도 수정할 부분이
인스펙터에 옮긴 스크립트 할당 뿐이었고 오류가 나도 시작 함수만 잘 따라가면
디버깅 없이도 눈에 보일 정도로 직관적이었다.
📌 함수의 매개 변수들을 잘 사용해서 디버깅이 편해진 이유도 있을 듯
✅ Unity라는 프로그램을 쓰는 이상 모델과 뷰를 분리해도 어쩔 수 없이 엮이는 부분이 있다.
예를들어, sprite
를 바로 바꿀지 변수로 보관하고 View
에 맡길지..
Data
의 보관 위치가 View
와 연동된다면 그냥 Model
에서 처리하기로 했다.
🎉 한 장 요약 내가 느낀 컨트롤러의 역할
✨Git-Hub : https://github.com/Chu-Nyan/ProjectSpartaDungeonUnity
이번 과제는MVC 패턴
과EventTrigger
를 사용하여 UI들의 상호 작용을 구성하였다.
오로지 기능만을 구현한다면 2일이면 끝낼 수도 있는 과제였지만, 필수 구현마저도 시간이 부족했던 것 같다.
게임의 구조를 보다 넓게 생각하는 방법을 배우는 기간이었다고 생각한다.
📌 폴더와 이름 분류도 가독성에 중요한 역할을 한다.
📌 enum
을 사용하여 가독성과 데이터 분류를 하였다.
똑같은 아이템 클래스를 사용하여도 enum
의 값을 변수로 지정해주어 차별점을 주었다.
public class Item
{ public ItemType itemType; }
public class Equipment : Item
{ public EquipmentType equipmentType; }
public enum UIType
{ Status, Inven, SlotMenu, ScreenLog, Button, Defalut }
📌 이번엔 착용 아이템을 Dictionary
로 구현해보았다
enum
과 같이 쓰니 평생 실수 안 할 거같은 코드가 되었다. 근데 쫌 과한 느낌이다.
Dictionary
가 List
보다 메모리를 더 사용하는데 내가 구상 중인 게임에선 고민을
해보긴 해야할 것이다.
public Dictionary<EquipmentType, Equipment> equipmentList
📌 직렬화한 인스펙터를 꾸며주는 건 예기치않은 버그를 막고, 가독성을 증진 시킨다.
[Header("Base Stat")]
public string unitName = "";
public float maxHp;
[Range(0,99)]public int lv;
[Range(0f, 1f)] public float criticalChance;
// 크리티컬을 정수로 관리하는지 소수점으로 관리하는지 확실히 알 수 있고
// 잘못된 값을 넣는 일을 방지 할 수있다.
[Header("Current Stat")]
public float hp;
// 'maxHp'와 'hp'의 차이점을 명확하게 알 수 있다.
📌 업캐스팅을 한 상태에서 오버라이드한 함수를 호출하면 자식의 것이 호출된다.
🎉 한 장 요약
1. 코드 설계을 하다.
지금까진 하나의 기능을 만들기 위해 클래스를 만들고, 또 다른 기능을 추가할 땐 필요한 게 있으면 쓰고 없으면 또 만들고 이런 식으로 진행을 해왔다.
그러면 결국, 굳이 없어도되는 클래스들이 생겨났고 그로인해 원하는 함수를 찾기 위해 여정을 떠나야했고 기능들도 중구난방으로 흩어져 있었다.
하지만 게임이 커질 수록 코드의 유지보수도 생각을 하며 코드를 작성해나가야한다.
만들어져야할 클래스들의 역할을 부여하고 전체적인 통일성이 있어야지 한 달이 지나도 쉽게 읽을 수있는 코드가 될 것이다.
잎만 무성한 코드가 아닌 뿌리가 튼튼한 코드가 내가 만드려는 코딩 스타일이 아닐까?
2. 다양한 다이어그램
항상 애용해왔던 알고리즘 다이어그램을 넘어 시퀀스 다이어그램, 클래스 다이어그램을 작성해보았다.
화살표의 기능들은 무슨 말인지도 이해도 안 가고 시간도 부족해서 정확하지 않았다..😏
클래스 다이어그램의 경우 HUD 설계를 위해 작성하였지만, 그 후에도 전체적인 구조가 필요할 때 한눈에 보이는 게 상당히 도움이 되었다.
프로젝트가 진행 중일때도 계속 업데이트가 된다면 새로운 기능을 추가할 때 좀 더 통일성을 주면서 추가할 수 있을 것 같다.
시퀀스 다이어그램은 기능의 완성이 된 후 만들었다.
완성 전에는 어떻게 할지도 감이 안 잡혀서 아직은 작성이 어려울 거 같지만, 후에 작성을 하여 내가 원하는 대로 잘 만들어졌는지 확인하기에 상당히 좋았다.
아직 코드가 어색한 나로써는 시각적으로 다가오는 구조들이 상당히 도움이 되고 앞으로도 필요에 따라 계속 작성을 해가보자.
📌 기억해야 할 이번 주 키워드
- 인스펙터 정리
[Header("Stat")] : 변수들의 분류 이름
[Range(0, 10)] : 값의 범위를 지정
- 비동기씬 로드
다음 씬을 현재 씬에서 불러오는 방법
로딩화면에서 다음 씬 불러오기 뭐 이런 역할 인 거 같은데 다음에 자세히 알아보자