first commit
This commit is contained in:
114
Assets/Scripts/BeakerContainer.cs
Normal file
114
Assets/Scripts/BeakerContainer.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
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<LiquidLayer> layers = new List<LiquidLayer>();
|
||||
private List<GameObject> _layerObjects = new List<GameObject>();
|
||||
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<Rigidbody>();
|
||||
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<Renderer>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user