오브젝트를 생성할 때, 위에서 아래로 빠르게 내려오는 효과를 만들어보자.
이때 Effect로 목표 지점에 가까워지면 감속하게 만들어보자.
현재 오브젝트를 기준으로 Y가 10 보다 큰 값에서 내려온다고 가정하자.
SmoothDamp를 이용하여 간단한 예제를 만들어 볼 수 있다.
https://docs.unity3d.com/kr/530/ScriptReference/Vector3.SmoothDamp.html
SmoothDampUpdate.cs는 업데이트 문 SmoothDamp를 사용하였다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SmoothDampUpdate : MonoBehaviour
{
Vector3 vel = Vector3.zero;
Vector3 startPos, endPos;
public float smoothTime = 1.0f;
void Start()
{
startPos = this.transform.position + new Vector3(0, 10, 0);
endPos = this.transform.position;
this.transform.position = startPos;
}
void Update()
{
this.transform.position
= Vector3.SmoothDamp(this.transform.position, endPos, ref vel, smoothTime);
}
}
큐브를 만들어서 스크립트를 추가한 후 게임을 실행해보자.
아래와 같이 처음에는 빠른 속도로 내려오다가 감속하는 것을 알 수 있다.
그런데 큰 문제가 있다. 큐브의 Position Y 값을 보자.
SmoothDamp의 부동 소수점 연산에 의해 정확한 값을 찾지 못한다.
따라서, 움직임을 끝내지 않고 매우 조금씩 계속 움직이고 있다.
또한 Update 문의 예제는 특정 상황에서 SmoothDamp를 사용하기에는 적절하지 않다.
따라서 코루틴을 이용해서 이 문제를 해결해보자.
Vector3.Lerp를 이용한다면 코루틴은 아래와 같이 만들어야 한다.
1초 동안 현재(current) 위치에서 목표(target) 위치까지 움직이도록 시간을 누적하여 처리한다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LerpCoroutine : MonoBehaviour
{
public float lerpTime = 1.0f;
IEnumerator lerpCoroutine(Vector3 current, Vector3 target, float time)
{
float elapsedTime = 0.0f;
this.transform.position = current;
while(elapsedTime < time)
{
elapsedTime += (Time.deltaTime);
this.transform.position
= Vector3.Lerp(current, target, elapsedTime / time);
yield return null;
}
transform.position = target;
yield return null;
}
void OnEnable()
{
Transform original = this.transform;
StartCoroutine(
lerpCoroutine(original.position + new Vector3(0, 10, 0), original.position, lerpTime));
}
}
선형 보간에 의해 1초 동안 일정한 속도로 내려가는 것을 알 수 있다.
OnEnable에 작성하였으므로 오브젝트를 껐다 키면 다시 재생할 수 있다.
(또한 SmoothDamp와 달리 Y = 0으로 정확히 이동한다.)
하지만 SmoothTime은 누적 시간이 아니라 위치로 판단해야 한다.
또한 위에서 보인 y 값이 아주 조금씩 움직이는 문제를 해결하기 위해
offset으로 일정 거리 내에 들어오면 while문을 종료하도록 방어 코드를 넣는다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SmoothDampCoroutine : MonoBehaviour
{
public float smoothTime = 1.0f;
IEnumerator SmoothCoroutine(Vector3 current, Vector3 target, float time)
{
Vector3 velocity = Vector3.zero;
this.transform.position = current;
float offset = 0.01f;
while (target.y + offset <= this.transform.position.y)
{
this.transform.position
= Vector3.SmoothDamp(this.transform.position, target, ref velocity, time);
yield return null;
}
transform.position = target;
yield return null;
}
void OnEnable()
{
Transform original = this.transform;
StartCoroutine(
SmoothCoroutine(original.position + new Vector3(0, 10, 0), original.position, smoothTime));
}
}
일정한 속도의 Lerp에 비해 목표 지점에 가까워질수록 점점 느려지고 있다.
그리고 offset 보정에 의해 Y = 0으로 정확히 변경되었다.
마지막으로 Lerp vs SmoothDamp를 각각 time = 0.5s vs 1.0s vs 2.0s를 비교하였다.
시간이 길수록 SmoothDamp가 조금 답답하게 느껴지므로 참고하도록 하자.
오브젝트가 나타나는 효과로 코루틴을 이용해 위 → 아래로 움직였다.
오브젝트 생성 이펙트로 Scale이 0에서 1로 커지도록 변경하는 것도 코루틴으로 가능하니, 직접 해보자.
Unity Plus:
Unity Pro:
Unity 프리미엄 학습:
'개발 > Unity' 카테고리의 다른 글
유니티 에셋 - 런타임 파일 브라우저로 파일 저장하기 (Save Files using Runtime File Browser) (0) | 2022.07.02 |
---|---|
유니티 에셋 - 런타임 파일 브라우저로 파일 업로드하기 (Upload Files using Runtime File Browser) (0) | 2022.06.29 |
유니티 - 머티리얼 로드하고 바꾸기 (Load and Change Materials) (0) | 2022.06.26 |
유니티 디버깅 - Error Pause를 활성화하여 에러 발생 시 게임 멈추기 (0) | 2022.06.26 |
유니티 - JsonUtility로 Json 내보내기 : (4) Export (0) | 2022.06.25 |
댓글