using UnityEngine; using UnityEngine.UI; namespace Unheimlich.Features.DetectiveBoard.UI { public enum LineColorState { Green = 0, Orange = 1, Red = 2 } [RequireComponent(typeof(RectTransform))] public class ConnectionLine : MonoBehaviour { [Header("References")] [SerializeField] private Image _lineImage; [SerializeField] private Image _outlineImage; [SerializeField] private RectTransform _rectTransform; private RectTransform _lineRectTransform; private RectTransform _outlineRectTransform; [Header("Settings")] [SerializeField] private float _lineThickness = 3f; [SerializeField] private Color _outlineColor = Color.yellow; [Header("Color States")] [SerializeField] private Color _greenColor = Color.green; [SerializeField] private Color _orangeColor = new Color(1f, 0.5f, 0f); [SerializeField] private Color _redColor = Color.red; private PostItNode _startNode; private PostItNode _endNode; private LineColorState _colorState = LineColorState.Green; private bool _isHovered; public PostItNode StartNode => _startNode; public PostItNode EndNode => _endNode; public LineColorState ColorState => _colorState; private void Awake() { if (_rectTransform == null) _rectTransform = GetComponent(); if (_lineImage == null) _lineImage = GetComponentInChildren(); if (_lineImage != null) { _lineRectTransform = _lineImage.GetComponent(); _lineImage.raycastTarget = true; } if (_rectTransform != null) { _rectTransform.anchorMin = new Vector2(0.5f, 0.5f); _rectTransform.anchorMax = new Vector2(0.5f, 0.5f); _rectTransform.pivot = new Vector2(0f, 0.5f); } if (_lineRectTransform != null) { _lineRectTransform.anchorMin = new Vector2(0f, 0.5f); _lineRectTransform.anchorMax = new Vector2(0f, 0.5f); _lineRectTransform.pivot = new Vector2(0f, 0.5f); } if (_outlineImage == null) { _outlineImage = transform.Find("Outline")?.GetComponent(); } if (_outlineImage != null) { _outlineRectTransform = _outlineImage.GetComponent(); if (_outlineRectTransform != null) { _outlineRectTransform.anchorMin = new Vector2(0f, 0.5f); _outlineRectTransform.anchorMax = new Vector2(0f, 0.5f); _outlineRectTransform.pivot = new Vector2(0f, 0.5f); } _outlineImage.raycastTarget = false; _outlineImage.gameObject.SetActive(false); } } public void Initialize(PostItNode startNode, PostItNode endNode) { _startNode = startNode; _endNode = endNode; _colorState = LineColorState.Green; UpdateColorState(); UpdateLine(); } public void UpdateLine() { if (_startNode == null || _endNode == null || _rectTransform == null) return; Vector2 startPos = _startNode.ConnectionPoint.anchoredPosition; Vector2 endPos = _endNode.ConnectionPoint.anchoredPosition; Vector2 direction = endPos - startPos; float distance = direction.magnitude; _rectTransform.anchoredPosition = startPos; float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg; _rectTransform.localRotation = Quaternion.Euler(0, 0, angle); if (_lineRectTransform != null) { _lineRectTransform.sizeDelta = new Vector2(distance, _lineThickness); } if (_outlineRectTransform != null) { _outlineRectTransform.sizeDelta = new Vector2(distance, _lineThickness + 3f); } } public void CycleColorState() { _colorState = (LineColorState)(((int)_colorState + 1) % 3); UpdateColorState(); } public void SetColorState(LineColorState state) { _colorState = state; UpdateColorState(); } private void UpdateColorState() { if (_lineImage == null) return; Color targetColor = _colorState switch { LineColorState.Green => _greenColor, LineColorState.Orange => _orangeColor, LineColorState.Red => _redColor, _ => _greenColor }; _lineImage.color = targetColor; } public void SetHovered(bool hovered) { _isHovered = hovered; if (_outlineImage != null) { _outlineImage.gameObject.SetActive(hovered); } } public bool ConnectsNodes(PostItNode nodeA, PostItNode nodeB) { return (_startNode == nodeA && _endNode == nodeB) || (_startNode == nodeB && _endNode == nodeA); } } }