192 lines
5.7 KiB
C#
192 lines
5.7 KiB
C#
using System;
|
|
using System.Collections;
|
|
using Core.Domain;
|
|
using Core.Ports;
|
|
using KBCore.Refs;
|
|
using UnityEngine;
|
|
|
|
namespace Infrastructure.Unity
|
|
{
|
|
[RequireComponent(typeof(MeshRenderer), typeof(Rigidbody))]
|
|
public class TileViewAdapter : MonoBehaviour, ITileView
|
|
{
|
|
private Tile _linkedTile;
|
|
|
|
public string TileId { get; private set; }
|
|
|
|
[Header("Visuals Settings")]
|
|
[SerializeField] private Color stableColor = new Color(0.2f, 0.2f, 0.2f); // Dark Grey
|
|
[SerializeField] private Color warningColor = new Color(1f, 0.2f, 0.2f); // Neon Red
|
|
[SerializeField] private Color fragileColor = new Color(0.6f, 0.8f, 1f, 0.5f); // Cyan/Glass
|
|
[SerializeField] private float colorSpeed = 2f;
|
|
|
|
[Self][SerializeField] private Rigidbody rb;
|
|
[Self][SerializeField] private MeshRenderer meshRenderer;
|
|
|
|
public Rigidbody Rigidbody => rb;
|
|
public MeshRenderer MeshRenderer => meshRenderer;
|
|
|
|
private MaterialPropertyBlock _propBlock;
|
|
private static readonly int ColorProperty = Shader.PropertyToID("_BaseColor");
|
|
private static readonly int EmissionColorProperty = Shader.PropertyToID("_EmissionColor");
|
|
|
|
private Action<TileViewAdapter> _onReturnToPool;
|
|
|
|
private void Awake()
|
|
{
|
|
_propBlock = new MaterialPropertyBlock();
|
|
|
|
rb.isKinematic = true;
|
|
rb.useGravity = false;
|
|
}
|
|
|
|
public void Initialize(Tile tile)
|
|
{
|
|
Initialize(tile, null);
|
|
}
|
|
|
|
public void Initialize(Tile tile, Action<TileViewAdapter> onReturnToPool = null)
|
|
{
|
|
_linkedTile = tile;
|
|
TileId = tile.Id;
|
|
_onReturnToPool = onReturnToPool;
|
|
|
|
// Reset physics
|
|
rb.isKinematic = true;
|
|
rb.useGravity = false;
|
|
|
|
if (_linkedTile.Type == TileType.Fragile)
|
|
{
|
|
SetColor(fragileColor);
|
|
}
|
|
else
|
|
{
|
|
SetColor(ThemeManager.CurrentTheme.StableColor);
|
|
}
|
|
|
|
_linkedTile.OnStateChanged += OnTileStateChanged;
|
|
}
|
|
|
|
private void OnTileStateChanged(Tile tile)
|
|
{
|
|
SetVisualState(tile.CurrentState);
|
|
}
|
|
|
|
public void SetVisualState(TileState state)
|
|
{
|
|
switch (state)
|
|
{
|
|
case TileState.Stable:
|
|
StartCoroutine(AnimateColor(ThemeManager.CurrentTheme.StableColor));
|
|
break;
|
|
case TileState.Warning:
|
|
StartCoroutine(AnimateColor(ThemeManager.CurrentTheme.WarningColor));
|
|
break;
|
|
case TileState.Falling:
|
|
DropPhysics();
|
|
break;
|
|
case TileState.Destroyed:
|
|
Dispose();
|
|
break;
|
|
default:
|
|
throw new ArgumentOutOfRangeException(nameof(state), state, null);
|
|
}
|
|
}
|
|
|
|
public void DropPhysics()
|
|
{
|
|
rb.isKinematic = false;
|
|
rb.useGravity = true;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
StartCoroutine(ShrinkAndDestroy());
|
|
}
|
|
|
|
public void OnPlayerStep()
|
|
{
|
|
_linkedTile?.StepOn();
|
|
}
|
|
|
|
public void PulseEmission(float intensity)
|
|
{
|
|
StartCoroutine(PulseEmissionRoutine(intensity, 0.1f));
|
|
StartCoroutine(PulseScaleRoutine());
|
|
}
|
|
|
|
private void SetColor(Color color)
|
|
{
|
|
meshRenderer.GetPropertyBlock(_propBlock);
|
|
_propBlock.SetColor(ColorProperty, color);
|
|
meshRenderer.SetPropertyBlock(_propBlock);
|
|
}
|
|
|
|
private IEnumerator AnimateColor(Color targetColor)
|
|
{
|
|
meshRenderer.GetPropertyBlock(_propBlock);
|
|
var startColor = _propBlock.GetColor(ColorProperty);
|
|
var t = 0f;
|
|
|
|
while (t < 1f)
|
|
{
|
|
t += Time.deltaTime * colorSpeed;
|
|
SetColor(Color.Lerp(startColor, targetColor, t));
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
private IEnumerator ShrinkAndDestroy()
|
|
{
|
|
var t = 0f;
|
|
var startScale = transform.localScale;
|
|
while (t < 1f)
|
|
{
|
|
t += Time.deltaTime;
|
|
transform.localScale = Vector3.Lerp(startScale, Vector3.zero, t);
|
|
yield return null;
|
|
}
|
|
|
|
if (_onReturnToPool != null)
|
|
{
|
|
_onReturnToPool(this);
|
|
}
|
|
else
|
|
{
|
|
Destroy(gameObject);
|
|
}
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
if (_linkedTile != null)
|
|
{
|
|
_linkedTile.OnStateChanged -= OnTileStateChanged;
|
|
}
|
|
}
|
|
|
|
private IEnumerator PulseScaleRoutine()
|
|
{
|
|
var original = transform.localScale;
|
|
transform.localScale = original * 1.05f;
|
|
yield return new WaitForSeconds(0.1f);
|
|
transform.localScale = original;
|
|
}
|
|
|
|
private IEnumerator PulseEmissionRoutine(float intensity, float duration)
|
|
{
|
|
meshRenderer.GetPropertyBlock(_propBlock);
|
|
|
|
var baseColor = _propBlock.GetColor(ColorProperty);
|
|
var glowingColor = baseColor * intensity;
|
|
|
|
_propBlock.SetColor(EmissionColorProperty, glowingColor);
|
|
meshRenderer.SetPropertyBlock(_propBlock);
|
|
|
|
yield return new WaitForSeconds(duration);
|
|
|
|
_propBlock.SetColor(EmissionColorProperty, Color.black);
|
|
meshRenderer.SetPropertyBlock(_propBlock);
|
|
}
|
|
}
|
|
} |