Я реализовал 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.
Или есть другой способ это преодолеть?
Вы заказываете прямо туториал, а не задаёте вопрос.
Но, давайте, отвечу вам на один из ваших вопросов, который мне кажется основным.
Да, вручную событие отправить можно.
Ваш класс 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;
}
}
}
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости