Как обрабатывать клики и перетаскивания gameobject'ов в Unity?
Мне нужно сделать контроллер, который бы обрабатывал клики на элементы и их перетаскивания мышью.
Сейчас обработка кликов есть в Update() - сравниваются теги и, в зависимости от тега, происходит какое-то действие.
private void Update()
{
if (!Input.GetMouseButtonDown(0)) return;
var ray = cam.ScreenPointToRay(Input.mousePosition);
if (!Physics.Raycast(ray, out var hit)) return;
if (hit.collider.CompareTag("Bishop"))
Debug.Log("Bishop");
else
Debug.Log(hit.collider.tag);
}
А как к этому можно добавить еще и обработку перетаскиваний? И нормально ли вообще использовать Update() для этого или лучше OnMouseDown() и OnMouseDrag()?
Ответы (1 шт):
Автор решения: Psyxoz0x13
→ Ссылка
Этот скрипт вешаем в любое место (я вешаю на камеру):
using UnityEngine;
public class Draging : MonoBehaviour
{
public Vector3 MouseWorldPosition { get; private set; }
[SerializeField] private float _cameraDragOffset = 4f;
private Camera _camera;
private DraggableObject _target;
private bool _isDragging;
private void Awake()
{
_camera = Camera.main;
}
private void Update()
{
if (Input.GetMouseButtonDown(0) && _isDragging == false)
{
_isDragging = TrySetTarget();
}
else if (Input.GetMouseButtonUp(0))
{
_isDragging = false;
_target?.StopDrag();
}
var mousePosition = Input.mousePosition;
mousePosition.z = _cameraDragOffset;
MouseWorldPosition = _camera.ScreenToWorldPoint(mousePosition);
}
private bool TrySetTarget()
{
var ray = _camera.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out RaycastHit raycastHit) &&
raycastHit.transform.TryGetComponent(out DraggableObject draggableObject))
{
_target = draggableObject;
draggableObject.StartDrag(this);
return true;
}
return false;
}
}
Этот на каждый объект, который хотели бы перетаскивать:
using System.Collections;
using UnityEngine;
public class DraggableObject : MonoBehaviour
{
private Draging _draging;
private Coroutine _dragCoroutine;
public void StartDrag(Draging draging)
{
_draging = draging;
_dragCoroutine = StartCoroutine(GetDrag());
}
public void StopDrag()
{
StopCoroutine(_dragCoroutine);
}
private IEnumerator GetDrag()
{
while (true)
{
transform.position = Vector3.Lerp(
transform.position,
_draging.MouseWorldPosition,
Time.deltaTime * 10f);
yield return null;
}
}
}
Довольно сыроват, но думаю суть ясна. Не очень понятно для какой игры и какие условия нужны, это уже настройте под себя.