Как обрабатывать клики и перетаскивания 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;
        }
    }
}

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

→ Ссылка