[Unity/C#]DOTween의 모든것

강동현·2024년 1월 2일
1

Unity/C#

목록 보기
11/26

1. DOTween?

1-1. Tweening

  • 시작 시점종료 시점을 설정해 위치/회전/크기 등의 값을 조정해 애니메이션을 쉽게 구현하는 기법
  • 모션과 비주얼 이펙트를 자연스럽게 동작하도록 한다.

1-2. DOTween

  • 유니티 환경에서 트위닝 기능을 지원하는 API
  • 내부적으로 최적화 기법을 사용해 유니티가 제공하는 일반적인 애니메이션/Transform 관련 함수/코루틴보다 향상된 성능을 보임
  • 성능상의 오버헤드를 줄이기 위해 custom update 함수를 사용한다.
  • [TIPS] 결론적으로 쉽고, 빠르므르 애용하자!
using DG.Tweening;

1-3. Tweener

  • 객체나 프로퍼티의 값을 조정해 애니메이션을 수행하는 주체
  • DO 계열 함수들은 Tweener를 리턴한다.
  • DOTween에서 행동의 주체

1-4. Sequence

  • 여러 트윈들을 그룹하해서 관리하고 수행하는 주체
  • 트윈들의 묶음이라 생각하면 된다.

1-5. Tween

  • 트윈시퀀스를 통용해서 부르는 명칭
  • 트윈 + 시퀀스

1-6. DOTween Component

  • DOTween다양한 컴포넌트에 적용 가능하다.
  1. transform
  2. Material
  3. Text/TMP
  4. Camera
  5. Light
  6. RigidBody/RigidBody2D
  7. AudioSource/AudioMixer(Unity5)
  8. LineRenderer
  9. SpriteRenderer
  10. TrailRenderer
  11. Outline
  • [중요]해당 컴포넌트의 모든 속성은 DOTween으로 Tweening 가능하다 알고 있음 편하다.

2. DOTween 함수

  • DOTween은 아래 계열 함수로 분리된다.

2-0. DOTween 기본 설정

2-0-0. DOTween.Init(bool recycle, bool useSafeMode, LogBehaviour logBehaviour, SetCapacity setCapacity)

  • DOTween 함수 기본 설정
  • 1. recycle: Tweener를 통해 함수 재사용 가능 여부 설정
  • 2. useSafeMode: 실행 중, 실행 대상이 파괴되는 등의 예외사항을 자동 처리(성능 감소 but always true)
  • 3. logBehaviour: 오류 메세지 기록 설정
  • 4. SetCapacity(Tweener 개수, Sequence 개수): Tweener 개수Sequence 개수를 설정
DOTween.Init(false, true, LogBehaviour.Verbose).SetCapacity(200, 50);

3. Tween을 만드는 방법

  • DOTween에서 Tween각 애니메이션을 수행하는 하나의 단위이다.
  • 즉, Tween을 통해 각 행동을 수행한다.
  • DOTween에서 Tween을 만드는 방식TO 계열DO 계열이 존재한다.

3-1. TO 계열

  • TO 계열 함수람다함수 사용법을 자세히 알아야 한다.
  • 람다함수를 통해 다양한 값의 트위닝을 수행
### 1. DOTween.To()
DOTween.To(시작값(getter), setter, 결과값, float duration);
DOTween.To(getter, setter, to, float duration);
//myFloat float 변수를 100f 값으로 1초동안 변화
DOTween.To(()=>myFloat, x=>myFloat = x, 100f, 1);
//myVector Vector3 변수를 Vector3(3,4,5) 값으로 10초동안 변화
DOTween.To(()=>myVector, x=>myVector = x, new Vector3(3,4,5), 10);
//현재 오브젝트의 position의 z값을 1부터 10까지 5초동안 변화시킨다.
DOTween.To(()=>1f, x=>transform.position = new Vector3(0, 0, x), 10f, 5f);
//myString에 ""부터 "hello, world!"라는 값을 3초동안 변화시킨다.
DOTween.To(() => "", str => myString = str, "hello, world!", 3);

3-2. DO 계열

  • 모든 트위닝 함수에 붙는 접두사
  • TO 계열 보다 직관적인 함수
  • DO는 대상의 변화를 지시
  • 타겟 값변화 기간, snap 여부가 인자로 들어감
  • Tween 타입을 리턴
  • snap 여부true로 설정할 경우 부드럽게 움직임
transform.DO-(100[endvalue], 5[duration(seconds)], true[snap]) //형태로 선언

3-2-1. Move 계열

DOMove(Vector3 targetPos, float duration)

  • curPos에서 targetPosduration 초 동안 이동
Vector3 targetPos = new Vector3(5, 5, 5);
transform.DOMove(targetPos, 5.0f);

DOLocalMove(Vector3 targetPos, float duration)

  • Local 이동으로 curPos에서 targetPosduration 초 동안 이동
Vector3 targetPos = new Vector3(5, 5, 5);
transform.DOLocalMove(targetPos, 5.0f);

DOMoveX/Y/Z(float targetPos, float duration)

  • curPos에서 특정 축(X/Y/Z)의 좌표가 targetPos가 되도록 duration 초 동안 이동
transform.DOMoveX(5, 5.0f);
transform.DOMoveY(5, 5.0f);
transform.DOMoveZ(5, 5.0f);
//위 코드는 동시에 수행되므로, (5, 5, 5) 영역으로 동시에 이동

DOLocalMoveX/Y/Z(float targetPos, float duration)

  • Local 이동으로 curPos에서 특정 축(X/Y/Z)의 좌표가 targetPos가 되도록 duration 초 동안 이동
transform.DOLocalMoveX(5, 5.0f);
transform.DOLocalMoveY(5, 5.0f);
transform.DOLocalMoveZ(5, 5.0f);
//위 코드는 동시에 수행되므로, (5, 5, 5) 영역으로 동시에 이동

3-2-2. Jump 계열

DOJump(Vector3 targetPos, float jumpPower, int jumpNum, float duration)

  • curPos에서 targetPosduration 초 동안 jumpPower의 힘으로 jumpNum번 점프하며 이동
Vector3 targetPos = new Vector3(5, 5, 5);
transform.DOJump(targetPos, 5.0f, 5, 5.0f);

DOLocalJump(Vector3 targetPos, float jumpPower, int jumpNum, float duration)

  • Local 이동으로 curPos에서 targetPosduration 초 동안 jumpPower의 힘으로 jumpNum번 점프하며 이동
Vector3 targetPos = new Vector3(5, 5, 5);
transform.DOJump(targetPos, 5.0f, 5, 5.0f);

3-2-3. Rotate 계열

RotateMode

  • 1. Fast(default): targetPos가 되도록 360도 미만의 최소 회전 값으로 회전한다.
  • 2. FastBeyond360: targetPos가 되도록 360도 이상의 최대 회전 값으로 (여러 바퀴) 회전한다.
  • 3. WorldAxisAdd: 월드 좌표계 기준으로 현재 회전값에서 벡터만큼을 더한다.
  • 4. LocalAxisAdd: 로컬 기준계 기준으로 현재 회전값에서 벡터만큼을 더한다.

DORotate(Vector3 targetRot, float duration, RotateMode mode)

  • Inspector 창에 Rotation 값targetRot 값으로 duration초 동안 변경
public Vector3 targetRot = new Vector3(90, 0, 0);
transform.DORotate(targetRot, 5.0f, RotateMode.Fast);

DOLocalRotate(Vector3 targetRot, float duration, RotateMode mode)

  • Local 회전으로 Inspector 창에 Rotation 값targetRot 값으로 duration초 동안 변경
public Vector3 targetRot = new Vector3(90, 0, 0);
transform.DOLocalRotate(targetRot, 5.0f, RotateMode.Fast);

DORotateQuaternion(Quaternion targetRot, float duration)

  • Quaternion 회전 방식으로 현재 Rotation 값targetRot 값으로 duration초 동안 변경
transform.DORotateQuaternion(Quaternion.identity, 5.0f);

DOLocalRotateQuaternion(Quaternion targetRot, float duration)

  • Local 회전으로 Quaternion 회전 방식으로 현재 Rotation 값targetRot 값으로 duration초 동안 변경
  • [TIPS] 작은 값을 회전시킬 때, 종료 지점에서 원치않는 흔들림이 발생할 경우 사용
transform.DOLocalRotateQuaternion(Quaternion.identity, 5.0f);

DOLookAt(Vector3 targetRot, float duration, AxisConstraint axisConstraint = AxisConstraints.None, Vector3 up = Vector3.up)

  • 물체의 Local 회전으로 Z축(설정 가능)이 해당 targetRot정면으로 바라보도록 duration초 동안 변경
public Vector3 targetRot = new Vector3(90, 0, 0);
transform.DOLookAt(targetRot, 5.0f);

DODynamicLookAt(Vector3 targetRot, float duration, AxisConstraint axisConstraint = AxisConstraints.None, Vector3 up = Vector3.up)

  • 지속적으로 위치가 변경되는 물체를 추적하기 위해선 본 함수 사용
  • 회전 목표매 프레임 계산
  • 물체의 Local 회전으로 Z축(설정 가능)이 해당 targetRot정면으로 바라보도록 duration초 동안 변경
public Vector3 targetRot = new Vector3(90, 0, 0);
transform.DODynamicLookAt(targetRot, 5.0f);

3-2-4. Scale 계열

DOScale(Vector3 targetScale, float duration)

  • curScale에서 targetScaleduration 초 동안 크기 변경
Vector3 targetScale = new Vector3(5, 5, 5);
transform.DOScale(targetScale, 5.0f);

DOScaleX/Y/Z(float targetScale, float duration)

  • curScale에서 특정 축(X/Y/Z)의 크기가 targetScale가 되도록 duration 초 동안 크기 변경
transform.DOScaleX(5, 5.0f);
transform.DOScaleY(5, 5.0f);
transform.DOScaleZ(5, 5.0f);
//위 코드는 동시에 수행되므로, (5, 5, 5)로 동시에 크기 변경

3-2-5. Effect - Punch

  • 펀치 한 대 때린 듯 이동/회전/크기 변경을 수행
  • punch: punch Vector 방향에서 펀치를 날림(반대편 이동)
  • vibrato: 얼마나 진동하는지를 결정
  • elaticity(0-1): 탄성 = 진동 범위(진동하는 범위가 어느정도인지 결정)
    0: punch Vector시작 위치 사이에서만 진동
    1: punch Vector반대 방향 사이에서만 진동

DOPunchPosition(Vector3 punch, float duration, int vibrato, float elaticity, bool snapping)

transform.DOPunchPosition(targetPos, 5, 10, 1, false);

DOPunchRotation(Vector3 punch, float duration, int vibrato, float elaticity)

transform.DOPunchRotation(targetPos, 5, 10, 1, false);

DOPunchScale(Vector3 punch, float duration, int vibrato, float elaticity)

transform.DOPunchScale(targetPos, 5, 10, 1, false);

3-2-6. Effect - Shake

  • 푸딩이 흔들리는 효과를 주며 이동/회전/크기 변경을 수행
  • [TIPS] 각종 충돌 시 흔들리는 효과 연출에 사용
  • strenth: flaot의 힘으로 진동 / Vector를 사용할 경우, 특정 축에 대한 흔들림**
  • vibrato: 얼마나 진동하는지를 결정
  • randomness(0-180): 흔들어지는 범위와 규칙성을 결정
  • faseOut: 흔들리는 효과가 점차 감소
  • randomnessMove: Full(전적으로 랜덤) / Harmonic(조화롭고 시각적으로 아름답게)

DOShakePosition(float duration, float/Vector3 strength, int vibrato, float randomness, bool snapping, bool fadeOut, ShakeRandomnessMode randomnessMode)

transform.DOShakePosition(1, 1, 10, 1, false, true);
transform.DOShakePosition(1, new Vector3(0, 0, 1), 10, 1, false, true);

DOShakeRotation(float duration, float/Vector3 strength, int vibrato, float randomness, bool fadeOut, ShakeRandomnessMode randomnessMode)

transform.DOShakeRotation(1, 1, 10, 1, false, true);
transform.DOShakeRotation(1, new Vector3(0, 0, 1), 10, 1, false, true);

DOShakeScale(float duration, float/Vector3 strength, int vibrato, float randomness, bool fadeOut, ShakeRandomnessMode randomnessMode)

transform.DOShakeScale(1, 1, 10, 1, false, true);
transform.DOShakeScale(1, new Vector3(0, 0, 1), 10, 1, false, true);

3-2-7. Material

  • DOColor: 색상(RGB)값 변환
  • DOFade: 투명도(Alpha)값 변환
.DOColor(Color to, float duration);
.DOFade(float to, float duration);

3-2-8. Text

  • Typing 연출
  • Fade IN&Out 연출
  • Color 연출
.DOText(string to, float duration, bool richTextEnabled = true, ScrambleMode scrambleMode = ScrambleMode.None, string scrambleChars = null);
.DOColor(Color to, float duration);
.DOFade(float to, float duration);

3-2-9. [번외]

  • 번외 기능 정리(나중에 공부 or 문서보고 개발)
  • DOPath 계열(DOPath, DOLocalPath)
  • Blendable 계열(DOBlendable[Move/LocalMove/Rotate/LocalRotate/Scale]By)
  • [Pro Only]DOSpiral

4. Set

  • Set은 Tween에 대한 설정을 수행
  • SET변화의 방식을 설정
Tween.Set-(...);
transform.DOScale(1.5f, 1.0f).SetLoops(3, LoopType.Restart);
  • SET여러 개한번에 설정하는 것이 가능하다.
transform.DOScale(1.5f, 1.0f)
.SetLoops(3, LoopType.Restart)
.SetId(1)
.SetEase(Ease.-)
.SetAutoKill(false);

SetAs(Tween tween, TweenParams tweenParams)

  • 설정 값을 빠르게 적용하도록 해줌
  • TweenParams 타입에 Set 값을 저장해넣고, 인자로 이를 넣어 적용
TweenParams tweenParams = new TweenParams()
.SetDelay(1)
.SetEase(Ease.Linear)
.SetRelative()
.SetSpeedBased();
object1.DOLocalMoveX(100,100).SetAs(tweenParams);
object2.DOLocalMoveX(200,200).SetAs(tweenParams);
object3.DOLocalMoveX(300,300).SetAs(tweenParams);

SetAutoKill(bool autoKillOnCompletion = true)

  • DOTween은 사용이 완료된 Tween자동으로 Kill메모리에서 해제
  • 즉, Garbage가 생성되고, 쌓이면, Garbage Collector가 작동하며 프레임이 끊길 수 있다.
  • AutoKill 기능을 꺼 영구적으로 메모리에 영구적으로 적재하고, Tweener 변수에 할당해 재사용한다.
  • 이를 통해 메모리 관리 측면에서 이득을 볼 수 있음
Tweener tr1 = transform.DOScale(1.5f, 2.0f).SetEase(Ease.InBounce).SetAutoKill(false);

SetEase(Ease easeType, AnimationCurve animCurve, EaseFunction customEase)

  • Ease: 변환 시, 움직임의 부드러움, 다양함을 주기 위해 사용하는 시간당 변화량 그래프를 의미한다.
  • 변화의 정도를 움직임에 적용하는 것
  • [TIPS] 제공하는 종류가 많아 헷갈리기 때문에, public Ease 변수를 선언하고 Inspector 창에서 설정하며 테스트하는 것이 좋다.
  • 기본값 = Ease.Unset
  • 강도: Sine < Quad < Cubic < Quart < Quint < Expo
  • In: 변화가 처음에 시작됨
  • Out: 변화가 끝에 시작됨
  • InOut: 번화가 양쪽에서 시작됨
box.DOLocalMoveX(400, 1).SetEase(Ease.Linear);

SetId(object id)

  • 특정 ID로 제어
  • Tween or Sequence특정 id를 부여
  • id를 통해 static 함수 등으로 제어
circle.DOLocalMoveX(0, 1).SetId("circleTween");
DOTween.Kill("circleTween");
box.DOLocalMoveX(200, 1).SetId(1);
DOTween.Rewind(1);

SetLink(GameObject target, LinkBehaviour linkBehaviour = LinkBehaviour.KillOnDestroy)

  • Tween or Sequence를 타겟 게임 오브젝트에 연결해 오브젝트의 상태 변화에 따라 트윈을 제어하게 해줌
    ex) 오브젝트가 SetActive(true)될 때마다 Tween을 재실행하는 LinkBehaviour 설정
    Tween or Sequence가 끝나면 AutoKill이 작동하기 때문에 이 기능을 꺼야함
Sequence mySequence = DOTween.Sequence()
.SetAutoKill(false)
.SetLink(Objects, LinkBehaviour.RestartOnEnable)
.Join(circle.DOLocalMoveX(200, 1))
.Join(box.DOLocalMoveX(200, 1));

SetLoops(int loops, LoopType loopType = LoopType.Restart)

  • loops: 반복 회수(-1이면 무한루프)
  • LoopType = Incremental: 종료된 시점을 시작 지점으로 모션을 다시 시작(연속)
  • LoopType = Restart: 처음 시작 지점으로 되돌아가서 모션을 다시 시작
  • LoopType = Yoyo: 실행된 모션이 되감기되며 다시 시작(#반복 회수는 돌아가는 모션 포함)
box.DOLocalMoveX(200, 1).SetLoops(-1, LoopType.Restart);

SetRecyclable(bool recyclable)

  • Tween이 종료되어도 Kill 되지 않도록 설정
  • 변수에 할당할 때 사용
Tweener tr1 = transform.DOMoveX(4, 1).SetRecyclable(true);

SetDelay(float delay, bool asPrependedIntervalIfSequence = false)

  • Tweener or Sequence가 실행되는 시간dalay초 만큼 지연
  • asPrependedIntervalIfSequenceSequence에만 사용 가능하고, 각 Tweener마다 delay를 줄지 설정
transform.DOMoveX(4, 1).SetDelay(2.0f);

SetRelative(bool isRelative = true)

  • 상대값 설정
  • 절대 좌표가 아닌 상대 좌표으로 변환할 수 있는 설정
circle.DOLocalMoveX(200, 1f);//x=200으로 이동
box.DOLocalMoveX(200, 1f).SetRelative();//현재 기준 +200 이동

SetSpeedBased

  • 속력 기준 설정
  • durationdistance로 변모
  • 같은 속력(distance/1초)으로 일정 거리를 이동
circle.DOLocalMoveX(200, 200).SetRelative().SetSpeedBased();
box.DOLocalMoveX(400, 200).SetRelative().SetSpeedBased();

SetUpdate(UpdateType updateType, bool isIndependentUpdate = false)

  • 메인메뉴 or 일시정지 등에 Time.timeScale = 0이 사용됨
  • Time.deltaTime과 관련된 모든 함수들의 작동을 멈춤
  • but .SetUpdate(true)를 통해 Time.timeScale = 0인 상황에도 움직이도록 설정 가능
  • UpdateType - Normal: Update
  • UpdateType - Late: Late Update
  • UpdateType - Fixed: Fixed Update
  • UpdateType - Manual: DOTween Custom Update 사용
transform.DOMoveX(4, 1).SetUpdate(UpdateType.Late, true);

5. On

  • 모션의 특정 상황에서 원하는 함수를 호출하는 콜백 기능

OnComplete(TweenCallback callback)

  • Tween Complete될 때 자동 호출
transform.DOMoveX(4, 1).OnComplete(MyCallback);

OnKill(TweenCallback callback)

  • Tween이 Kill될 때, 자동 호출
transform.DOMoveX(4, 1).OnKill(MyCallback);

OnPlay(TweenCallback callback)

  • Tween이 Play될 때, 자동 호출
transform.DOMoveX(4, 1).OnPlay(MyCallback);

OnPause(TweenCallback callback)

  • Tween이 Pause될 때, 자동 호출
transform.DOMoveX(4, 1).OnPause(MyCallback);

OnRewind(TweenCallback callback)

  • Tween이 Rewind될 때, 자동 호출
transform.DOMoveX(4, 1).OnRewind(MyCallback);

OnStart(TweenCallback callback)

  • Tween이 Start될 때 자동 호출
transform.DOMoveX(4, 1).OnStart(MyCallback);

OnStepComplete(TweenCallback callback)

  • 각 Loop마다 Complete될 때, 자동 호출
transform.DOMoveX(4, 1).OnStepComplete(MyCallback);

OnUpdate(TweenCallback callback)

  • Tween이 업데이트되는 매 프레임마다 자동 호출
transform.DOMoveX(4, 1).OnUpdate(MyCallback);

OnWaypointChange(TweenCallback<int> callback)

  • Tween이 waypoint에 도달했을 때, 자동 호출
transform.DOMoveX(4, 1).OnWaypointChange(MyCallback);

On Call Back 사용법

    1. 단순 사용법(콜백함수(Preb))만을 넣어준다.
    1. 람다 함수를 통해 함수 객체를 직접 넣어준다.
// 타겟 포지션까지 3초동안 이동한 뒤 완료되면 GetTarget 함수를 호출한다.
transform.DOMove(targetPosition, 3).OnComplete(GetTarget);
myTween.OnStart(()=>{
//ex) 트윈 시작 시 실행
});
myTween.OnComplete(()=>{
//ex) 트윈 종료 후 실행
});
myTween.OnUpdate(()=>{
//ex) 트윈 수행 중 매프레임 마다 실행
});
transform.DOScale(Vector3.zero, 1).OnComplete(() => gameObject.SetActive(false));
// 1초동안 오브젝트의 크기를 0으로 변환시키고 트윈이 끝나면 오브젝트를 비활성화 시킨다.

6. Sequence

  • Tweener들의 모임
  • 다른 Tweener들을 제어하고, 그룹으로 애니메이션을 적용

6-1 Sequence 선언

Sequence sequence = new Sequence();
Tween tr1 = transform.DOMove(targetPos, 1.0f).SetEase(Ease.Flash).SetDelay(1.0f).SetLoops(3).OnComplete(()=> Debug.Log("Completed"));
Tween tr2 = transform.DORotate(targetPos, 1.0f).SetEase(Ease.InBack).SetDelay(1.0f).SetLoops(3).OnComplete(() => Debug.Log("Completed"));
Tween tr3 = transform.DOScale(targetPos, 1.0f).SetEase(Ease.InBounce).SetDelay(1.0f).SetLoops(3).OnComplete(()=> Debug.Log("Completed"));
Tween tr4 = transform.DOLocalMove(targetPos, 1.0f).SetEase(Ease.InCirc).SetDelay(1.0f).SetLoops(3).OnComplete(()=> Debug.Log("Completed"));

6-2 Sequence 관리

6-2-1 Append

  • 시퀀스 맨 뒤에 트윈 추가
sequence.Append(tr1);

6-2-2 Insert(float time, Tweener target)

  • (현재 시간 기준) 삽입을 원하는 특정 시간(time)에 트윈(target) 추가
sequence.Insert(5.0f, tr3);

6-2-3 Join

  • 현재 시퀀스의 마지막 트윈과 인자로 입력된 시퀀스를 묶음(동시 실행)
sequence.Join(tr2);

6-2-4 Prepend

  • 시퀀스 맨 앞에 트윈 추가
sequence.Prepend(tr4);

6-2-5 동시 사용

  • Sequence 명령어를 한번에 선언하는 것도 가능
sequence.Append(tr1)
		.Insert(5.0f, tr3)
        .Join(tr2)
        .Prepend(tr4);
profile
GAME DESIGN & CLIENT PROGRAMMING

0개의 댓글