본문 바로가기
사원 모아 사장

사원 모아 사장 개발 일지 (5) DynamicSequence를 이용한 눈 깜빡임 구현

by samosa 2024. 1. 8.

 

😶 캐릭터들이 너무 정적이야. 눈이라도 깜빡였으면 좋겠는데, 이 기능을 어떻게 넣으면 좋을까?

👾 이미지를 갈아 끼워야지.

😶 그럼 공통 기능이 될 수 있겠네. 눈을 깜빡이게 하는 기능이 아니라, 지정한 길이에 맞춰 이미지를 루프시키는 기능인 거야.

👾 여러 이미지를 루프시키는 로직은 DynamicSequence 클래스가 처리하자. 얘가 여러 이미지들을 들고 있으면 될까?

😶 생각해보니, 갈아끼우는 대상이 단지 이미지가 아닐 수도 있을 것 같아. 예를 들어 하나의 DynamicSequence가 있는데, 얘가 또 그 하위의 DynamicSequence를 갈아끼울 수도 있는 거잖아.

👾 그게 무슨 소리야?

😶 그러니까, 눈을 깜빡이는 시퀀스가 하나 있어. 그럼 이 시퀀스는 눈을 감은 이미지와 눈을 뜬 이미지를 들고 있겠지. 그런데 또 다른 하품하는 시퀀스가 있다고 쳐. 얘는 하품하려고 입을 벌리는 이미지랑 입을 닫은 이미지를 들고 있을 수 있는 거잖아. 그리고 더 상위에서는 기본적으로 눈을 깜빡이는 상위 시퀀스랑 하품하는 상위 시퀀스들을 더 상위에서 갈아 끼우면서 상태 관리를 하는 거야.

👾 그럼 DynamicSequence 클래스가 GameObject 타입인 TimedGameObjects들을 들고 있으면 되겠다. 각각의 tgo를 지정한 길이만큼 활성화시키고 다음 tgo로 넘어가는 거야.

private IEnumerator RunTimedObjects()
{
    while (timedGameObjects.Count == 0)
    {
        yield return null;
    }
    
    timedGameObjects.First().gameObject.SetActive(true);
    
    while (true)
    {
        foreach (var tgo in timedGameObjects)
        {
            tgo.gameObject.SetActive(true);
            if (useUnscaledTime)
                yield return YieldInstructionCache.WaitForUnscaledSeconds(tgo.GetVariedDuration());
            else
                yield return YieldInstructionCache.WaitForSeconds(tgo.GetVariedDuration());
            tgo.gameObject.SetActive(false);
        }
    }
}

 

👾 이 코드는 왜 이렇게 썼어?

😶 일단 Update 함수를 쓰지 않아서, 항상 매 프레임 실행하고 있는 상태가 아니야. 또 YieldInstructionCache로 코루틴을 캐싱하고 있지. 이런 건 코드 상의 최적화에 도움을 줄 수 있어.

👾 아하!