나 개발자 진짜 되냐?

[ 11月 29日 ] 오늘 내가 배운 것 _ 54日次 _ Async란? Lamda 문법 정리 본문

오늘 공부를 정리해봐요!

[ 11月 29日 ] 오늘 내가 배운 것 _ 54日次 _ Async란? Lamda 문법 정리

Snow Rabbit 2024. 11. 29. 20:50

오늘은!

프레임 워크를 복습하며 짜보았다.

 

이번에는 비동기적 기능을 사용할 것이기 때문에

 

Async 기능을 사용할 것이다.

 

허엇 Async? 가 뭘까

 

함께 알아보자!

 


Async

메서드가 비동기로 실행될 것임을 선언하는 친구

 

특징1.

반드시 반환타입은 Task, Task <T> 여야 한다.

 

특징2.

Void 반환타입에는 async가 이벤트 처리에만 사용해야 한다.

 

함께 사용되는 친구

Await도 있다.

 

Await

비동기 작업이 완료될 때까지 기다리는 친구

기다리는 동안 메인스레드가 차단되지 않고 다른 작업 계속 진행 가능



 

아니...

최근에 저 동기비동기를 배우면서

코코코코코루틴 배웠거든요..

 

그럼 코루틴을 쓰면 되는 거지

뭐 하러 어싱크인지 싱크대인지 뭔지를 쓰는 거죠?

 

Coroutine단순 비동기 실행에 적합

async/await더 복잡한 작업에 적합

 

 

아잇..

더 복잡한 작업이 뭔데요??

 

뭐.. 네트워크 요청이나

파일.. 가져오는 등등이고

 

 

코루틴은 그냥 2초 멈추기

3초 생각하기

4초 움직이기

등등 이런 것!

 

 

코루틴이 못하는데 어싱크대는 가능한 작업으로는

 

파일 읽고 쓰기

데이터베이스 요청

네트워크 통신

다중 비동기작업 등등등

 

카콜라루틴은 심지어

모노비헤이비어 없으면 못쓰는 친구이기 때문에..

유니티 엔진 내 작업에 쓸 때 적합

2초 멈추기 3초 춤추기

 

어싱크대는

비동기적으로 처리해야 하는 데이터 중심작업에 유리하다.

 

 


Scene을 바꿀 때 쓰는 함수를 만들어주었다.

 

Async를 사용하면서

씬을 로드하는 진행사항을 담아 둘 수 있다.

 

 

이렇게 해주면 별표친구들이 뜨는데

 

프로퍼티 / 메서드 설명 사례
progress 씬 로딩의 진행상황을 나타냄
0.0 - 1.0 사이로 표시되며 로딩이 완료될 수록 값이 증가
로딩화면에서 진행률 표시
isDone 씬 로딩이 완료되었는지 여부를 나타냄 true 가 되면 로딩 완! 씬 로딩 끝나고 특정 작업 실행
allowSceneActivation 씬 로딩 완료 후 자동으로 활성화 될 지 여부 설정
false로 설정하면 씬 로딩이 완료되어도 활성화 X
활성화 시 true로 변경해줘!
로딩 완료 후 사용자가 특정버튼 누르거나
조건을 만족 했을때 씬 활성화
로딩 화면을 유지하고 싶을때..?

 

 

우리는 일단 isDone를 사용할 것이다.

 

 

 

그렇게 해서!

 

만약에 끝나지 않았다면

로딩창 띄우기를 실행시키는 것이다.

지금은 디버그 해놨지만 넣으면 되겠다!

 

그다음 while문을 나와서

그다음에 callback을 실행시키면 된다.

 

여기서 callback에는 뭐 특정 애니메이션을 실행시키거나

데이터 초기화 등등

다양한 작업이 수행될 것이다.

 

즉, 씬이 완전히 로드된 후에!

수행할 추가 작업을 지정하는 용도로 사용된다!

 

 

여기서 문제는!

while문은 비동기가 아니기 때문에

while문 돌 때 다 멈춰버린다.

 

그래서 게임이 멈춰버리는 거처럼 보이기 때문에

우리는 이 함수 자체를 비동기로 돌릴 것이다.

 

그렇게 하는 방법은

 

public과 void 사이에

async를 넣어주면 된다!

 

그러면 이 자체가 비동기가 된다.

 

다음에 우리는

코루틴에 yield return null과 비슷한

 

await Task.Yield();을 넣어서

메인 스레드 차단 없이 다음 프레임까지 대기할 수 있도록 한다.

 

간단하게 말하면

 

아 일단 나 바쁘지만

내 차례 잠시 줄게! 유니티엔진 너도 할거 많지?

너 좀 해

내가 양보할게!

 

이런 느낌이다.

 

이렇게 해줘야

게임이 멈추거나 끊기는 것을 방지할 수 있다.

비동기 작업이 너무 오래 실행되면

프레임 드롭이 발생한다고 한다.

그렇기 때문에

 

Task.Yield를 통해

프레임마다 작업을 쪼개서 실행하면

게임이 멈추지 않는다고 한다.

 

 

자 이제

씬 두개 만들어서

하나는 인트로

하나는 게임

 

=> 꼭 씬을 만들면

안으로 들어가서 File > Build 해서 add Scene 해줘야한다!

 

 다

 

인트로 씬으로 들어가서

인트로 오브젝트를 만든다음 인트로 스크립트를 붙이고

 

 

씬 로드 하고!

 

버튼을 하나 만들어서

버튼에다가

 

 

넣고!

아!

왼쪽 하단에 넣을때에는

모양이 스크립트라서

스크립트를 넣는게 아니라!

 

스크립트가 달려있는 오브젝트를 넣어 주어야한다.

내가 자주 까먹어서 적어본다.

 

그럼!

 

- 완 -

 

어어!

지금까지 우리는

 

 

Single

혼자 왔니? 를 썼었다.

 

이번엔 둘이 가능한

Additive에 대해 써보자!

 

 

쉽게 비교하면

 

Single

열심히 롤드컵을 보던 나,

 

아이고 시간이 8시네

뉴스 볼 시간이구나 ♪

 

서열이 엄마보다 낮은 나는

롤드컵을 포기하고 뉴스로 돌린다.

 

=> 씬을 완전히 전환해야 할 때 사용,

이전 씬의 데이터는 유지하지 않아도 될 때 적합

 

내가 보던 롤드컵은 사라지고

뉴스만 화면에 띄워지게 됨

 

 

Additive

열심히 롤드컵을 보던 나,

 

아이고 시간이 8시네

뉴스 좀 틀어봐라

 

악!!! 안돼!!! 결승이란말이야!!!!

 

나의 외침에 엄마는 놀란다.

그래? 티원이 진짜 이길 수 있어?

 

나는 확신에 가득하며 대답한다.

신은 지지않아......

 

그렇게 한 티비로

롤드컵과 뉴스를 동시에 보게 되었다.

 

=> 씬을 동시에 표시해야하거나 데이터를 공유해야할 때 사용,

씬을 두개 분리하고 둘다 동시에 활성화 해야할 때

 

내가 보던 롤드컵과

엄마가 보던 뉴스가 추가적으로 표시

 

보통 이 경우는

현재 씬은 게임월드고

UI씬을 추가적으로 로드할 때 사용하는 편이다.

 

 

 

 

자 그러면 이제 아까 인트로 씬 스크립트로 돌아와서

single이 아니라

addtive로 바꿔보자!

 

 

흠 친절하게 마지막에는

유니티엔진 어쩌고

씬 매니지먼트어쩌고 저쩌고 해서 친절하게 알려준다

고대로 써주면 된다.

마지막에 우리는 저 single을 additive로 바꿔주면 된다!

 

마침 친절하게 알려준다.

 

 

이 중간에 있는 화살표가 궁금해지는 순간이다.

 

이 친구의 이름은 람다.

익명함수죠.

 

짧고 간결하게 함수를 정의할 수 있다.

 

Lamda

(parameters) => expression_or_statements;

 

중요한건

 

(parameters)

 함수가 들어올 공간

보통 매개변수가 없으면 비워 둔다.

그냥 함수가 들어갈 자리인데 여기는

() 이렇게 해주면 함수에 매개변수 없는거

 

=>

이녀석은 람다연산자로

매개변수와 함수 본문을 구분해주는 친구

 

이 뒤에

expression_or_statements;

 

그냥 함수의 본문 으로

식이 하나면 expression 그냥 쓰면 되고

만약에 여러문장이면 statements {}로 묶으면 된다.

 

예시로

 

(int x, int y) => x + y;

 

매개변수 x, y 그리고

식이 하나니까 그냥 쓴것

 

하지만 가장 중요한 정보가 있다.

 

바로 람다 이 친구는

델리게이트를 쓰기위해 나온 나름의? 전용 친구 인것.

 

델리게이트라는 친구가 나오면서 람다 함수가 나오다보니

절친이지만

영원한 짝지 까지는 아니다.

 

Action은 보통 반환값이 없을때 사용하고

 

반환값이 있을땐 Func를 쓴다

 

만약에 bool값이라면?

Predicate를 써준다.

 

Action printMessage = () => Console.WriteLine("Hello!");
printMessage(); // 출력: Hello!



Func<int, int, int> add = (x, y) => x + y;
Console.WriteLine(add(3, 4)); // 출력: 7



Predicate<int> isEven = x => x % 2 == 0;
Console.WriteLine(isEven(4)); // 출력: True

 

 

 


자..

대충 이해가 되었을지 모르겠다.

 

다시 아까로 돌아와서..

 

람다를 안쓰면

 

 

 

쓰면 이런느낌

 

한 30분 머리굴려 나온 생각을 정리하면

ChangeScene 메서드에서 callback?.Invoke();로 호출되며 람다 함수가 실행된다.

 

콜백 된 후 무언갈 실행시키고 싶은데

그냥은 안되고 함수로 받아서 해줘야해..

근데 함수 만들기 싫고, 길이는 짧으니 잠깐 쓰다 말 익명함수

Lamda로 하자!

 

그래서! 

람다를 써서 한다!

 

휴!!

 

 

두개로 이렇게 딹! 두개 Load 가능!

 

자, 이제 씬의 역할이 끝났으니

다시 Unload 해보자!

 

load 와 unload 둘다

loadManager에서 진행하자!

 

 

unload도 load와 똑같이 진행한다. 

 

 

자,

이렇게 해주면 로드 언로드 끝

 

 

특이한 문제가 발생한다.

 

우리는 싱글톤 덕분에

하이라키창에 manager든 뭐든

오브젝트가 없어도

시작을 누르면

자연스럽게 만들어지도록 만들었다.

 

하지만..!!

 

언젠가

싱글톤으로 만들어준 오브젝트 친구에게

(보통 매니저 친구들이겠죠?)

 

인스펙터창에서 무언가를 넣어줘야하는 상황이 생긴다면

 

싱글톤으로 만들어 둔 의미가 사라진다.

왜? 기존에 있던걸 지우고 다시 새로만들어 버리니깐..!

 

그래서 우리는!

 

제일 먼저 모든 메니저를 올려주는 씬을

위에서 배운

additive를 통해서 올려줄 것 이다.

 

 

 

해보자!

 

 

1. 먼저 Scene를 하나 만든다

DontDestroy로 만들어주었다.

* 빌드 해줘야합니다!!

 

여기 씬 안에는

 

 

각각의 매니저들이 잘 들어가있고

그에 맞게 스크립트도 잘 들어가있다.

 

그리고 

 

Game 씬 안에

GameScene이라는 오브젝트를 만들어주고

스크립트 붙여준다.

 

또 그림 오른쪽 처럼

 

씬 스크립트 파일안에

게임씬을 대표하는 오브젝트에 넣을 스크립트

GameScene.cs를 만들고

이 씬들을 관리할

SceneBase를 만들어준다.

 

자 SceneBase에 우리는 무슨짓을 해줄거냐!

 

 

 

일단 추상화 해주자!

다른곳에서 안쓸겨 나 껍데기여!

 

 

우리는 여기에다가 아까 배운

 

Additive를 사용해서 로드를 하고

다 로드 되면 다시 지울것이다.

 

이렇게 해주면 아까 만들었던

DontDestroy씬에 있던

매니저들이 다! 먼저 생성되게 된다!

 

먼저

 

 

불값을 하나 만들어주자,

 

이렇게 해주면

 

불값 자체가 false기 때문에

만약에 DontDestroy라는 씬을 호출한 적이 없다!

면 true가 되어서

 

함수에 진입하게 된다.

 

그러면 호출한 적이 없기 때문에 씬을 호출해주면 된다!

 

자 이 람다.....

녀석 안에 뭘 써주냐

콜백 되었기 때문에

이미 로드가 되었으니,

우리는 호출이 되었다는 뜻에서

DontDestroy를 trun로 바꿔주고

 unload 해주면 된다!

 

쉽나요!?

 

다음에 이렇게 만들어주었으니..

 

아까 위에 만들었던

IntroScene.cs와

GameScene.cs에다가

 

SceneBase를 상속해주면 된다!

 

그러면!

매니저들이 유지 되어있는 모습을 볼 수 있다!

 

일단 여기까지!해주면

매니저들의 예외처리는 어느정도 완료했다.

 

뭐..

고생했다

 

https://qua28.tistory.com/231

 

[ C# / 백준 ] 10699번 C# : 오늘 날짜

어제 헬로월드를 출력하며뿌듯함을 느낀 나 하지만 다음바로 막혀버렸다. 📖 문제 📖 오늘 날짜라..마음 같아서는 하드코딩 하고 싶은데힌트가 있다. date라는 친구를 썼다고 한다. 흠..모르

qua28.tistory.com

 

 

그렇지 고생했지 암암

우히히히ㅣ

롤체 하러가야지!!!!