2022/12/29

노윤수·2022년 12월 29일

drag and drop

public class CombiWords : MonoBehaviour, IPointerDownHandler, IBeginDragHandler, IEndDragHandler, IDragHandler
{
    public GameObject HintCombinationTable;
    [SerializeField] private Canvas canvas;
    RectTransform rectTransform;
    CanvasGroup canvasGroup;

    private void Awake()
    {
        rectTransform = GetComponent<RectTransform>();
        canvasGroup = GetComponent<CanvasGroup>();
    }

    public void OnBeginDrag(PointerEventData eventData)
    {
        canvasGroup.blocksRaycasts = false;
    }

    public void OnDrag(PointerEventData eventData)
    {
        rectTransform.anchoredPosition += eventData.delta / canvas.scaleFactor;
        gameObject.transform.SetParent(HintCombinationTable.transform);
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        canvasGroup.blocksRaycasts = true;
    }

    public void OnDrop(PointerEventData eventData)
    {
        throw new System.NotImplementedException();
    }
}

네달 전에는 구현 못하던 기능인데 이제 구현 가능해져서 기분이 좋네요. 드롭한 물체의 개수에 따라서 기존 드롭한 물체들의 위치도 바뀌는 기능입니다. list(vector2)를 이용해서 배열 선언할때 길이는 선언하지 않을 수 있도록 했습니다.

중요한 부분은 onDrag입니다. 마우스를 클릭한 상태에서 eventData.delta를 anchoredPosition에 추가하는 것까지는 생각 할 수 있으나, canvas의 크기에 맞춰서 드래그가 되어야 하기 때문에 canvas.scaleFactor를 나누어 주어야합니다. 그리고 동시에 hintCombinationTable의 자식으로 설정해줌으로써 다음 장에서 쓰는 스크립트에서 이용할 수 있도록 해줍니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using System.ComponentModel;

public class WordSlot : MonoBehaviour, IDropHandler, INotifyPropertyChanged
{
    RectTransform rectTransform;
    public static int GetNum = 0;
    public int _GetNum;
    float startX = -753;
    float endX = 753;
    public static int numberChanged = 0;
    public event PropertyChangedEventHandler PropertyChanged;
    public int changeNum
    {
        get { return numberChanged; }
        set
        {
            Debug.Log("프로퍼티 변경 실행");
            LocationChange();
            numberChanged++;
        }
    }
    public List<Vector2> anchoredPositionArray = new List<Vector2>();
    private void Awake()
    {
        _GetNum = GetNum;
        rectTransform = GetComponent<RectTransform>();
        changeNum++;
    }
    public void OnDrop(PointerEventData eventData)
    {
        changeNum++;
        if (eventData.pointerDrag != null)
        {
            LocationChange();
            GetNum++;
        }
    }

    public void LocationChange()
    {
        Debug.Log("진짜 변경");
        anchoredPositionArray.Clear();

        for (int i = 0; i < transform.childCount; i++)
        {
            anchoredPositionArray.Add(new Vector2(startX + (endX - startX) * (i + 1) / (GetNum + 2), 0));
            transform.GetChild(i).GetComponent<RectTransform>().anchoredPosition = anchoredPositionArray[i];
            transform.GetChild(i).GetComponent<CanvasGroup>().blocksRaycasts =false;
        }
    }
}

새로운 오브젝트를 드래그앤 드롭할때마다 locationChange함수가 실행됩니다. 기존의 위치를 모두 조정해야하기 때문에, 배열을 깔끔하게 삭제한 뒤, 내분점을 자식오브젝트의 개수만큼 추가해주어서 각각의 자식오브젝트가 내분점에 anchoredPosition으로 들어갈 수 있도록 해줍니다. 그리고, blockRaycasts를 false로 해서 더 이상 입력을 받지 않도록 해줍니다. blockRaycasts는 true일때 입력을 받고, false일때 입력을 받지 않습니다.
profile
코딩조아

0개의 댓글