Files
ScienceLab.WeightAndMass/Assets/Scripts/MassController.cs
2026-04-07 03:14:32 +03:00

105 lines
2.7 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class MassController : MonoBehaviour
{
[SerializeField] private TextMeshProUGUI _weightText;
[SerializeField] private float _animationSpeed = 2f;
private List<Rigidbody> _bodies = new List<Rigidbody>();
private Coroutine _weightRoutine;
private float _currentDisplayedValue = 0f;
private enum UnitMode { Kg, G, Mg }
private UnitMode _currentMode = UnitMode.Kg;
private void Reset()
{
Collider c = GetComponent<Collider>();
if (c != null) c.isTrigger = true;
}
private void Update()
{
if (_bodies.Count > 0) UpdateWeight();
}
public void AddObject(Rigidbody rb)
{
if (rb == null) return;
if (!_bodies.Contains(rb))
_bodies.Add(rb);
}
public void RemoveObject(Rigidbody rb)
{
if (rb == null) return;
_bodies.Remove(rb);
UpdateWeight();
}
public void SwitchUnit()
{
_currentMode = _currentMode switch
{
UnitMode.Kg => UnitMode.G,
UnitMode.G => UnitMode.Mg,
_ => UnitMode.Kg
};
UpdateWeight();
}
private void UpdateWeight()
{
float totalKg = 0f;
foreach (var rb in _bodies)
{
if (rb == null) continue;
LiquidContainer lc = rb.GetComponent<LiquidContainer>()
?? rb.GetComponentInChildren<LiquidContainer>();
totalKg += lc != null ? lc.GetTotalMassKg() : rb.mass;
}
float target = ConvertValue(totalKg);
if (_weightRoutine != null) StopCoroutine(_weightRoutine);
_weightRoutine = StartCoroutine(AnimateWeight(target));
}
private float ConvertValue(float kg)
{
return _currentMode switch
{
UnitMode.G => kg * 1000f,
UnitMode.Mg => kg * 1_000_000f,
_ => kg
};
}
private string GetUnitLabel()
{
return _currentMode switch
{
UnitMode.G => " g",
UnitMode.Mg => " mg",
_ => " kg"
};
}
private IEnumerator AnimateWeight(float targetValue)
{
float elapsed = 0f;
float startValue = _currentDisplayedValue;
float duration = 1f / _animationSpeed;
while (elapsed < duration)
{
elapsed += Time.deltaTime;
_currentDisplayedValue = Mathf.Lerp(startValue, targetValue, elapsed / duration);
_weightText.text = _currentDisplayedValue.ToString("F2") + GetUnitLabel();
yield return null;
}
_currentDisplayedValue = targetValue;
_weightText.text = targetValue.ToString("F2") + GetUnitLabel();
}
}