이 글은
https://www.inflearn.com/course/유니티-게임-프로그래밍-에센스
강의를 요약한 강의노트 입니다.
유니티를 처음 접하시는 분들이거나 좀 더 기반을 다지고 싶으신 분들에게 👍강력하게 추천합니다.
Synchronous(동기)
Synchronous(동기) :
간단히 설명하면 이전 수행이 끝날 때까지 다음 수행은 대기를 하는 것이다.
일반적인 함수는 Synchronous(동기)로 실행이된다.
아래 foo함수를 보자.void foo(){ A(); B(); C(); }
foo함수는 아래와 같이 순차적으로 return을 만나야 다음 코드가 실행된다.
1. A실행 ➡️ return;
2. B실행 ➡️ return;
3. C실행 ➡️ return;
따라서 Synchronous(동기)란
이전 수행이 끝날 때까지 다음 수행은 대기를 하는 것이다.
Asynchronous(비동기)
Asynchronous(비동기) :
간단히 설명하면 이전 수행이 끝나든 상관없어 다음 수행이 바로 수행되는 것이다.
코루틴 함수는 Asynchronous(비동기)로 실행이된다.
따라서 위 foo함수가 Asynchronous(비동기)로 실행된다면,
A, B, C가 거의 동시에 실행이된다.
따라서 비동기로 수행을 한다면
어떤 시점에 여러 작업이 동시에 처리되는 멀티쓰레드 프로그래밍을 구현할 수 있다.
유니티가 지원하는 기능으로 우리는 이를 통해
처리와 처리사이의 대기시간 넣거나, 여러 처리를 동시에 병렬로 실행이 가능하는 등의 작업을 할 수 있는 것이다.
IEnumerator (코루틴 함수 이름)() : 코루틴 함수 생성시 타입
StartCoroutine() : 코루틴 실행하기
StopCoroutine() : 코루틴 멈추기
yield : 일반 함수의 return과 비슷한 것
yield return new WaitForSeconds() :
괄호안 해당하는 시간만큼 실제시간 대기
yield return null : 한 프레임 대기
StartCoroutine()과 StopCoroutine()사이에는 매개변수로 코루팀 함수를 string타입의 이름으로 넣거나 함수를 넣을 수 있다.
두 차이점은 string타입으로 넣으면 StopCoroutine()을 사용해 인위적으로 멈출 수 있다.
아래 HelloCoroutine코드를 보고 비동기와 동기에 대해 자세히 보자
public class HelloCoroutine : MonoBehaviour
{
void Start()
{
StartCoroutine("HelloUnity");
StartCoroutine("HiCSharp");
Debug.Log("End");
}
IEnumerator HelloUnity()
{
Debug.Log("Hello");
yield return new WaitForSeconds(3f);
Debug.Log("Unity");
}
IEnumerator HiCSharp()
{
Debug.Log("Hi");
yield return new WaitForSeconds(5f);
Debug.Log("CSharp");
}
}
일반적인 우리가 생각한 결과는
Hello -> 3초뒤 -> Unity -> Hi -> 5초(총 8초)뒤 -> CSharp -> End
일 것이다.
하지만 실제 결과는
Hello -> Hi -> End -> 3초뒤 -> Unity -> 5초(5초)뒤 -> CSharp
와 같이 실행된다.
이것이 비동기 이다.
아래 코드에서 만약 HelloUnity함수가 코루틴이 아닌 일반함수였다면 무한루프로 인해 다음문장이 수행되지않는다.
하지만, 코루틴으로 선언했기 때문에 HiCSharp코루틴 함수와 End가 출력이 되고 마우스 좌클릭을 통해 코루틴을 종료시키는게 가능하다.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HelloCoroutine : MonoBehaviour
{
void Start()
{
StartCoroutine("HelloUnity");
StartCoroutine("HiCSharp");
Debug.Log("End");
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
StopCoroutine("HelloUnity");
}
}
IEnumerator HelloUnity()
{
while (true)
{
yield return new WaitForSeconds(3f);
Debug.Log("Hello Unity");
}
}
IEnumerator HiCSharp()
{
Debug.Log("Hi");
yield return new WaitForSeconds(5f);
Debug.Log("CSharp");
}
}
일반함수의 경우 대기시간이 없어 우리가 인지할 새도 없이 바뀌어버린다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Fade : MonoBehaviour
{
public Image fadeImage;
// Start is called before the first frame update
void Start()
{
FadeIn();
}
void FadeIn()
{
Color startColor = fadeImage.color;
for (int i = 0; i < 100; i++)
{
startColor.a = startColor.a - 0.01f;
fadeImage.color = startColor;
}
}
}
코루틴함수를 사용하면 1초의 시간에 걸쳐 함수가 실행되어 우리가 인지할 수 있다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Fade : MonoBehaviour
{
public Image fadeImage;
// Start is called before the first frame update
void Start()
{
FadeIn();
}
void FadeIn()
{
Color startColor = fadeImage.color;
for (int i = 0; i < 100; i++)
{
startColor.a = startColor.a - 0.01f;
fadeImage.color = startColor;
}
}
}
Color는 r = red, g = green, b = Blue, a = alpha로 구성된다.
에디터에서는 0 ~ 255의 범위를 가지지만,
코드에서는 퍼센트로 환산하여 0 ~ 1의 범위로 가진다.