using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
public class Card : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler
{
[Header("Card ID")]
[SerializeField]
private int _cardID = -1; // 초기값, -1인 상태로 사용되면 예외처리 핸들링
// public int CardID => _cardID;
private Canvas _canvas;
/// <summary>
/// 카드의 여러 값을 생싱시 세팅
/// </summary>
/// <param name="id"></param>
public void Init(Canvas canvas, int id)
{
_canvas = canvas;
_cardID = id;
transform.GetChild(0).GetComponent<TextMeshProUGUI>().text = _cardID.ToString();
}
public int GetCardID()
{
return _cardID;
}
// 드래그 시작 처리
public void OnBeginDrag(PointerEventData eventData)
{
Debug.Log("OnBeginDrag");
CardArrowLineMaker.Instance.ActiveLineDrawer(true);
CardArrowLineMaker.Instance.SetIsDragging(true);
var cam = Camera.main;
float depth = 0f - cam.transform.position.z;
Vector3 sp = new Vector3(eventData.position.x, eventData.position.y, depth);
Vector3 start = cam.ScreenToWorldPoint(sp);
start.z = 0f;
CardArrowLineMaker.Instance.SetStartPoint(start);
}
// 드래그 중 처리
public void OnDrag(PointerEventData eventData)
{
Debug.Log("OnDrag");
var cam = Camera.main;
float depth = 0f - cam.transform.position.z; // 목표 z=0
Vector3 sp = new Vector3(eventData.position.x, eventData.position.y, depth);
Vector3 end = cam.ScreenToWorldPoint(sp);
end.z = 0f;
CardArrowLineMaker.Instance.SetEndPoint(end);
}
// 드래그 종료 처리
public void OnEndDrag(PointerEventData eventData)
{
Debug.Log("OnEndDrag");
CardArrowLineMaker.Instance.SetIsDragging(false);
CardArrowLineMaker.Instance.ActiveLineDrawer(false);
}
}
현재 카드 기능을 드래그해서 GUI에 표현하는 것 까지 해두었다
이제 카드를 적에게 드래그해서 놓는 순간을 구현한다
핵심은 end시 ray를 발사해서 적을 찾고, 그 적에게 어떤 행동을 한다는 매커니즘이다
// 드래그 종료 처리
public void OnEndDrag(PointerEventData eventData)
{
Debug.Log("OnEndDrag");
CardArrowLineMaker.Instance.SetIsDragging(false);
CardArrowLineMaker.Instance.ActiveLineDrawer(false);
// shoot ray to camera space
Camera cam = Camera.main;
Ray ray = cam.ScreenPointToRay(eventData.position);
RaycastHit2D hit = Physics2D.GetRayIntersection(ray, Mathf.Infinity);
if (hit.collider.gameObject.tag == "Enemy")
{
Debug.Log("Hit to enemy");
}
}
드래그를 끝내는 순간 레이를 발사해서 적 태그를 감지 후 처리한다
레이어로 처리해도 되는데 일단은 편한게 태그라서 태그로 처리했다

debug가 잘 나오는 것을 확인할 수 있다
using UnityEngine;
public class CardManager : MonoBehaviour
{
[Header("card area")]
[SerializeField]
private Transform _handArea;
[Header("card prefab")]
[SerializeField]
private GameObject _card;
[Header("draw Deck")]
[SerializeField]
private Deck _drawDeck;
[Header("player object")]
[SerializeField]
private Player _player;
[Header("select card")]
[SerializeField]
private Card _selectCard;
[SerializeField]
private Canvas _canvas; // 최상위 Canvas
void Start()
{
_player.OnDrawCard += InstanceCard;
}
/// <summary>
/// 카드 드로우시 생성
/// </summary>
/// <param name="cardID"></param>
public void InstanceCard(int cardID)
{
GameObject card = Instantiate(_card, _handArea);
card.GetComponent<Card>().Init(_canvas, cardID);
}
/// <summary>
/// 카드 효과 호출 함수
/// </summary>
/// <param name="target"></param>
/// <param name="cardID"></param>
public void UsedCard(Character target, int cardID)
{
Debug.Log($"target:{target} / card : {cardID}");
}
}
이제 이 카드 매니저의 usedcard 함수와 연동시키면 된다
public event System.Action OnUsingCard;
public void UsedCard(Character target, int cardID)
{
Debug.Log($"target:{target} / card : {cardID}");
OnUsingCard.Invoke();
}
이때 델리게이트를 사용해서 연결하려 한다
맞는 방법은 모르겠지만 이번 프로젝트에서 델리게이트를 적극적으로 사용해볼 것 같다
....
반대로 해야한다
카드가 사용을 호출하면 이를 delegate로 cardmanager가 받아서 카드 효과를 사용한다
// if using card, than call this delegate
public event System.Action<int, Character> OnUsingCard;
// 드래그 종료 처리
public void OnEndDrag(PointerEventData eventData)
{
Debug.Log("OnEndDrag");
CardArrowLineMaker.Instance.SetIsDragging(false);
CardArrowLineMaker.Instance.ActiveLineDrawer(false);
// shoot ray to camera space
Camera cam = Camera.main;
Ray ray = cam.ScreenPointToRay(eventData.position);
RaycastHit2D hit = Physics2D.GetRayIntersection(ray, Mathf.Infinity);
if (hit.collider.gameObject.tag == "Enemy")
{
Debug.Log("Hit to enemy");
OnUsingCard.Invoke(_cardID, hit.collider.gameObject.GetComponent<Character>());
}
}
카드쪽에서 드래그를 끝낼시 검사하고 이를 델리게이트로 넘겨준다
/// <summary>
/// 카드 드로우시 생성
/// </summary>
/// <param name="cardID"></param>
public void InstanceCard(int cardID)
{
GameObject card = Instantiate(_card, _handArea);
card.GetComponent<Card>().Init(_canvas, cardID);
card.GetComponent<Card>().OnUsingCard += UsingCard;
}
/// <summary>
/// 카드 효과 호출 함수
/// </summary>
/// <param name="target"></param>
/// <param name="cardID"></param>
public void UsingCard(int cardID, Character target)
{
Debug.Log($"target:{target} / card : {cardID}");
}
이를 받아서 바로 처리하게 된다
대리자 패턴이다
/// <summary>
/// 카드 효과 호출 함수
/// </summary>
/// <param name="target"></param>
/// <param name="cardID"></param>
public void UsingCard(int cardID, Character target)
{
Debug.Log($"target:{target} / card : {cardID}");
// forTest
BattleManager.Instance.ApplyDamage(target, 5);
Debug.Log("적에게 5 데미지를 주었습니다");
}
테스트용으로 데미지를 준다

잘 출력되는 것을 확인할 수 있다
이제 사용된 카드가 무덤으로 들어가게 처리해준다
// 드래그 종료 처리
public void OnEndDrag(PointerEventData eventData)
{
//Debug.Log("OnEndDrag");
CardArrowLineMaker.Instance.SetIsDragging(false);
CardArrowLineMaker.Instance.ActiveLineDrawer(false);
// shoot ray to camera space
Camera cam = Camera.main;
Ray ray = cam.ScreenPointToRay(eventData.position);
RaycastHit2D hit = Physics2D.GetRayIntersection(ray, Mathf.Infinity);
if (hit.collider.gameObject.tag == "Enemy")
{
Debug.Log("Hit to enemy");
OnUsingCard.Invoke(_cardID, hit.collider.gameObject.GetComponent<Character>());
Destroy(gameObject);
}
}
카드 사용시 카드는 사실상 GUI이기에 삭제 후
/// <summary>
/// 카드 효과 호출 함수
/// </summary>
/// <param name="target"></param>
/// <param name="cardID"></param>
public void UsingCard(int cardID, Character target)
{
Debug.Log($"target:{target} / card : {cardID}");
// forTest
BattleManager.Instance.ApplyDamage(target, 5);
Debug.Log("적에게 5 데미지를 주었습니다");
_graveyardDeck.SetCardToTop(cardID);
}
카드 매니저에서 덱의 탑으로 올려준다
'개발일지 > 게임개발' 카테고리의 다른 글
| Project_DT - 카드 효과 처리 매커니즘 (1) | 2025.10.09 |
|---|---|
| Project_DT - 카드 database 구축 (0) | 2025.10.01 |
| Project_DT - 카드 드래그 가이드 개발 (2) | 2025.09.25 |
| Project_DT - 카드 사용 구현 (2) | 2025.09.23 |
| Project_DT - 플레이어 드로우 기능 (0) | 2025.09.23 |