텍스트의 애니메이션은 일련의 과정이 있다.
1. 작은 점에서 커지는 상자 애니메이션
2. 모든 텍스트가 출력될 수 있게 충분히 커지는 상자
3. 상자에 꽉 차게 출력되는 텍스트
4. 텍스트가 사라지고 다시 애니메이션의 마지막 프레임 사이즈로 줄어드는 상자
5. 사라지는 애니메이션
커지고 작아지는 애니메이션은 스프라이트로 존재해서 간단히 애니메이터로 구현했다.
문제는 출력될 string 길이에 따라 미리 사이즈를 키우고 나서 출력해야한다는 점이었다.
여기서 문제가 발생한다...
나는 지금 Substring으로 전체 문장중 출력할 문장만 TextMeshPro의 Text에 넣어주는 중...
폰트나 사이즈에 따라 완성된 텍스트의 사이즈가 각양각색인데 어떻게 TMP에 넣어보지도 않고 전체 사이즈를 알아내지???
물론... 한글이면 10px, 영어면 5px... 머 이렇게 임의로 정해줄수도 있겠지만 123만 봐도 1과 3의 가로 길이가 확연히 다른데 그렇게 대충 정하는 방식이면 오차가 클 것 같았다.
처음에 선택한 방법은 Contents Size fitter로 PreferredSize를 알아내는 것이었다.
Contents Size fitter에서 어떻게 알아내는지는 모르나 Text 적합한 사이즈를 계산해주니까 값만 가져올 방법이 있을거 같았다.
그러다 발견한 TMP의 프로퍼티에서 Preferred Width가 있는걸 발견!!
TMP에서 자체적으로 적합한 사이즈를 계산해주는거 같아서 이걸 바탕으로 값을 가져올 방법을 여러 포럼에서 뒤졌다.
(참고한 사이트:https://discussions.unity.com/t/get-the-actual-width-of-the-visible-text/694589/23)
GetPreferredValues를 통해서 가져올 수 있다는 사실을 확인.
마지막 난관은 아직 입력되지 않은 Text를 바탕으로 Size를 어떻게 알아내지?? 였다.
GetPreferredValues(string)을 통해 string만 넣어도 값을 출력해주는걸까 했는데 그건 아닌거 같고...
약간의 꼼수를 사용해 해결했다.
그것은... 유령 텍스트 만들기
알파값을 0으로 한 텍스트 상자를 하나 만들고 전체 문장을 넣어 사이즈를 구한 뒤 사이즈를 조절했다.
사용되지 않는 오브젝트가 하나 추가된 셈이니 좋은 방식은 아니지만... 결과적으론 잘 작동했다.
우선 코루틴을 사용하여 최종 목표인 사이즈를 설정하고 애니메이터의 종료시 이벤트를 추가해 연결했다.
IEnumerator BoxSizeFitIn(float timeSecond)
{
IsBoxSizeFitting = true;
TotalTextSize = GhostText.GetPreferredValues();
if (TotalTextSize.x > 300)
{
TotalTextSize.x = 300;
}
TotalTextSize += Spacing;
yield return new WaitForSeconds(timeSecond);
if(CurrentBoxState == BoxState.Openning)
{
CurrentBoxState = BoxState.TextFlow;
}
else if(CurrentBoxState == BoxState.Closing)
{
TextBoxAni.Play("TextBoxClose");
}
}
if (IsBoxSizeFitting)
{
time += Time.deltaTime;
if(time > BoxGrowingSpeed)
{
time = 0;
IsBoxSizeFitting = false;
if (CurrentBoxState == BoxState.Openning)
{
TextBox.rectTransform.sizeDelta = TotalTextSize;
Text.rectTransform.localPosition = new Vector2(-TotalTextSize.x / 2 + 32, TotalTextSize.y - 32);
}
else if (CurrentBoxState == BoxState.Closing)
{
TextBox.rectTransform.sizeDelta = new Vector2(64, 64);
}
}
else
{
if(CurrentBoxState == BoxState.Openning)
{
TextBox.rectTransform.sizeDelta
= new Vector2(TotalTextSize.x * time / BoxGrowingSpeed + (64 * (1 - time / BoxGrowingSpeed)), TotalTextSize.y * time / BoxGrowingSpeed + (64 * (1 - time / BoxGrowingSpeed)));
}
else if(CurrentBoxState == BoxState.Closing)
{
TextBox.rectTransform.sizeDelta
= new Vector2(TotalTextSize.x - (TotalTextSize.x * time / BoxGrowingSpeed) + (64 * (time / BoxGrowingSpeed)), TotalTextSize.y - (TotalTextSize.y * time / BoxGrowingSpeed) + (64 * (time / BoxGrowingSpeed)));
}
}
}
이쪽은 업데이트에 들어가는 실질적으로 상자 사이즈를 조절하는 구간.
애니메이션의 시작점과 끝점이 64*64px이라서 64px부터 목표한 Size까지 시간에 따라 0~1로 증가하도록 작성되었다.
다음은 디벨롭과 완성본으로 이어집니다.
'📁 개발 히스토리' 카테고리의 다른 글
유니티 - 인벤토리 구현하기(1) (0) | 2025.02.22 |
---|---|
유니티 - 캐릭터를 따라다니는 텍스트 박스(3) (0) | 2025.01.13 |
유니티 - 캐릭터를 따라다니는 텍스트 박스(1) (0) | 2025.01.11 |
유니티 - 자잘한 것들(try catch, 디버그 모드) (0) | 2023.04.16 |
유니티 - 제네릭(Generic Type), 델리게이트(Delegate) (0) | 2023.04.16 |