How do I move my character to an object when I click on it?

Basic question here, and I feel like I’m close but can’t quite get it.

I have an object–it’s a pot on a stove–that is in my 2D game. There will be multiple pots that appear and disappear in the game, all in predefined places (like on top of the burners of a stovetop). There’s also a chef in the game, who goes to each pot and does an action. The user never directly controls the chef’s movement–instead, when the user clicks a pot, the chef runs over to the counter in front of that pot, where he can perform an action on the pot.

Can someone tell me how to do this? I’m not only looking for the code but for a “correct” design, in terms of where the various variables and methods should be located. In other words, what goes in the pot’s script and what goes in the chef’s script? (I’m using C#.)

My thought was that the pot GameObject would have an OnMouseDown() method, to catch the user clicking on it. And in that method, there should be a call to a Move() method that is attached to the chef GameObject. But what I have is not quite working. The chef moves one small bit toward the pot but then stops. I realize that this is because I’m calling the Move function once and that’s it; It seems like the Update method should be involved somehow (the pot’s or the chef’s?); or maybe I should have an if statement in my Move method that checks to see if the user is at the pot, and if not, runs the move code in a loop. Or maybe the design is just fundamentally wrong and it could be done more easily. Here is the code I have:

public class PotController : MonoBehaviour {

	private GameObject chefObject;
	
	void Start () {
		chefObject = GameObject.Find ("Chef");
	}

	void OnMouseDown() {
		ChefController chefScript = chefObject.GetComponent<ChefController> ();
		chefScript.Move ();
	}
}

public class ChefController : MonoBehaviour {

	public float moveSpeed;
	private Vector3 moveDirection;
	
	public void Move () {

		Vector3 currentPosition = transform.position;
		if (Input.GetButton ("Fire1")) {
			Vector3 moveToward = Camera.main.ScreenToWorldPoint (Input.mousePosition);
			moveDirection = moveToward - currentPosition;
			moveDirection.z = 0; 
			moveDirection.Normalize ();			
		}
		Vector3 target = moveDirection * moveSpeed + currentPosition;
		transform.position = Vector3.Lerp( currentPosition, target, Time.deltaTime );
	}
}

The design seems correct in my opinion. The way you implement it however, has problems. I would have used coroutines as follow :

 public class PotController : MonoBehaviour {
 
     private GameObject chefObject;
     
     void Start () {
         chefObject = GameObject.Find ("Chef");
     }
 
     void OnMouseDown() {
         ChefController chefScript = chefObject.GetComponent<ChefController> ();
         StartCoroutine( chefScript.Move ( transform.position ) );
     }
 }

 public class ChefController : MonoBehaviour {
 
     public float moveSpeed;
     private Vector3 moveDirection;
     
     public IEnumerator Move ( Vector3 position ) {
             // Make the chef move until he has reached his destination
		 while( ( position - transform.position ).magnitude > 0.01f )
		 {
			 transform.position = Vector3.Lerp( transform.position, position, Time.deltaTime * moveSpeed );
			 yield return new WaitForEndOfFrame() ;
		 }
     }
 }

If you have never used coroutines, take a look at this Unity tutorial :

https://unity3d.com/learn/tutorials/modules/intermediate/scripting/coroutines

I haven’t tested the code above and I am not familiar with 2D games. If there is any problem, tell me, I will try to help you.