using System.Collections; using System.Collections.Generic; using UnityEngine; public class BeakerContainer : MonoBehaviour { [System.Serializable] public class LiquidLayer { public LiquidContainer.LiquidType liquidType; public Color color; public float density; public float amount; } [SerializeField] private GameObject _layerTemplate; [SerializeField] private float _emptyMassKg = 0.15f; [SerializeField] private float _volumeLiters = 0.25f; [SerializeField] public float capacity = 1f; public List layers = new List(); private List _layerObjects = new List(); private Rigidbody _rb; public bool IsFull() => TotalAmount() >= 1f; public bool IsEmpty() => TotalAmount() <= 0f; public float TotalAmount() { float total = 0f; foreach (var l in layers) total += l.amount; return total; } private void Awake() { _rb = GetComponent(); if (_layerTemplate != null) _layerTemplate.SetActive(false); } public void AddLiquid(Color color, float amount, float density, LiquidContainer.LiquidType type) { float canAdd = Mathf.Clamp(amount, 0f, 1f - TotalAmount()); if (canAdd <= 0f) return; LiquidLayer existing = layers.Find(l => l.liquidType == type); if (existing != null) { existing.amount += canAdd; } else { layers.Add(new LiquidLayer { liquidType = type, color = color, density = density, amount = canAdd }); } layers.Sort((a, b) => b.density.CompareTo(a.density)); UpdateVisual(); UpdateMass(); } public void UpdateMass() { if (_rb == null) return; float liquidMass = 0f; foreach (var l in layers) liquidMass += l.amount * _volumeLiters * l.density; _rb.mass = _emptyMassKg + liquidMass; } public void UpdateVisual() { foreach (var obj in _layerObjects) Destroy(obj); _layerObjects.Clear(); if (_layerTemplate == null || layers.Count == 0) return; float yOffset = 0f; foreach (var layer in layers) { GameObject go = Instantiate(_layerTemplate, _layerTemplate.transform.parent); go.SetActive(true); Vector3 pos = _layerTemplate.transform.localPosition; pos.y = yOffset; go.transform.localPosition = pos; Vector3 scale = _layerTemplate.transform.localScale; scale.y = Mathf.Max(0.01f, layer.amount); go.transform.localScale = scale; Renderer rend = go.GetComponent(); if (rend != null) { Material mat = new Material(rend.sharedMaterial); if (mat.HasProperty("_c1")) mat.SetColor("_c1", layer.color); if (mat.HasProperty("_c2")) mat.SetColor("_c2", layer.color); rend.material = mat; } yOffset += scale.y; _layerObjects.Add(go); } } }