DOTween 은 getter 와 setter 두 람다로 어떤 값이든 트윈한다
Esc

    DOTween 은 getter 와 setter 두 람다로 어떤 값이든 트윈한다

    2026년 9월 25일 수정–Unity라이브러리트윈
    IEnumerator MoveUpCo(Vector3 to, float duration)
    {
        Vector3 from = transform.position;
        for (float t = 0f; t < duration; t += Time.deltaTime)
        {
            float p = t / duration;
            transform.position = Vector3.LerpUnclamped(from, to, 1f - (1f - p) * (1f - p));
            yield return null;
        }
    }

    움직임 하나를 코루틴이나 Update 보간으로 만들면 시작값 기억, 경과 시간, 진행률, 이징, 적용이 매번 따라옵니다. 반복이나 되감기, 지연이 붙으면 더 늘어납니다. Animator 는 이 코드를 없애 주지만 도착점이 클립에 박혀, 실행 중에 정해지는 목표에는 쓰기 어렵습니다.

    DOTween 은 이 보간을 값의 종류와 상관없이 한 번만 짜 두고, 바꿀 값을 getter 와 setter 두 람다로 받습니다. 사용자는 무엇을, 어디까지, 몇 초 동안만 말합니다. 기준 판본은 DOTween 1.3.030(GitHub 커밋 4846808)입니다.

    움직임마다 짜던 보간을 한 번만 짠다

    같은 “1초 동안 위로 3 만큼, 끝에서 부드럽게” 를 네 방식으로 적으면 이렇습니다.

    코루틴과 Update 보간은 모양이 같고, 요구가 붙을 때마다 분기가 늘어납니다. DOTween 쪽은 끝값을 코드에서 계산해 넘기고, 이징과 반복을 한 줄씩 붙이며, 이 컴포넌트에는 Update 가 없습니다. 보간 코드는 라이브러리 안에 한 벌만 있습니다.

    바꿀 값은 두 람다로 받는다

    “어떤 필드든 트윈한다” 를 리플렉션으로 하면 느리고, DOTween 이 나온 2014년의 .NET 3.5 수준 Mono 와 iOS AOT 에서는 위험했습니다. 그래서 DOTween 은 값을 읽는 법과 쓰는 법을 델리게이트로 받습니다. transform.DOMove 는 그 두 람다를 대신 써 주는 확장 메서드일 뿐입니다.

    // DOTween/ShortcutExtensions.cs
    public static TweenerCore<Vector3, Vector3, VectorOptions> DOMove(this Transform target, Vector3 endValue, float duration, bool snapping = false)
    {
        TweenerCore<Vector3, Vector3, VectorOptions> t = DOTween.To(() => target.position, x => target.position = x, endValue, duration);
        t.SetOptions(snapping).SetTarget(target);
        return t;
    }

    라이브러리는 값의 이름도 주인도 모른 채 시간만 계산해 setter 를 부릅니다. 단축 메서드가 없는 값은 같은 모양으로 직접 넘깁니다.

    int score;
    DOTween.To(() => score, x => score = x, 1000, 2f);   // 0 에서 1000 까지 2초

    값은 제네릭 필드 T2 startValue, endValue, changeValue 에 들어가서 갱신 중에 박싱이 없습니다. 대신 트윈 하나를 만들 때마다 두 람다가 힙에 올라갑니다. 이 설계는 어떤 값이든 같은 엔진으로 돌리는 대신 만들 때 할당을 치르는 쪽을 골랐습니다.

    첫 트윈이 구동기를 세운다

    2014년에는 한 프레임의 단계에 끼어드는 PlayerLoop API 가 공개되지 않았습니다(2018.1 에 공개). DOTween 은 MonoBehaviour 하나를 만들어 그 Update 에서 모든 트윈을 돌리고, 그 오브젝트는 첫 트윈을 만드는 순간 생깁니다.

    DOTween.Init() 을 직접 부르면 이 과정을 원하는 때에 미리 하고, 인자로 준 값이 설정 에셋보다 우선합니다. 부르지 않으면 첫 트윈이 대신 부릅니다. 사용자 컴포넌트에는 트윈을 돌리는 코드가 하나도 남지 않습니다.

    코어는 DLL, 유니티 모듈 코드는 .cs

    설치 폴더에서 코어는 DOTween.dll 이고, 그 옆 Modules 폴더의 DOTweenModule*.cs 는 소스 그대로입니다. 코어는 Transform, Vector3, Color 처럼 버전마다 거의 안 바뀐 타입만 써서 한 DLL 을 모든 유니티 버전에 줄 수 있습니다. Rigidbody, Image, AudioMixer 는 프로젝트에서 뺄 수 있고 API 가 바뀌므로, 사용자 프로젝트에서 컴파일되는 .cs 로 빼고 define 으로 감쌌습니다.

    종류 define 기본
    유니티 내장 시스템 DOTWEEN_NOAUDIO, DOTWEEN_NOPHYSICS, DOTWEEN_NOPHYSICS2D, DOTWEEN_NOSPRITES, DOTWEEN_NOUI define 이 없으니 켜짐
    외부 에셋이나 선택 기능 DOTWEEN_UITOOLKIT, DOTWEEN_TEXTMESHPRO, DOTWEEN_TK2D 등 꺼짐

    내장 시스템은 거의 모든 프로젝트에 있으니 “끄는 define” 으로 아무 설정 없이 켜 두고, 없는 프로젝트에서 켜면 컴파일이 깨지는 외부 에셋은 “켜는 define” 으로 둡니다. 코어는 모듈을 컴파일 시점에 알 수 없으므로 위 그림의 Awake 처럼 DOTweenModuleUtils 를 이름으로 찾아 초기화합니다.

    주의할 점

    1. 모듈 define 을 한 플랫폼에서만 손으로 지우지 않는다

    안 지키면 생기는 문제. Utility Panel 은 모듈 define 을 유효한 모든 BuildTargetGroup 에 같이 넣고, 모든 그룹에 있어야 “켜짐” 으로 봅니다. Player Settings 에서 한 플랫폼의 define 만 지우면 패널은 꺼졌다고 보여 주는데 다른 플랫폼에서는 그 모듈이 여전히 컴파일됩니다. 플랫폼마다 쓸 수 있는 확장 메서드가 달라져 한쪽에서만 빌드가 깨집니다.

    이렇게 쓴다. 모듈은 패널에서만 켜고 끕니다. 설정 에셋이 원본이라, 패널에서 바꾸면 에셋과 모든 플랫폼의 define 이 함께 맞춰집니다.

    2. DOTweenSettings 에셋을 Resources 밖으로 옮기지 않는다

    안 지키면 생기는 문제. 런타임은 첫 트윈에서 Resources.Load("DOTweenSettings") 로 설정을 읽습니다. 에셋을 Resources 가 아닌 곳으로 옮기면 찾지 못하고 코드의 기본값으로 돕니다. 패널에서 바꿔 둔 재활용, SafeMode, 로그 수준 같은 기본값이 조용히 빠집니다.

    이렇게 쓴다. 에셋은 Resources/DOTweenSettings 그대로 둡니다. 코드로 확실히 정하고 싶은 값은 DOTween.Init(...) 인자로 넘깁니다. 인자가 에셋보다 우선합니다.

    3. 기본 이징을 InOutQuad 로 알고 SetEase 를 빼지 않는다

    안 지키면 생기는 문제. DOTween.defaultEaseType 의 XML 주석은 InOutQuad 라고 적지만 실제 초기값과 설정 에셋의 기본값은 OutQuad 입니다. 주석을 믿고 이징을 비워 두면 천천히 출발할 것이라 기대한 트윈이 빠르게 출발합니다.

    이렇게 쓴다. 곡선 모양이 중요한 트윈에는 SetEase 를 명시합니다. 프로젝트 전체의 기본을 바꾸려면 설정 에셋이나 DOTween.defaultEaseType 을 게임 시작 때 정합니다.

    정리

    DOTween 은 보간을 한 번만 짜 두고, 바꿀 값을 getter 와 setter 두 람다로 받아 어떤 값이든 트윈합니다.

    • 코루틴이나 Update 보간에서 움직임마다 짜던 코드를 “무엇을, 어디까지, 몇 초” 한 줄로 바꿉니다. 값은 제네릭 필드에 있어 갱신 중 박싱이 없고, 대신 만들 때 람다를 할당합니다.
    • 첫 트윈이 DontDestroyOnLoad 오브젝트 [DOTween] 을 만들고, 그 MonoBehaviour 가 모든 트윈을 돌립니다.
    • 코어는 버전과 무관한 DLL, 유니티 하위 시스템에 기대는 코드는 define 으로 켜고 끄는 모듈 .cs 입니다.