139 lines
4.1 KiB
C#
139 lines
4.1 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
} |