How to move gameObject OnMouseDown slowly from one position to another?

Hi everybody,

I am new to Unity and it’s coding.
I am simply trying to make an gameObject float 2 meters up (animated with duration) when the player clicks the gameObject. I thought on using the following code

void OnMouseDown ()
	{
		rigidbody.MovePosition(rigidbody.position + speed * Time.deltaTime);
	}

But obviously like the code instructs the object just teleports from on position to the other. How can I make the object move slowly between these two points? I was thinking to mix something up with update() and OnMouseDown() but got stuck here. Can somebody help me out with this one? Highly appreciated.

If you want the cube to start moving when you click it, simply set a bool OnMouseDown, and check that in update:

bool shouldMove = false;

void Update() {
    if(shouldMove)
        rigidbody.MovePosition(transform.position + speed * Time.deltaTime);
}

void OnMouseDown() {
    shouldMove = true;
}

That’ll get it moving, assuming you’ve defined the vector ‘speed’.

If you want it to stop moving when you click it, you can simply put “shouldMove = false” in the OnMouseUp method. If you want it to only move a certain distance, you need to set up a target, and move towards it at a certain speed:

float speed = 3f; //set to whatever you want
Vector3 target;
bool shouldMove = false;

void Start() {
    target = transform.position + Vector3.up; //Or, you know, wherever you want the target to be
}

void Update() {
    if(shouldMove)
        rigidbody.MovePosition(Vector3.MoveTowards(transform.position, target, speed * Time.deltaTime));
}

void OnMouseDown() {
    shouldMove = true;
}

Note that here, speed is a float. Hope this helps!

Hello,
You can use Rigidbody.AddForce(…) and the physics will do the job. This is the simplest way.

You can use Transform.translate and also use Vector3.Lerp so the transition is “smooth”

There are a couple of solutions.

Use an animation

IMHO the easiest solution is to add an Animation component.

Then create an animation that moves the transform.y upwards and set it as default animation. Then the code is as easy as:

void OnMouseDown()
{
    animation.Play();
}

Doing more fancy moves like a smoothed or some jittering when the object “arrives” is as easy as it is for you to edit any animation in the animation window. :slight_smile:

If it gets advanced later you can easily extend the animation, use AnimationEvents to trigger more code or even convert to a mecanim animator controller if it gets too messy.

Use Update() and a member variable

If you want to do the moving in-code by yourself, an easy start is to hold the “target position” in a member variable, only set this variable and then do the moving in Update()

Vector3 shouldPosition;
void OnMouseDown()
{
    shouldPosition = rigidbody.position + Vector3.up * 2; // should be 2 meter above from where its now
}

void Update()
{
    if (shouldPosition != Vector3.zero)
    {
        rigidbody.MovePosition(Vector3.MoveTowards(rigidbody.position, shouldPosition, Time.deltaTime * speed));
    }
    if (rigidbody.position == shouldPosition)
    {
        shouldPosition = Vector3.zero;
    }
}

Disadvantage: You have to add any kind of “cool thing” by writing code and do it yourself. Like an ease-out effect (look at Vector3.Lerp for that).

Use StartCoroutine and a parameter

Slightly similar to the previous suggestion, you can spawn a new coroutine that holds the “shouldPosition” so you save the trouble with the member variable. It might be a bit faster (I doubt you will notice, though). And some people just prefer coroutines… :wink:

void OnMouseDown()
{
    StartCoroutine(MoveUpwards(rigidbody.position + Vector3.up * 2));
}

IEnumerator MoveUpwards(Vector3 shouldPosition)
{
    while (rigidbody.position != shouldPosition)
    {
        rigidbody.MovePosition(Vector3.MoveTowards(rigidbody.position, shouldPosition, Time.deltaTime * speed));
        yield return null;
    }
}