Files
2026-05-21 16:04:49 +02:00

71 lines
2.3 KiB
C#

using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.VFX;
namespace DanieleMarotta.RiversongCodeShowcase
{
public class BuildingUpgradeAnimation : MonoBehaviour
{
[SerializeField]
private VisualEffect _vfxPrefab;
[SerializeField]
private float _stretchDuration = 0.25f;
[SerializeField]
private float _stretchFactor = 1.2f;
[SerializeField]
private float _settleDuration = 0.75f;
[SerializeField]
private float _settleElasticity = 4.5f;
public async UniTask PlayAsync(Building building)
{
var vfx = Instantiate(_vfxPrefab, transform.position, transform.rotation);
DustVfxProperties.Setup(vfx, 1, new Vector2(building.Rect.Width, building.Rect.Height));
var fromScale = transform.localScale;
var toScale = new Vector3(fromScale.x, fromScale.y * _stretchFactor, fromScale.z);
var elapsed = 0f;
while (elapsed < _stretchDuration)
{
elapsed += Time.unscaledDeltaTime;
var t = EaseOutBack(Mathf.Clamp01(elapsed / _stretchDuration));
transform.localScale = Vector3.LerpUnclamped(fromScale, toScale, t);
await UniTask.NextFrame();
}
elapsed = 0;
while (elapsed < _settleDuration)
{
elapsed += Time.unscaledDeltaTime;
var t = EaseOutElastic(Mathf.Clamp01(elapsed / _settleDuration), _settleElasticity);
transform.localScale = Vector3.LerpUnclamped(toScale, fromScale, t);
await UniTask.NextFrame();
}
transform.localScale = fromScale;
}
private static float EaseOutBack(float t)
{
const float c1 = 1.70158f;
const float c3 = c1 + 1;
return 1 + c3 * Mathf.Pow(t - 1, 3) + c1 * Mathf.Pow(t - 1, 2);
}
private static float EaseOutElastic(float t, float elasticity)
{
var c4 = 2 * Mathf.PI / elasticity;
return t switch
{
0 => 0,
1 => 1,
_ => Mathf.Pow(2, -10 * t) * Mathf.Sin((10 * t - 0.75f) * c4) + 1
};
}
}
}