Кто-нибудь может подсказать, как исправить проблему: если карта не попадает в драг зону, она “залипает” и возвращается в руку только после того, как я беру новую карту или передвигаю её к краю стола?
Код карты:
using UnityEngine;
using UnityEngine.Rendering;
using DG.Tweening;
using NUnit.Framework;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine.Splines;
using UnityEngine.UIElements;
using TMPro;
public class Card : MonoBehaviour
{
private HandManager handManager;
private Collider2D col;
private Vector3 starDragPosition;
private Quaternion starDragRotation;
public bool canDrag = true;
private SortingGroup sortingGroup;
private int defaultSorting;
// private bool isDragging = false;
private Vector3 startScale;
private int baseOrder;
private clCard card;
private ICardDropArea currentDropArea;
public int Power => card != null ? card.Power : 0;
private void Start()
{
col = GetComponent<Collider2D>();
handManager = FindFirstObjectByType<HandManager>();
// Сначала получаем компонент, потом используем
sortingGroup = GetComponentInChildren<SortingGroup>();
if (sortingGroup != null)
{
defaultSorting = sortingGroup.sortingOrder;
baseOrder = sortingGroup.sortingOrder;
}
}
private void OnMouseEnter()
{
transform.DOKill();
starDragPosition = transform.position;
starDragRotation = transform.rotation;
startScale = transform.localScale;
// увеличиваем
transform.DOScale(startScale * 1.2f, 0.2f);
// поворот в 0
transform.DORotate(Vector3.zero, 0.2f);
// делаем поверх всех
sortingGroup.sortingOrder = 100;
}
private void OnMouseExit()
{
transform.DOKill();
transform.rotation = starDragRotation;
transform.DOScale(0.24f, 0.24f);
sortingGroup.sortingOrder = baseOrder;
}
private void OnMouseDown()
{
if (!canDrag) return;
starDragPosition = transform.position;
transform.position = GetMousePositionInWorldSpace();
starDragRotation = transform.rotation;
transform.rotation = GetMouseRotationInWorldSpace();
}
private void OnMouseDrag()
{
if (!canDrag) return;
transform.position = GetMousePositionInWorldSpace();
}
private void OnMouseUp()
{
if (!canDrag) return;
Vector3 mousePos = GetMousePositionInWorldSpace();
var hits = Physics2D.OverlapPointAll(mousePos);
ICardDropArea foundArea = null;
foreach (var hit in hits)
{
if (hit.gameObject == gameObject) continue;
if (hit.TryGetComponent(out ICardDropArea area))
{
foundArea = area;
break;
}
}
if (foundArea != null)
{
foundArea.OnCardDrop(this);
FieldManager field = FindFirstObjectByType<FieldManager>();
field.fieldCards.Add(this);
field.UpdateTotalPower();
}
else
{
// возврат в руку
transform.position = starDragPosition;
transform.rotation = starDragRotation;
handManager.UpdateCardsPosition();
}
}
Quaternion GetMouseRotationInWorldSpace()
{
Quaternion r = transform.rotation;
r.z = 0;
return r;
}
Vector3 GetMousePositionInWorldSpace()
{
Vector3 p = Camera.main.ScreenToWorldPoint(Input.mousePosition);
p.z = 0;
return p;
}
public void RemoveCard()
{
handManager.handCards.Remove(gameObject);
handManager.UpdateCardsPosition();
}
public void Init(clCard card)
{
this.card = card;
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.TryGetComponent(out ICardDropArea area))
{
currentDropArea = area;
}
}
private void OnTriggerExit2D(Collider2D collision)
{
if (collision.TryGetComponent(out ICardDropArea area) && currentDropArea == area)
{
currentDropArea = null;
}
}
}
Код драг зоны:
using DG.Tweening;
using NUnit.Framework;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Splines;
using TMPro;
public class UpCardDropArea : MonoBehaviour, ICardDropArea
{
[SerializeField] public int maxHandsSize;
[SerializeField] public SplineContainer splineContainer;
[SerializeField] float cardSpacing = 0.08f;
private Collider2D col;
private HandManager handManager;
void Start()
{
col = GetComponent<Collider2D>();
}
// Start is called once before the first execution of Update after the MonoBehaviour is created
public void OnCardDrop(Card card)
{
card.RemoveCard();
card.transform.SetParent(transform); // ✅ лучше чем null
handCards.Add(card.gameObject);
card.canDrag = false;
UpdateCardsPosition();
if (handCards.Count >= maxHandsSize)
{
col.enabled = false;
}
}
public List<GameObject> handCards = new();
public void UpdateCardsPosition()
{
if (handCards.Count == 0) return;
Spline spline = splineContainer.Spline;
float start = 0.5f - (handCards.Count - 1) * cardSpacing / 2f;
for (int i = 0; i < handCards.Count; i++)
{
float p = start + i * cardSpacing;
Vector3 splinePosition = splineContainer.transform.TransformPoint(spline.EvaluatePosition(p));
handCards[i].transform.DOMove(splinePosition, 0.4f);
// фиксированный поворот (карта всегда ровная)
handCards[i].transform.DORotate(Vector3.zero, 0.4f);
SortingGroup sg = handCards[i].GetComponentInChildren<SortingGroup>();
sg.sortingOrder = i;
}
}
}
Код руки:
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Splines;
using DG.Tweening;
public class HandManager : MonoBehaviour
{
[SerializeField] public int maxHandsSize;
[SerializeField] public SplineContainer splineContainer;
[SerializeField] public Transform spawnPoint;
[SerializeField] public List<CardData> cardDatas;
[SerializeField] private CardView cardViews;
public int re = 10;
private List<clCard> deck = new();
public List<GameObject> handCards = new();
void Start()
{
// создаём колоду
for (int i = 0; i < re; i++)
{
CardData data = cardDatas[Random.Range(0, cardDatas.Count)];
clCard card = new(data);
deck.Add(card);
}
}
void Update()
{
}
public void DrawCard()
{
if (handCards.Count >= maxHandsSize) return;
if (deck.Count == 0) return;
// берём карту
clCard drawnCard = deck[Random.Range(0, deck.Count)];
deck.Remove(drawnCard);
// создаём карту
CardView view = Instantiate(cardViews, spawnPoint.position, spawnPoint.rotation);
// настраиваем данные
view.Setup(drawnCard);
Card cardComponent = view.GetComponent<Card>();
cardComponent.Init(drawnCard);
// добавляем в руку
handCards.Add(view.gameObject);
UpdateCardsPosition();
}
public void UpdateCardsPosition()
{
if (handCards.Count == 0) return;
float cardSpacing = 1f / maxHandsSize;
float firstCardPosition = 0.5f - (handCards.Count - 1) * cardSpacing / 2;
Spline spline = splineContainer.Spline;
for (int i = 0; i < handCards.Count; i++)
{
float p = firstCardPosition + i * cardSpacing;
Vector3 splinePosition = spline.EvaluatePosition(p);
Vector3 forward = spline.EvaluateTangent(p);
Vector3 up = spline.EvaluateUpVector(p);
// Кватернион считается в мировом пространстве
Quaternion rotation = Quaternion.LookRotation(up, Vector3.Cross(up, forward).normalized);
// ИСПРАВЛЕНИЕ 1: используем DORotateQuaternion для мирового вращения
handCards[i].transform.DOMove(splinePosition, 0.25f);
handCards[i].transform.DORotateQuaternion(rotation, 0.25f);
SortingGroup sg = handCards[i].GetComponentInChildren<SortingGroup>();
sg.sortingOrder = i + 10;
}
}
}