2024-08-14 10:52:35 +00:00
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Linq;
|
2024-08-13 10:13:09 +00:00
|
|
|
using Sirenix.OdinInspector;
|
|
|
|
using UnityEngine;
|
2024-08-14 10:52:35 +00:00
|
|
|
using UnityEngine.Pool;
|
2024-08-13 10:13:09 +00:00
|
|
|
|
|
|
|
namespace BlueWater
|
|
|
|
{
|
|
|
|
public class LiquidController : MonoBehaviour
|
|
|
|
{
|
2024-08-14 10:52:35 +00:00
|
|
|
[SerializeField]
|
2024-08-19 03:15:31 +00:00
|
|
|
private Renderer _liquidRenderer;
|
2024-08-14 10:52:35 +00:00
|
|
|
|
2024-08-13 10:13:09 +00:00
|
|
|
[SerializeField, Required]
|
2024-08-14 10:52:35 +00:00
|
|
|
private Liquid _liquidObject;
|
2024-08-13 10:13:09 +00:00
|
|
|
|
|
|
|
[SerializeField, Required]
|
|
|
|
private Transform _spawnTransform;
|
|
|
|
|
2024-08-14 10:52:35 +00:00
|
|
|
[SerializeField]
|
|
|
|
private Transform _spawnLocation;
|
|
|
|
|
|
|
|
[SerializeField]
|
|
|
|
private int _objectPoolCount = 1000;
|
|
|
|
|
|
|
|
[SerializeField]
|
|
|
|
private Color _liquidColor = new(0f, 0.7294118f, 1f, 1f);
|
|
|
|
|
|
|
|
private IObjectPool<Liquid> _objectPool;
|
|
|
|
private List<Liquid> _activeLiquids = new();
|
|
|
|
private Dictionary<Color, float> _colorTimes = new();
|
|
|
|
|
|
|
|
private bool _isPouring;
|
|
|
|
private float _startTime = float.PositiveInfinity;
|
2024-08-19 03:15:31 +00:00
|
|
|
private Material _material;
|
2024-08-14 10:52:35 +00:00
|
|
|
|
|
|
|
// Hashes
|
|
|
|
private static readonly int _colorHash = Shader.PropertyToID("_Color");
|
|
|
|
|
|
|
|
private void Awake()
|
|
|
|
{
|
|
|
|
_objectPool = new ObjectPool<Liquid>(CreateObject, OnGetObject, OnReleaseObject, OnDestroyObject, maxSize: _objectPoolCount);
|
|
|
|
}
|
|
|
|
|
2024-08-19 03:15:31 +00:00
|
|
|
private void Start()
|
|
|
|
{
|
|
|
|
_material = Instantiate(_liquidRenderer.material);
|
|
|
|
_liquidRenderer.material = _material;
|
|
|
|
}
|
|
|
|
|
2024-08-13 10:13:09 +00:00
|
|
|
private void Update()
|
|
|
|
{
|
2024-08-14 10:52:35 +00:00
|
|
|
if (_isPouring)
|
2024-08-13 10:13:09 +00:00
|
|
|
{
|
2024-08-14 10:52:35 +00:00
|
|
|
_objectPool.Get();
|
|
|
|
|
|
|
|
if (_colorTimes.ContainsKey(_liquidColor))
|
|
|
|
{
|
|
|
|
_colorTimes[_liquidColor] += Time.time - _startTime;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_colorTimes[_liquidColor] = Time.time - _startTime;
|
|
|
|
}
|
|
|
|
|
|
|
|
_startTime = Time.time;
|
|
|
|
|
2024-08-19 03:15:31 +00:00
|
|
|
_liquidRenderer.material.SetColor(_colorHash, MixColorsByTime());
|
2024-08-13 10:13:09 +00:00
|
|
|
}
|
|
|
|
}
|
2024-08-14 10:52:35 +00:00
|
|
|
|
|
|
|
private Liquid CreateObject()
|
|
|
|
{
|
|
|
|
var instance = Instantiate(_liquidObject, _spawnTransform.position, Quaternion.identity, _spawnLocation);
|
|
|
|
instance.SetManagedPool(_objectPool);
|
|
|
|
instance.SetColor(_liquidColor);
|
|
|
|
return instance;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void OnGetObject(Liquid liquid)
|
|
|
|
{
|
|
|
|
liquid.transform.position = _spawnTransform.position;
|
|
|
|
liquid.transform.rotation = Quaternion.identity;
|
|
|
|
liquid.gameObject.SetActive(true);
|
|
|
|
_activeLiquids.Add(liquid);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void OnReleaseObject(Liquid liquid)
|
|
|
|
{
|
|
|
|
liquid.gameObject.SetActive(false);
|
|
|
|
_activeLiquids.Remove(liquid);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void OnDestroyObject(Liquid liquid)
|
|
|
|
{
|
|
|
|
Destroy(liquid.gameObject);
|
|
|
|
_activeLiquids.Remove(liquid);
|
|
|
|
}
|
|
|
|
|
|
|
|
[Button("기본 색상")]
|
|
|
|
private void DefaultColor() => _liquidColor = new Color(0f, 0.7294118f, 1f, 1f);
|
|
|
|
|
|
|
|
public void ReleaseAllObject()
|
|
|
|
{
|
|
|
|
// 뒤에서부터 Remove해야 오류가 없음
|
|
|
|
for (var i = _activeLiquids.Count - 1; i >= 0; i--)
|
|
|
|
{
|
|
|
|
_activeLiquids[i].Destroy();
|
|
|
|
}
|
|
|
|
|
|
|
|
_colorTimes.Clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void ActiveIsPouring()
|
|
|
|
{
|
|
|
|
_startTime = Time.time;
|
|
|
|
_isPouring = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void InActiveIsPouring()
|
|
|
|
{
|
|
|
|
_isPouring = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private Color MixColorsByTime()
|
|
|
|
{
|
|
|
|
var totalTime = _colorTimes.Values.Sum();
|
|
|
|
|
|
|
|
// 혼합된 색상 초기화 (검은색)
|
|
|
|
var mixedColor = Color.black;
|
|
|
|
|
|
|
|
// 색상 혼합
|
|
|
|
foreach (var element in _colorTimes)
|
|
|
|
{
|
|
|
|
var color = element.Key;
|
|
|
|
var time = element.Value;
|
|
|
|
var ratio = time / totalTime;
|
|
|
|
|
|
|
|
mixedColor += color * ratio;
|
|
|
|
}
|
|
|
|
|
|
|
|
mixedColor.a = 1f;
|
|
|
|
|
|
|
|
return mixedColor;
|
|
|
|
}
|
2024-08-13 10:13:09 +00:00
|
|
|
}
|
|
|
|
}
|