EscapeShooter/My project/Assets/Project Files/Game/Scripts/Experience/ExperienceStarsManager.cs

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;
}
}
}
}