How to drag gameobject elastically..?

Hi everyone,I need to click and drag a game object and when I release the game object it should go back to the original position with a wiggle effect like a bended rubber.

I know how to make the click and drag and bring it back to original state on releasing all I need is to get the wiggle effect due to elasticity and inertia with damping and the wiggle strength should depend on the stretch distance.Can anyone guide me through the scripting of this.

Below is the illustration which shows I want.

4 Answers

4

Whole new script, simpler but the concept remains.

It is known that elastic forces are of the type F = -k*x. But an ideal elastic force would never stop its movement so I added a perturbation that would slow down speed depending on its value. Right now its working and it´s very fun to see. Enjoy!

using UnityEngine;
using System.Collections;

public class Draggable : MonoBehaviour{

	private Vector3 origin;
	private float forceConstant = 200;
	private bool returning = false;
	private float precision = 0.1f;


	private void Start(){
		origin = transform.position;
	}
	
	private void Update(){
		if (Input.GetMouseButton(0)){
			transform.position = new Vector3(5*Input.mousePosition.x/Screen.width, 5*Input.mousePosition.y/Screen.width, 0);
		}
		if (Input.GetMouseButtonUp(0)){
			returning = true;
                    rigidbody.constraints = RigidbodyConstraints.None;
		}

		if (returning){
			rigidbody.AddForce (forceConstant*(origin - transform.position));
			rigidbody.velocity *= 0.9f;
			if (rigidbody.velocity.magnitude < precision && 
                        Vector3.Distance(transform.position, origin) < precision){
                            rigidbody.constraints = RigidbodyConstraints.FreezeAll;
				returning = false;
			}
		}
	}
}

(Hopefully) Last edit: as you don´t seem to believe me I have uploaded a [18687-draggable.unitypackage.zip|18687] with the script and a scene showing it. Just load, play and click. It works WELL, it only needs to improve the mouse input part, but your question wasn´t about it so I just implemented a fast solution.

No this is not working.The UpdatePosition() function just brings the object smoothly back to its position.Its not making the object to wiggle before it stops.

sorry man just look at the code,there is no part in the code for making the wiggle.read my question.I need like a rubber effect.Click and drag and on release it should reach the original position like a stretched rubber band.It should offset left and right from its starting position like pingpong and come to rest.

Edited, it´s working well.

drag is not working correctly

i downloaded package and used it in new project. Its not working.

Somehow for me it became a nontrivial task.
Fully functional c# addition with smooth drag. For further users.

private Vector3 origin;
private float forceConstant = 20;
private bool returning = false;
private float precision = 0.1f;

public float speed = 9.0f;
private Vector3 targetPos;

private void Start(){
	origin = transform.position;
}

private void Update(){

	if (Input.GetMouseButton (0)) {
				
		float distance = transform.position.z - Camera.main.transform.position.z;
		targetPos = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, distance);
		targetPos = Camera.main.ScreenToWorldPoint (targetPos);
		transform.position = Vector3.MoveTowards (transform.position, targetPos, speed * Time.deltaTime);

// transform.position = new Vector3 (Input.mousePosition.x / Screen.width, Input.mousePosition.y / Screen.width, 0);

	}

	if (Input.GetMouseButtonUp(0)){
		returning = true;
		GetComponent<Rigidbody>().constraints = RigidbodyConstraints.None;
	}
	
	if (returning){
		GetComponent<Rigidbody>().AddForce (forceConstant*(origin - transform.position));
		GetComponent<Rigidbody>().velocity *= 0.9f;
		if (GetComponent<Rigidbody>().velocity.magnitude < precision && 
		    Vector3.Distance(transform.position, origin) < precision){
			GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezeAll;
			returning = false;
		}
	}
}

}

@sethuraj, the follow code works.

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

public class dragScript : MonoBehaviour {

	private Vector3 screenPoint;
	private Vector3 offset;

	public Transform cube;
	public float speed;
	Vector3 startPosition;
	public bool CUbeReleased;
	public Vector3 dir;
	public Vector3 curPosition;
	public float value = 8.0f;
	void Start()
	{
		startPosition = transform.position;
	
	}

	void OnMouseDown()
	{
		screenPoint = Camera.main.WorldToScreenPoint(gameObject.transform.position);

		offset = gameObject.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));

	}

	void OnMouseDrag()
	{

			Vector3 curScreenPoint = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, screenPoint.z);

			curPosition = Camera.main.ScreenToWorldPoint (curScreenPoint) + offset;
			transform.position = curPosition;
			
	}
	void OnMouseUp()
	{
		

		CUbeReleased = true;

	}

	void Update() {
		

		if (CUbeReleased == true && Vector3.Distance(this.transform.position,cube.transform.position) > 0.3f) {


			dir = cube.transform.position - this.transform.position;
			dir.Normalize ();

			this.gameObject.GetComponent<Rigidbody> ().AddForce (dir * (Mathf.Sin (dir.sqrMagnitude)*value));

			//if (this.gameObject.GetComponent<Rigidbody> ().velocity.magnitude < 1.0f && Vector3.Distance(this.transform.position,cube.transform.position) < 0.2f) {
			
			//	value = 0.1f;
			//}
			Debug.Log (Mathf.Abs(Vector3.Distance(this.transform.position,cube.transform.position)));
		}
	}



}

Why not use a Tween asset, like DOTween?