How do i drag a transform parallel to a plane with my mouse at a certain offset?

Hi there! Hope your day is going well :slight_smile:

Right now I am trying to figure out how to drag a transform parallel to a plane with my mouse with an additional offset. For example, I want to target something and then be able to always have it hover 1 unit off the plane.

Currently, I have something working where I can drag my transform, but it stays a set distance away from the camera.

I cannot seem to figure out the distance needed for it to stay parallel, nor am I sure I even am going about this the right way.

Here is my current code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SelectionManager : MonoBehaviour
{
    [SerializeField] private string selectableTag = "selectable";
    [SerializeField] private Material highlightMaterial;
    [SerializeField] private Material defaultMaterial;
    private Transform _selection;
    public Transform _grabbed;
    public float _grabbed_distance;
    // Start is called before the first frame update
    void Start()
    {
    }

    // Update is called once per frame
    private void Update()
    {
        if (_selection != null) {
            var selectionRenderer = _selection.GetComponent<Renderer>();
            selectionRenderer.material = defaultMaterial;
            _selection = null;
        }
        var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;
        if (Physics.Raycast(ray, out hit)) {
            var selection = hit.transform;
            if (selection.CompareTag(selectableTag)) {
                var selectionRenderer = selection.GetComponent<Renderer>();
                if (selectionRenderer != null) {
                    selectionRenderer.material = highlightMaterial;
                }
                _selection = selection;
            }
        }

        if (Input.GetMouseButtonDown(0)) {
            if (_grabbed != null) {
                _grabbed = null;
            }
            else if (_grabbed == null) {
                if (hit.transform.CompareTag(selectableTag)) {
                _grabbed = hit.transform;
                _grabbed_distance = Vector3.Distance(_grabbed.position,Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y,0)));
                }
            }
        }

        if (_grabbed != null) {
            Vector3 pre_point = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, _grabbed_distance));
            // _grabbed_distance = _grabbed_distance/pre_point.y;
            Vector3 point = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, _grabbed_distance));
            // _grabbed_distance = hit.distance;
            _grabbed.position = point;
            Debug.Log(_grabbed_distance + " | " + point.y);
        }
    }
}

I would raycast against a β€œvirtual” plane: Unity - Scripting API: Plane.Raycast

1 Like

Using the above link from exiguous i made this for my own drag of plane:

                private void OnMouseDrag()
                {

                var dragPlane = new Plane(dragPlaneTransform.up, dragPlaneTransform.position);
                Ray ray = playerCamera.ScreenPointToRay(Input.mousePosition);
                float enter;

                if (dragPlane.Raycast(ray, out enter))
                {
                    //Get the point that is clicked
                    Vector3 hitPoint = ray.GetPoint(enter);

                    //Move your cube GameObject to the point where you clicked
                    transform.position = hitPoint;
                }
1 Like