Подмена объекта при drag'n'drop

Программирование на Юнити.

Подмена объекта при drag'n'drop

Сообщение Biser 19 авг 2019, 11:52

Всем добрый день! Столкнулся с интересной задачей, может кто то сталкивался с подобным и подскажет как можно решить.
Задача следующая:
Имеется сцена, на которой расположены две панели - на одной расположены объекты, представляющие всех доступных игроку персонажей, вторая панель отображает текущую сформированную из этих персонажей группу. Т.е. на второй панели есть слоты куда можно перетащить нужных персонажей из первой панели для формирования группы. При перетаскивании персонажей, они должны оставаться на первой панели, а по сути перетаскиваться должен некий упрощенный объект - ссылка на выбранного персонажа.

Т.е. задача формулируется примерно так: при начале перетаскивания объекта с первой панели нужно создавать "упрощенный" объект, и перемещать уже его вместо исходного.
Текущая реализация:
Объект первой панели (ActiveHero) имеет скрипт который создает нужный объект и инциирует начало его перетягивания
Синтаксис:
Используется csharp
public class ActiveHeroDragNDropBehaviour : MonoBehaviour, IBeginDragHandler
{
    public void OnBeginDrag(PointerEventData eventData)
    {
        GameObject slotPrefab = Resources.Load("Prefabs/PartyHero") as GameObject; //  префаб перетаскиваемого героя
        GameObject partyHero =  UnityEngine.Object.Instantiate(slotPrefab, transform);
        partyHero.GetComponent<PartyHeroBehaviour>().hero = gameObject.GetComponent<ActiveHeroSlotBehaviour>().hero; //тот же герой
        partyHero.transform.position = Input.mousePosition;
        partyHero.GetComponent<DragNDropHandler>().OnBeginDrag(eventData);
    }
}


Подмененный объект (PartyHero) имеет скрипт
Синтаксис:
Используется csharp
// обработчик перетаскивания - прекреплен к перетаскиваемому объекту
public class DragNDropHandler : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
    public static GameObject itemBeingDrag;
    public static bool dragOutOfSlot; // признак что отпустили вне слота
    Vector3 startPosition;
    Transform startParent;
   

    public void OnBeginDrag(PointerEventData eventData)
    {
        itemBeingDrag = gameObject;
        startPosition = transform.position;
        startParent = transform.parent;
        GetComponent<CanvasGroup>().blocksRaycasts = false;
        dragOutOfSlot = true; // по умолчанию считаем что отпустим за пределами слота. Если не так - то скрипт слота изменит значение
        Debug.Log("потащили ");
    }

    public void OnDrag(PointerEventData eventData)
    {
        transform.position = Input.mousePosition;
        Debug.Log("тащим ");
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        Debug.Log("EndDrag");
        itemBeingDrag = null;
        GetComponent<CanvasGroup>().blocksRaycasts = true;
        // определяем если отпустили за пределами панели слотов
        if (dragOutOfSlot) // если отпустили за слотом то считаем что удалили
        {
            UnityEngine.Object.Destroy(gameObject);
        }
        else // если
        {    
            transform.position = startPosition;
        }
    }  
}
 

Ну и есть ещё скрипт на слоте целевой панели, который фиксирует перемещение в него объекта:
Синтаксис:
Используется csharp
public class PartySlotBehaviour : MonoBehaviour, IDropHandler
{
    public GameObject item
    {
        get
        {
            if (transform.childCount > 0 )
            {
                return transform.GetChild(0).gameObject;
            };
            return null;
        }
    }

    public void OnDrop(PointerEventData eventData)
    {
        Debug.Log("Drop");
        if (!item)
        {
            DragNDropHandler.itemBeingDrag.transform.SetParent(transform);
        } else {
            item.transform.SetParent(DragNDropHandler.itemBeingDrag.transform.parent);
            DragNDropHandler.itemBeingDrag.transform.SetParent(transform);
        }
        DragNDropHandler.dragOutOfSlot = false; // считаем что отпустили в слоте
    }
}
 


В итоге это работает не совсем корректно - "Подмененный" объект появляется при начале перетаскивания, но не таскается визуально. В момент отпускания на слоте он туда попадает, но у него не установлен признак blocksRaycasts ...
Если таскать сам "Упрощенный" объект (предварительно помещенный для отладки в слот), то все работает отлично (последовательность записей отладки в консоле: потащили - тащим - EndDrag - Drop ). В нашем же случае последовательность (потащили - Drop).
Буду благодарен за помощь.
Biser
UNец
 
Сообщения: 1
Зарегистрирован: 19 авг 2019, 11:37

Вернуться в Скрипты

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 6