
오늘 학습 키워드
유니티 숙련 팀 프로젝트 발표
오늘 학습 한 내용을 나만의 언어로 정리하기
발표
우리팀 피드백
- 트러블 슈팅이 너무 글자가 많았다. 스크린샷, 움짤 등 그림이 더 많았으면 좋았을 듯
- 씬 이름 이니셜 절대 안됨. (지우기)
- Player, Monster는 한 스크립트에 너무 많은 기능이 들어가 있음. 좀 더 나누는게 좋음
- 동적 생성 UI 말고도 다른 것도 해서 씬 다이어트 하는게 좋음
- NavMesh 쓸때 SetDestination Update에 두지 말기
- 데이터 Json 활용하기
다른팀 아이디어
- 기온 시스템
- 내구도
다른팀 피드백
- BT 그룹을 나눠야 함
- 캔버스는 많을 이유가 없음
- 처음 시네마틱 하드코딩. 시네마틱 매니저 따로 만들기
- 효과음 딕셔너리로 저장하면 나중에는 불가능
챌린지 반 강의 (주제 : 델리게이트)
델리게이트?
- 하나의 로직에서 얼마든지 다른 값으로 사용할 수 있는게 변수.
- 이를 함수에 적용한게 델리게이트
- 함수에 대한 참조 타입. 함수를 변수처럼 저장하거나 매개변수로 전달할 수 있음
- 어떤 요청을 했을 때 그 결과를 처리하는 것을 만들 수 있음.(콜백)
- 1:1 관계에 유용
// 델리게이트 선언
delegate 반환형 델리게이트이름(매개변수)
// 예시
delegate void SpawnDelegateFunc();-
델리게이트에 사용될 함수는 반환형과 매개변수가 같아야 함
-
델리게이트 사용을 위한 순서
- 델리게이트를 선언함
- 델리게이트를 저장할 변수를 만듬
- 사용할 함수를 만듬
- 델리게이트 변수에 함수를 저장함
- 델리게이트 실행
델리게이트를 쓰는 이유?
- 확장성
class UIPopup
{
public delegate void PopupConfirmFunc();
// 반환형이 없고 매개변수가 없는 형태면 다 가능
public void PopupConfirm(PopupConfirmFunc confirmAction)
{
confirmAction();
}
}이벤트
- 델리게이트의 한 종류
- 옵저버 패턴과 유사하게 활용할 수 있도록 도와줌
- 델리게이트를 클래스/구조체 멤버에 표현하는 문법
- 외부에서 +/-만 할 수 있음
// 이벤트 구조 : 델리게이트 변수 앞에 event만 붙이면 됨
event 델리게이트이름 변수이름;- 이벤트를 등록해두면 필요한 함수들을 이벤트에 등록하고, 이벤트 발생 시 등록된 기능들을 전부 실행함
- 등록한 이벤트를 외부에서 실행할 수 없음.
- 1:N 관계에 유용
액션
- C#에서 제공하는 편의성이 증가한 delegate 타입
- 반환형이 Void인 델리게이트에 한해 만들 수 있고, 매개변수가 필요한 경우에는 뒤에 제네릭으로 추가함.
public delegate void MoveDelegateFunc(Vector2 moveVector)
// 아래와 같음
public event Action<Vector2> OnMoveEvent;- 액션에서 매개변수는 16개까지 추가 가능함.
편의성이 증가된 다른 델리게이트 타입들
- Action (많이쓰임)
- 반환값이 없는 델리게이트 타입
- 알림이나 콜백 처리에 편리함
public class UserManager : Singleton<UserManger>
{
private Action OnLogin;
public void Login(string id, string password, Action onLoginSuccess)
{
OnLogin = onLoginSuccess;
}
public void LoginDone()
{
OnLogin();
}
}- Func (많이쓰임)
- 반환값이 있는 델리게이트 타입
- 리턴값을 여러개 가지고 싶으면 클래스/구조체, 튜플 활용
- LINQ는 기본적으로 Func로 구성되어있음. Func<T,bool>
- 제네릭 맨 뒷자리가 리턴값임
- Predicate
- 반환값이 bool인 델리게이트 타입
- EventHandler (안쓰임)
- 이벤트를 다룰 때 표준으로 쓰이는 델리게이트 타입
알아두면 좋은 점
- 이벤트 사용후에 구독 해지는 필수!
- 안하면 GC가 안됨. 메모리 누수 방지 차원에서 꼭 해주기!
- 등록은 OnEnable(+=)
- 해지는 OnDisable(-=)
델리게이트와 패턴
- Action ←> Command
- Func ←> Strategy, Factory
- Predicate ←> Specification
- event ←> Observer
무명 메소드 / 람다
- 한 번만 쓰고 말 기능을 일일히 함수로 만들기에는 너무 번거로우니까 무명메소드가 나옴
- 근데 그마저도 귀찮아서 람다가 나옴
- 재활용이 필요할 때에는 기본 버전을 쓰고, 한 번 쓰이고 재활용 안되는건 그냥 람다 쓰기
// 기본
private Action<string> printName;
void Start()
{
printName = HelloName;
printName?.Invoke("Chad");
}
void HelloName(string name)
{
Debug.Log($"Hello, My Name is {name}")
}
// 무명 메소드화
private Action<string> printName;
void Start()
{
printName = delegate(string s)
{
Debug.Log($"Hello, My Name is {name}")
};
}
// 람다화
private Action<string> printName;
void Start()
{
printName = (s) =>
{
Debug.Log($"Hello, My Name is {name}")
};
}
챌린지 반 강의 (주제 : UI 기본)
- UI : 게임 위치에 상관없이 사용자 화면 위에 나오는 것
Canvas Render Mode에 대한 차이
- 만약에 캐릭터 위치에 따라 UI 위치가 달라야 한다면 (ex. 몬스터 체력) → Canvas Render Mode를 World Space로 바꿈. Scale 0.001 정도로 바꿔야 쓸만해짐
- UI와 3D 모델이 같이 보여야 한다면 → Screen Space - Camera 로 하고 Render Camera를 설정하고 Plane Distance를 적절히 설정해 주기
- 여러 캔버스 끼리는 Sort Order로 순서 정할 수 있음
해상도 대응 방법
-
Canvas Scaler → Scale With Screen Size
- Reference Resolution을 지정하면 됨
-
Rect Transform를 사용해서 Anchor, pivot을 지정하면 됨
UI 컴포넌트
Image
- Sprite로 변환된 이미지를 사용 가능
- 2D Sprite 설치하면 스프라이트 에디터 설정 가능
- Image Type : 이미지 가공을 어떻게 할 것인지
- Simple :가장 기본적인 방법. 별 다른 가공 없이 사용함
- Sliced : 라인 패치를 적용함
- 라인 패치 : 이미지를 9등분 해서 특정 부분은 유지하되 특정 부분은 줄이거나 늘릴 것을 설정
- 스프라이트 에디터에서 설정 가능함
- 최소 마지노선을 정해 두어야 함. 너무 작아지면 어쩔 수 없이 줄어듬
- Tiled : 원본 사이즈를 그대로 쓰되 타일처럼 반복함
- Filled : 값을 줘서 채워지는걸 표현 가능
Raw Image
- 유니티로 가져온 모든 이미지는 Texture 라고 불림
- 그래서 무슨 이미지이든 Raw Image 안에는 들어갈 수 있음
- 그닥 쓸 일은 없음
- 다만 가공할 수 없고 바로 가져와서 써야되는 경우에는 쓰임
Text
- TMP가 훨씬 성능이 좋음
InputField
- 글자 입력 가능함
- Content type에서 글자를 어떤 형식으로 표현할지 정할 수 있음
Slider
- Interactable 끄고 체력바 처럼 쓸 수 있음
- 최대값과 최소값을 정해줄 수 있어서 편함. 나누기 안해줘도 됨
Scroll View
- Viewport(보이는 부분) 안에 Content(데이터가 있는 부분)가 있음
Mask
- 이미지를 특정한 방식으로 자르고 싶을 때 씀
- 원하는 모양 아래에 원하는 이미지를 넣음
- 그리고 원하는 모양 부분에 Mask 컴포넌트를 넣음
- 그러면 원하는 모양만큼 이미지가 짤림
Layout Group
- 부모 오브젝트 안에 Layout Group 컴포넌트가 추가되면 아래에 알아서 자식 오브젝트가 정렬됨
- 정렬이 너무 띄워져 있음. 그러면 Child Force Expand를 끄면 됨. 그럼 앞에서부터 차례차례 쌓임
Content Size Filter
- 사용하는 레이아웃 그룹에 따라 다르게 설정하면 됨
- 만약에 수직 스크롤이다 → Vertical Fit 부분을 Min이나 Prefer로 변경
Canvas Group
- 하위의 오브젝트까지 동시에 다룰 수 있음
이벤트 시스템
- UI에 상호작용을 하도록 도와줌.
- 상호작용이 안된다면 보통 두 가지 문제 중 하나
- 씬에 이벤트 시스템이 없거나
- 캔버스에 Graphic Raycast Target이 없거나