popcorn/popcorn/Assets/MyGame/Scripts/HeartMeter.cs

95 lines
3.0 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using TMPro;
using UniRx;
using UnityEngine;
using UnityEngine.UI;
public class HeartMeter : SingletonMonoBehaviour<HeartMeter>
{
[SerializeField] private Slider slider;
[SerializeField] private TextMeshProUGUI heartLevel;
private Coroutine coroutine;
private List<ShopLevelData> shopLevelList = new List<ShopLevelData>();
private int currentHeartCount;
private readonly ReactiveProperty<float> viewHeartCount = new ReactiveProperty<float>();
public IReadOnlyReactiveProperty<int> ShopLevel => shopLevel;
private readonly ReactiveProperty<int> shopLevel = new ReactiveProperty<int>();
private CompositeDisposable compositeDisposable = new CompositeDisposable();
private float minHeart;
private float maxHeart;
private void Awake()
{
if (CheckInstance()) return;
}
private void Start()
{
shopLevel.AddTo(this);
viewHeartCount.AddTo(this);
compositeDisposable.AddTo(this);
}
public void Initialize(int newShopLevel = 0, int newHeartCount = 0)
{
compositeDisposable.Clear();
shopLevelList = SpreadsheetDataManager.Instance.GetBaseDataList<ShopLevelData>(Const.ShopLevelDataSheet);
viewHeartCount.SkipLatestValueOnSubscribe().Subscribe(heartCount =>
{
if (shopLevelList.Count == shopLevel.Value)
{
slider.value = 1;
}
else
{
slider.value = Mathf.InverseLerp(minHeart, maxHeart, heartCount);
}
}).AddTo(compositeDisposable);
SetHeart(newHeartCount);
SetShopLevel(newShopLevel);
}
public void SetHeart(int heartCount)
{
currentHeartCount = heartCount;
viewHeartCount.SetValueAndForceNotify(heartCount);
}
public void SetShopLevel(int newShopLevel, bool animate = false)
{
var maxLevel = shopLevelList.Last().shopLevel;
var level = Mathf.Min(newShopLevel, maxLevel);
shopLevel.Value = level;
heartLevel.text = $"{level}";
minHeart = shopLevelList.FirstOrDefault(data => data.shopLevel == level)?.heart ?? 0;
maxHeart = shopLevelList.FirstOrDefault(data => data.shopLevel == level + 1)?.heart ?? minHeart;
if (animate)
{
var tmpCount = currentHeartCount - (int)minHeart;
SetHeart((int)minHeart);
AddHeart(tmpCount);
}
else
{
viewHeartCount.SetValueAndForceNotify(currentHeartCount);
}
}
public void AddHeart(int value)
{
this.SafeStopCoroutine(coroutine);
currentHeartCount += value;
coroutine = this.CallWaitForSeconds(1f, () =>
{
SetHeart(currentHeartCount);
});
this.CallLerp(1f, f =>
{
viewHeartCount.Value = Mathf.Min(currentHeartCount, viewHeartCount.Value + value * f);
});
}
}