CapersProject/Assets/02.Scripts/LiquidController.cs
2024-08-19 12:15:31 +09:00

147 lines
4.1 KiB
C#

using System.Collections.Generic;
using System.Linq;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.Pool;
namespace BlueWater
{
public class LiquidController : MonoBehaviour
{
[SerializeField]
private Renderer _liquidRenderer;
[SerializeField, Required]
private Liquid _liquidObject;
[SerializeField, Required]
private Transform _spawnTransform;
[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;
private Material _material;
// Hashes
private static readonly int _colorHash = Shader.PropertyToID("_Color");
private void Awake()
{
_objectPool = new ObjectPool<Liquid>(CreateObject, OnGetObject, OnReleaseObject, OnDestroyObject, maxSize: _objectPoolCount);
}
private void Start()
{
_material = Instantiate(_liquidRenderer.material);
_liquidRenderer.material = _material;
}
private void Update()
{
if (_isPouring)
{
_objectPool.Get();
if (_colorTimes.ContainsKey(_liquidColor))
{
_colorTimes[_liquidColor] += Time.time - _startTime;
}
else
{
_colorTimes[_liquidColor] = Time.time - _startTime;
}
_startTime = Time.time;
_liquidRenderer.material.SetColor(_colorHash, MixColorsByTime());
}
}
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;
}
}
}