using System; using System.Collections; using Core.Domain; using Core.Ports; using KBCore.Refs; using UnityEngine; using Random = UnityEngine.Random; 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 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 void Awake() { _propBlock = new MaterialPropertyBlock(); rb.isKinematic = true; rb.useGravity = false; } public void Initialize(Tile tile) { _linkedTile = tile; TileId = tile.Id; SetColor(stableColor); _linkedTile.OnStateChanged += OnTileStateChanged; } private void OnTileStateChanged(Tile tile) { SetVisualState(tile.CurrentState); } public void SetVisualState(TileState state) { switch (state) { case TileState.Stable: StartCoroutine(AnimateColor(stableColor)); break; case TileState.Warning: StartCoroutine(AnimateColor(warningColor)); break; case TileState.Falling: DropPhysics(); // Optionally change material or add effects for falling state break; case TileState.Destroyed: Dispose(); // Optionally change material or add effects for destroyed state break; default: throw new ArgumentOutOfRangeException(nameof(state), state, null); } } public void DropPhysics() { rb.isKinematic = false; rb.useGravity = true; // rb.AddTorque(Random.insideUnitSphere * 5f, ForceMode.Impulse); } public void Dispose() { StartCoroutine(ShrinkAndDestroy()); } public void OnPlayerStep() { _linkedTile?.StepOn(); } 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; } Destroy(gameObject); } private void OnDestroy() { if (_linkedTile != null) { _linkedTile.OnStateChanged -= OnTileStateChanged; } } } }