71 lines
2.3 KiB
C#
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
|
|
};
|
|
}
|
|
}
|
|
} |