252 lines
7.3 KiB
C#
252 lines
7.3 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace Watermelon
|
|
{
|
|
using UI.Particle;
|
|
|
|
public class ExperienceStarsManager : MonoBehaviour
|
|
{
|
|
private readonly string TRAIL_POOL_NAME = "Custom UI Trail";
|
|
private readonly string PARTICLE_POOL_NAME = "Custom UI Particle";
|
|
|
|
[Header("Data")]
|
|
[SerializeField] ExperienceStarsFlightData starsData;
|
|
|
|
[Header("Stars")]
|
|
[SerializeField] RectTransform starsHolder;
|
|
|
|
[Space]
|
|
[SerializeField] GameObject starUIPrefab;
|
|
|
|
[Space]
|
|
[SerializeField] Transform starIconTransform;
|
|
[SerializeField] JuicyBounce starIconBounce;
|
|
|
|
[Header("Particles")]
|
|
[SerializeField] RectTransform particlesParent;
|
|
|
|
[Space]
|
|
[SerializeField] GameObject trailPrefab;
|
|
[SerializeField] GameObject particlePrefab;
|
|
|
|
private PoolGeneric<UIParticleTrail> trailPool;
|
|
private PoolGeneric<UIParticle> particlePool;
|
|
|
|
private Pool starsPool;
|
|
|
|
private List<ExpStarData> starsInfo = new List<ExpStarData>();
|
|
private System.Action OnComplete;
|
|
|
|
private ExperienceUIController experienceUIController;
|
|
|
|
public void Init(ExperienceUIController experienceUIController)
|
|
{
|
|
this.experienceUIController = experienceUIController;
|
|
|
|
AssignPools();
|
|
|
|
starIconBounce.Init(starIconTransform);
|
|
}
|
|
|
|
private void AssignPools()
|
|
{
|
|
trailPool = new PoolGeneric<UIParticleTrail>(trailPrefab, TRAIL_POOL_NAME, particlesParent);
|
|
particlePool = new PoolGeneric<UIParticle>(particlePrefab, PARTICLE_POOL_NAME, particlesParent);
|
|
starsPool = new Pool(starUIPrefab, starUIPrefab.name, transform);
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
if (trailPool != null)
|
|
PoolManager.DestroyPool(trailPool);
|
|
|
|
if (particlePool != null)
|
|
PoolManager.DestroyPool(particlePool);
|
|
|
|
if (starsPool != null)
|
|
PoolManager.DestroyPool(starsPool);
|
|
}
|
|
|
|
public void PlayXpGainedAnimation(int starsAmount, Vector3 screenView, System.Action OnComplete = null)
|
|
{
|
|
this.OnComplete = OnComplete;
|
|
|
|
starsAmount = Mathf.Clamp(starsAmount, 1, 10);
|
|
|
|
for (int i = 0; i < starsAmount; i++)
|
|
{
|
|
RectTransform starRect = starsPool.GetPooledObject().GetComponent<RectTransform>();
|
|
|
|
starRect.SetParent(transform.parent);
|
|
|
|
Vector3 worldPos = Camera.main.ViewportToWorldPoint(screenView);
|
|
starRect.anchoredPosition = Camera.main.WorldToScreenPoint(worldPos) + new Vector3(Random.Range(-25f, 25f), Random.Range(-25f, 25f), 0f);
|
|
starRect.SetParent(starsHolder);
|
|
|
|
Vector2 startDirection = Random.onUnitSphere;
|
|
Vector2 endPoint = Vector2.zero;
|
|
|
|
var data = new ExpStarData()
|
|
{
|
|
star = starRect,
|
|
|
|
startPoint = starRect.anchoredPosition,
|
|
middlePoint = starRect.anchoredPosition + startDirection * starsData.FirstStageDistance,
|
|
|
|
key1 = starRect.anchoredPosition + startDirection * starsData.Key1,
|
|
key2 = endPoint + starsData.Key2,
|
|
|
|
endPoint = endPoint,
|
|
|
|
startTime = Time.time,
|
|
duration1 = starsData.FirstStageDuration,
|
|
duration2 = starsData.SecondStageDuration
|
|
};
|
|
|
|
data.SetCurves(starsData);
|
|
|
|
var trail = trailPool.GetPooledComponent();
|
|
|
|
trail.SetPool(particlePool);
|
|
|
|
trail.AnchoredPos = starRect.anchoredPosition;
|
|
trail.transform.localScale = Vector3.one;
|
|
|
|
data.SetTrail(trail);
|
|
|
|
starsInfo.Add(data);
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (starsInfo.IsNullOrEmpty())
|
|
return;
|
|
|
|
for (int i = 0; i < starsInfo.Count; i++)
|
|
{
|
|
var data = starsInfo[i];
|
|
|
|
if (data.Update())
|
|
{
|
|
starsInfo.RemoveAt(i);
|
|
i--;
|
|
|
|
starIconBounce.Bounce();
|
|
|
|
experienceUIController.OnStarHitted();
|
|
}
|
|
}
|
|
|
|
if (starsInfo.IsNullOrEmpty())
|
|
OnComplete?.Invoke();
|
|
}
|
|
|
|
[Button]
|
|
public void Spawn2Stars()
|
|
{
|
|
ExperienceController.GainExperience(2);
|
|
}
|
|
|
|
[Button]
|
|
public void Spawn5Stars()
|
|
{
|
|
ExperienceController.GainExperience(5);
|
|
}
|
|
|
|
[Button]
|
|
public void Spawn10Stars()
|
|
{
|
|
ExperienceController.GainExperience(10);
|
|
}
|
|
|
|
private class ExpStarData
|
|
{
|
|
public RectTransform star;
|
|
|
|
public Vector2 startPoint;
|
|
public Vector2 middlePoint;
|
|
|
|
public Vector2 key1;
|
|
public Vector2 key2;
|
|
|
|
public Vector2 endPoint;
|
|
|
|
public float startTime;
|
|
public float duration1;
|
|
public float duration2;
|
|
|
|
private ExperienceStarsFlightData data;
|
|
|
|
private UIParticleTrail trail;
|
|
|
|
public void SetCurves(ExperienceStarsFlightData data)
|
|
{
|
|
this.data = data;
|
|
}
|
|
|
|
public void SetTrail(UIParticleTrail trail)
|
|
{
|
|
this.trail = trail;
|
|
|
|
trail.Init();
|
|
trail.IsPlaying = true;
|
|
}
|
|
|
|
public bool Update()
|
|
{
|
|
var time = Time.time - startTime;
|
|
|
|
if (time > duration1)
|
|
{
|
|
var t = (time - duration1) / duration2;
|
|
|
|
if (t >= 1)
|
|
{
|
|
star.gameObject.SetActive(false);
|
|
|
|
trail.DisableWhenReady = true;
|
|
trail.IsPlaying = false;
|
|
|
|
return true;
|
|
}
|
|
|
|
SecondStageUpdate(t);
|
|
}
|
|
else
|
|
{
|
|
var t = time / duration1;
|
|
|
|
FirstStageUpdate(t);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public void FirstStageUpdate(float t)
|
|
{
|
|
var prevPos = star.anchoredPosition;
|
|
|
|
star.anchoredPosition = Vector2.Lerp(startPoint, middlePoint, data.PathCurve1.Evaluate(t));
|
|
star.localScale = Vector3.one * data.StarsScale1.Evaluate(t);
|
|
|
|
trail.NormalizedVelocity = (star.anchoredPosition - prevPos).normalized;
|
|
|
|
trail.AnchoredPos = star.anchoredPosition;
|
|
}
|
|
|
|
public void SecondStageUpdate(float t)
|
|
{
|
|
var prevPos = star.anchoredPosition;
|
|
|
|
star.anchoredPosition = BezierUtils.EvaluateCubic(middlePoint, key1, key2, endPoint, data.PathCurve2.Evaluate(t));
|
|
star.localScale = Vector3.one * data.StarsScale2.Evaluate(t);
|
|
|
|
trail.NormalizedVelocity = (star.anchoredPosition - prevPos).normalized;
|
|
|
|
trail.AnchoredPos = star.anchoredPosition;
|
|
}
|
|
}
|
|
}
|
|
} |