본문 바로가기
개발/Unity

Unity) 숫자 롤링 애니메이션 (Number Rolling), 숫자 플립 애니메이션( Number Flip)

by 테샤르 2024. 8. 28.

숫자 롤링 애니메이션 (Number Rolling), 숫자 플립 애니메이션( Number Flip)

 

숫자의 자리수를 기준으로 롤링이 되는 기능을 테스트 했다.

숫자 플립 애니메이션이라고 하는데 의미는 비슷하다.

위에서 내려오는 기준으로 가장 오른쪽에 있는 숫자가 롤링이 끝나면 등록된 Callback을 진행한다.

 

 

반응형

Callback 에서 숫자의 정보를 기반으로 자리수가 넘어가면 다음 자리의 롤링을 진행한다.

첫번째 자리수는 결국은 계속 롤링이 되는 형태이다.

< 테스트 롤링 코드>

using System;
using System.Collections.Generic;
using UnityEngine;

using System.Threading.Tasks;
using UnityEngine.UI;

public class RollingSystem : MonoBase
{
	[SerializeField]
	private RollingObject rollingObject = default;

	[SerializeField]
	private RectMask2D maskObject =default;

	private float _objectHeight = default;
	public float objectHeight
	{
		set { _objectHeight = value; }
	}

	private List<RollingObject> rollings = default;
	private Action<RollingObject> moveEndObject = default;
	private Action <RollingObject> totalMoveAction = default;
	private float duratimeTime = 0f;
	private int startNumber = -1;
	private int endNumber = -1;
	private int digit = 10;

	private AnimationCurve animationCurve = AnimationCurve.Linear(0f, 0f, 1f, 1f); // Default to linear

	private void SetNumber(RollingObject rollingObject, int _number)
	{
		int showNumber = _number % digit;
		rollingObject.SetNumber(_number, showNumber);
	}

	public RollingSystem Initialized(int _startNumber)
	{
		if (rollings == null)
		{
			rollingObject.SetActive(false);
			rollings = new List<RollingObject>();
			int value = _startNumber;
			for (int i = 0; i < 3; i++)
			{
				var item = Instantiate<RollingObject>(rollingObject, maskObject.transform);
				SetNumber(item, value);
				rollings.Add(item);
				value++;
			}

			_objectHeight = rollingObject.Rect.sizeDelta.y;
		}

		var offsetY = 0f;
		foreach (var item in rollings)
		{
			item.MoveObject(new Vector2(0, offsetY));
			item.SetActive(true);
			offsetY += _objectHeight;
		}

		return this;
	}

	public RollingSystem Initialized(float _durationTime, int _startNumber, int _endNumber, int _digit)
	{
		startNumber = _startNumber;
		endNumber=_endNumber;
		duratimeTime = _durationTime;
		digit = _digit;
		Initialized(startNumber);
		
		return this;
	}

	public RollingSystem SetMoveAction(Action<RollingObject> _action)
	{
		moveEndObject = _action;
		return this;
	}
	public RollingSystem SetTotalMoveAction(Action<RollingObject> _action)
	{
		totalMoveAction = _action;
		return this;
	}

	public RollingSystem SetAnimationCurve(AnimationCurve curve)
	{
		animationCurve = curve;
		return this;
	}

	public async void Play()
	{
		await MoveRollings();
	}

	private async Task MoveRollings()
	{
		while (true)
		{
			float elapsedTime = 0f;
			Vector2[] initialPositions = new Vector2[rollings.Count];

			// Get the initial positions of the rollings
			for (int i = 0; i < rollings.Count; i++)
			{
				initialPositions[i] = rollings[i].GetPosition();
			}

			while (elapsedTime < duratimeTime)
			{
				elapsedTime += Time.deltaTime;
				float normalizedTime = elapsedTime / duratimeTime;
				float curveValue = animationCurve.Evaluate(normalizedTime);

				for (int i = 0; i < rollings.Count; i++)
				{
					float newY = Mathf.Lerp(initialPositions[i].y, initialPositions[i].y - _objectHeight, curveValue);
					rollings[i].MoveObject(new Vector2(0, newY));
				}

				await Task.Yield();
			}

			// Ensure all rollings reach the final position
			for (int i = 0; i < rollings.Count; i++)
			{
				rollings[i].MoveObject(new Vector2(0, initialPositions[i].y - _objectHeight));
			}

			// Reuse the last object by moving it to the top
			RollingObject lastRollingObject = rollings[0];
			for (int i = 0; i < rollings.Count - 1; i++)
			{
				rollings[i] = rollings[i + 1];
			}

			var nextNumber = lastRollingObject.Number + rollings.Count;
			SetNumber(lastRollingObject, nextNumber);

			rollings[rollings.Count - 1] = lastRollingObject;
			lastRollingObject.MoveObject(new Vector2(0, rollings[rollings.Count - 2].GetPosition().y + _objectHeight));

		
			moveEndObject?.Invoke(lastRollingObject);

			if (lastRollingObject.Number == (endNumber + (rollings.Count-1)))
			{
				totalMoveAction?.Invoke(lastRollingObject);
				break;
			}
		}
	}
}

 

 

★☆☆☆☆

 

반응형

댓글