scrollrect и drop

317
26 января 2018, 20:25

Я реализовал scrollrect. Где есть группа дочерних объектов. По движению мышки, все перемещается.

Хочу ещё перемещать объекты между собой. Менять порядок их расположения, перетягивая объекты. Внутри scrollrect.

Для этого хочу, обрабатывать OnBeginDrag, OnDrag, OnEndDrag. Но после того как кнопку мыши была нажата 1 секунду на объекте.

Написал такой код.

Файл dragh.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class dragh : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler {
    public static GameObject itemBeingDragged;
    Vector3 startPosition;
    Transform startParent;
    public void OnBeginDrag(PointerEventData eventData)
    {
        itemBeingDragged = gameObject;
        startPosition = transform.position;
        startParent = transform.parent;
        Debug.Log("");
    }
    public void OnDrag(PointerEventData eventData)
    {
        transform.position = eventData.position;
    }
    public void OnEndDrag(PointerEventData eventData)
    {
        itemBeingDragged = null;
        transform.position = startPosition;
    }
}

Файл ControlDrop.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class ControlDrop : MonoBehaviour, IPointerDownHandler {
    private float controlTime = 1f;
    private float currentTime = 0f;
    private bool active = false;
    public void OnPointerDown(PointerEventData eventData)
    {
        active = true;
        GetComponent<dragh>().enabled  = false;
    }
    void Update () {
        if (Input.GetMouseButton (0) && active==true) {
            currentTime +=Time.deltaTime;
            if (currentTime >= controlTime)
            {
                active = false;
                GetComponent<dragh>().enabled = true;
                Debug.Log("ADD");
            }
        }
        if (Input.GetMouseButtonUp (0)) {
            currentTime = 0f;
            active = false;
            GetComponent<dragh>().enabled  = false;
        }
    }
}

В файле ControlDrop.cs я пытаюсь определить, что мышка находиться на объекте, с нажатой кнопкой более 1 секунды.

И активирую компонент dragh. Который собственно и отслеживает перетаскивание объекта.

Проблема в том, что если объект dragh, для отслеживания перемещения активируется в момент когда кнопка мыши нажата, он не срабатывает. И ни какие события не происходят.

Хочу получить, то как на этом видео: https://www.youtube.com/watch?v=Pj6uVoYl15M

Как это преодолеть? Возможно как то в ручную отправить событие OnBeginDrag.

Или есть другой способ это преодолеть?

Answer 1

Вы заказываете прямо туториал, а не задаёте вопрос.
Но, давайте, отвечу вам на один из ваших вопросов, который мне кажется основным.

Да, вручную событие отправить можно.
Ваш класс drag реализует интерфейс IBeginDragHandler, который собственно и является контрактом на реализацию метода

public void OnBeginDrag(PointerEventData eventData)

Другими словами, имея ссылку на объект вы можете вызвать у него этот метод. Вы уже работаете с этим объектом включая и выключая его. Так что мешает вызвать метод, когда вам это потребуется? И вообще, зачем вы каждый раз ищете объект? Закэшируйте его.

dragh _dragger;
void Start()
{
    _dragger = GetComponent<dragh>();
}

а после этого уже обращайтесь к нему, когда вам потребуется. Например, вызовете у него метод о начале перетягивания

_dragger.OnBeginDrag(null);   

Но сюда вам придётся передавать параметр PointerEventData, но, как я вижу, вы его не используете внутри метода, поэтому можно использовать null.

Использовать цикл Update вообще мысль грустная, как и стучаться в Input, если вам нужно узнать, а не нажата ли кнопка.
К тому же вы уже используете интерфейс IPointerDownHandle, который обеспечивает реакцию на нажатие ЛКМ на вашем объекте. Так развейте идею - у unity есть такое понятие, как корутины. т.е. работать этот цикл будет только тогда, когда вы зажмёте кнопку, а не каждый кадр что-то проверять. К тому же, можно использовать и ещё один интерфейс - IPointerUpHandle - реакция на отпускание кнопки. Реализация, например, такая:

Coroutine _routine;
float _duration = 1f;
public void OnPointerDown(PointerEventData eventData)
    {
        _routine = StartCoroutine()
    }
public void OnPointerUp(PointerEventData eventData)
    {
        if (_routine != null)
        {
            StopCoroutine(_routine);
        }
    }
IEnumerator TimerRoutine()
    {
        MonoBehaviour dragh = null;
        float left = 0;
        while (true)
        {
            left += Time.deltaTime;
            if (left >= _duration)
            {
                dragh.enabled = true;
                _routine = null;
                yield break;
            }
            else
            {
                yield return null;
            }
        }
    }
READ ALSO
TLSv1.0, вычисление &#39;HMAC&#39;

TLSv1.0, вычисление 'HMAC'

ЗдравствуйтеПрошу мне помочь, как сгенерировать HMAC от сообщения? HEX:

251
Получить web страницу через TcpClient

Получить web страницу через TcpClient

Пытаюсь получить содержимое страницы через TcpClient (c#)Взял за основу ответ HTTP запрос через TCPClient По какой то причине получаю ответ длинной 0

284
Отправка сообщений с Hangfire

Отправка сообщений с Hangfire

Покажите пожалуйста какой пример отправки сообщений на Email с технологией Hangfire

281
C# Запуск программы после входа пользователем в систему

C# Запуск программы после входа пользователем в систему

Есть программа, которая прописывает себя в автозагрузкуВсе работает, все отлично

246