Drag and Release 3D

Hello,

Needing some help with my Drag and Release code.

Currently, my code does the following : -

Determines the direction my ‘Player’ is facing using the mouse position
If GetMouseButtonDown - record this position
else if GetMouseButtonUp - record this last position of the mouse and store the value
use the stored value to apply force in the direction the ‘Player’ is facing

So, currently I can click anywhere for this to happen, and ideally I want this to only happen when I click directly on my player object, I’ve looked into scripting for onMouseDown, and onMouseUp, but unsure as to how to implement it properly, can anyone help with this, guide me a little ?

using UnityEngine;
using System.Collections;

public class dragRelease3D : MonoBehaviour {

    Vector3 delta     = Vector3.zero;
    Vector3 lastPos = Vector3.zero;

    // Speed at which 'Player' faces away from the mouse position, default : 16

    public float FaceAwaySpeed = 16;

    // Force Type Dropdown - Default : Velocity Change
    public ForceMode ForceType = ForceMode.VelocityChange;

    void Update () {

        // Player facing direction, 'Away' from mouse position

        // Generate a plane that intersects the transform's position with an upwards normal
        Plane playerPlane = new Plane(Vector3.up, transform.position);
        // Generate a ray from the cursor position
        Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
        // Determine the point where the cursor ray intersects the plane
        float hitdist = 0.0f;
        // If the ray is parallel to the plane, Raycast will return false
        if (playerPlane.Raycast (ray, out hitdist))
        {
            // Get the point along the ray that hits the calculate distance
            Vector3 targetPoint = ray.GetPoint(hitdist);
            // Determine the target rotation.  This is the rotation if the transform looks at the target point
            Quaternion targetRotation = Quaternion.LookRotation(targetPoint - transform.position);
            // Smoothly rotate towards the target point ( at FaceAwaySpeed )
            transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, FaceAwaySpeed * Time.deltaTime);
            // End of Player facing direction segment
        }

        if ( Input.GetMouseButtonDown(0) )
        {
            lastPos = Input.mousePosition;
        }
        else if ( Input.GetMouseButtonUp(0) )
        {
            delta = Input.mousePosition - lastPos;
            Debug.Log ("Delta Distance From Starting Position : " + delta.magnitude );

            // Multiply delta.magnitude times the force you want to apply to the 'Player'

            GetComponent<Rigidbody>().AddForce(-transform.forward * delta.magnitude, ForceType);

            // Make sure Gravity is enabled for the Rigidbody ( Player )

            GetComponent<Rigidbody>().useGravity = true;
        }
    }
}

I’d probably recommend going with the newer eventsystem approach for something like this. Once you’ve created the drag handler script you then just add it to whatever you want to drag/drop. BoredMormon covers this off in his handy tutorial:

it’s dealing with 2d, but you can apply the same scripts to 3d, just make sure you have the right raycaster component attached to the camera.

1 Like

So, thanks ! Managed to get this converted to the EventSystem approach, my code so far below ( for anyone interested or having similar problems ) : -

Miscellaneous ( but important ) - Scene needs to have a EventSystem added, and the Main Camera in your scene also requires a Physics Raycaster added.

TO DO :
(a) Still need to determine a maximum value that force can be applied, and if the user exceeds that, then default to that maximum value, otherwise use the lower value.
(b) Some sort of visual on screen guide to showcase the amount of force being applied, and possibly direction it will be applied

using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;

public class dragReleaseObject : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler

{
    Vector3 delta = Vector3.zero;
    Vector3 lastPos = Vector3.zero;

    // Speed at which 'Player' faces away from the mouse position, default : 16
    public float FaceAwaySpeed = 16;

    // Force Type Dropdown - Default : Velocity Change
    public ForceMode ForceType = ForceMode.VelocityChange;

    void Start()
    {
        Debug.Log("Start");
    }

    public void OnBeginDrag(PointerEventData _EventData)
    {
        Debug.Log("OnBeginDrag");
        lastPos = Input.mousePosition;
    }

    public void OnDrag(PointerEventData _EventData)
    {
        Debug.Log("OnDrag");

        // Player facing direction, 'Away' from mouse position

        // Generate a plane that intersects the transform's position with an upwards normal
        Plane playerPlane = new Plane(Vector3.up, transform.position);
        // Generate a ray from the cursor position
        Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
        // Determine the point where the cursor ray intersects the plane
        float hitdist = 0.0f;
        // If the ray is parallel to the plane, Raycast will return false
        if (playerPlane.Raycast (ray, out hitdist))
        {
            // Get the point along the ray that hits the calculate distance
            Vector3 targetPoint = ray.GetPoint(hitdist);
            // Determine the target rotation.  This is the rotation if the transform looks at the target point
            Quaternion targetRotation = Quaternion.LookRotation(targetPoint - transform.position);
            // Smoothly rotate towards the target point ( at FaceAwaySpeed )
            transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, FaceAwaySpeed * Time.deltaTime);
            // End of Player facing direction segment
        }
    }

    public void OnEndDrag(PointerEventData _EventData)
    {
        Debug.Log("OnEndDrag");
        delta = Input.mousePosition - lastPos;
        Debug.Log("Delta Distance From Starting Position : " + delta.magnitude );

        // Multiply delta.magnitude times the force you want to apply to the 'Player'

        GetComponent<Rigidbody>().AddForce(-transform.forward * delta.magnitude, ForceType);

        // Make sure Gravity is enabled for the Rigidbody ( Player )

        GetComponent<Rigidbody>().useGravity = true;
    }
}