Что это: Пошаговая инструкция: как сделать свою вью карты и подключить её к системе (HandView, анимации, раскладки).
Как использовать: см. разделы ниже.
Пошаговая инструкция: как сделать свою вью карты и подключить её к системе (HandView, анимации, раскладки).
Реализуйте интерфейс ICardView: Data, IsFaceUp, Transform, SetData, Flip, FlipAsync, MoveToAsync, SetInteractable, события OnClicked/OnHovered/OnUnhovered.
Пример скелета:
public class MyCardView : MonoBehaviour, ICardView
{
public CardData Data { get; private set; }
public bool IsFaceUp { get; private set; }
public Transform Transform => transform;
public event Action<ICardView> OnClicked;
public event Action<ICardView> OnHovered;
public event Action<ICardView> OnUnhovered;
public void SetData(CardData data, bool faceUp = true)
{
Data = data;
IsFaceUp = faceUp;
// обновить визуал (спрайт, текст и т.д.)
}
public void Flip()
{
IsFaceUp = !IsFaceUp;
// обновить визуал
}
public async UniTask FlipAsync(float duration = 0.3f)
{
// анимация переворота (например scaleX 0 -> 1 и смена спрайта)
IsFaceUp = !IsFaceUp;
await UniTask.CompletedTask;
}
public async UniTask MoveToAsync(Vector3 position, float duration = 0.2f)
{
var tween = transform.DOMove(position, duration).SetEase(Ease.OutQuad);
await UniTask.WaitUntil(() => !tween.IsActive());
}
public void SetInteractable(bool interactable) { /* raycast, кнопка */ }
}Подключение: передайте экземпляр в HandView.AddCardAsync(myCardView) или в CardPresenter.
Если карта всегда открыта или всегда закрыта — реализуйте ICardDisplayMode и возвращайте AlwaysFaceUp или AlwaysFaceDown. Тогда Flip/FlipAsync можно оставить пустыми или no-op.
Реализуйте ICardViewAnimations: PlayOneShotAsync, PlayLooped, StopLooped, StopAllLooped. Внутри вызывайте CardViewAnimationTemplates для своего transform:
public async UniTask PlayOneShotAsync(CardViewAnimationType type, float? duration = null, CancellationToken cancellation = default)
{
Tween t = CardViewAnimationTemplates.PlayOneShot(transform, type, duration ?? 0.3f);
if (t != null)
await UniTask.WaitUntil(() => !t.IsActive(), cancellationToken: cancellation);
}Зацикленные анимации: храните активные твины в словаре по типу и по StopLooped убивайте их.
- HandView работает с любым ICardView: добавление/удаление карт, раскладка (Fan, Line, Grid).
- CardPresenter принимает (ICardView view, DeckConfig config) и связывает данные с вью.
- Для дропа/перетаскивания: обрабатывайте клик или IDragHandler на своей вью и вызывайте MoveToAsync или перенос между зонами в логике игры.
| Вариант | Когда использовать |
|---|---|
| CardComponent | No-code, настройка в инспекторе, классические карты (колода 36/52/54), существующие примеры (Пьяница). |
| Своя ICardView / CardViewUniversal | MVP с кодом, произвольные карты, кастомный визуал и анимации, режимы «всегда открыта» и т.д. |
Если у вас своя модель карты (id, название, стоимость, арт):
- Сделайте свой интерфейс вью (например IMyGameCardView) с SetData(MyCardData) и при необходимости свои события.
- Визуал и логику зон реализуйте сами; для анимаций и раскладок переиспользуйте:
- CardViewAnimationTemplates — Bounce, Pulse, Shake, Highlight, FlyIn, Idle;
- CardLayoutCalculator и CardLayoutSettings (Config, Utils) для позиций карт в руке/зоне.
Так вы не привязаны к CardData, но используете общие анимации и раскладки.
- Interfaces
- CardViewUniversal
- README Cards — две ветки (классические карты vs произвольные)