RTS style mouse click and unit move to mouse click

I am currently trying to make an RTS style game in Unity, but I am having trouble trying to get a unit to move to where I click the mouse button.

I’m using a raycast to get the coordinates and then using LookAt() to have the unit face where the mouse click took place. My problem is I’m stumped on how to make it move towards the mouse click.

I’ve tried rigidbody.addforce(), transform.forward(), transform.Translate() to just make the unit move foward since it is already facing in the proper direction. Is there a function I can try to get my unit to move foward, or is there a better way of getting the unit to move towards the mouse click?

I’ve been playing around with a cube in a new scene and trying to write code to make it face in the direction of a mouse click and move forward towards that click, here’s my code that I have already: (Please excuse me as I’m new to javascript and trying anything I can think of to make it work)

Any idea is appreciated big time!

function FixedUpdate ()

{

 if(Input.GetMouseButtonDown(0))
		ShootRay();
}

function ShootRay()

{

 var ray = Camera.main.ScreenPointToRay(Input.mousePosition);

 var hit: RaycastHit;

	if(Physics.Raycast(ray, hit, Mathf.Infinity))
		{
			cube = GameObject.Find("Cube");
			
		       cube.transform.LookAt(Vector3(hit.point.x,0,hit.point.z));
		       cube.transform.Translate(hit.point.x,0,hit.point.z);
		
		}
		
}

Lord Richard’s answer is pretty spot on. I figured I would elaborate on it a bit to give you a working point.

Please excuse any syntax errors here as I usually work in C# but wrote this in Javascript since that appears to be what you are working in.

I created two separate scripts for this concept. One I called CommandMove.js, this is assigned to the player camera, it would essentially be in your input scripts. The goal of this script is basically what your above one is.

Goals: Receive user input, Tell unit GameObject to move.

The only changes I made were as follows:

function ShootRay() {
	var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
	var hit : RaycastHit;

    if(Physics.Raycast(ray, hit, Mathf.Infinity)) {
    	var moveScript : UnitMoveable = unit.GetComponent("UnitMoveable");
    	if (moveScript) {
    		moveScript.MoveTo(hit.point);
    	}
    }
}

In this code assume that “unit” is a GameObject var that is your unit you want to move (ie. your cube). What this does is creates a variable for a script component called UnitMoveable.js, if that component is assigned to the object, then it calls the MoveTo function on that Unit, passing in the Vector3 point that you clicked.

UnitMoveable.js is as follows:

var moveSpeed : float = 2.0f;
private var vDestination : Vector3;
private var isMoving : boolean;

function Start () {
	isMoving = false;
}

function FixedUpdate () {
	if (isMoving) {
		if (transform.position.Equals(vDestination)) {
			isMoving = false;
		}
		else {
			// Vector will do a linear interpolation between our current position and our destination
			var v : Vector3;
			v = Vector3.Lerp(transform.position,vDestination,Time.fixedDeltaTime * moveSpeed);

			// Raycast to the surface below our next destination step to make sure we are standing on it
			// this is probably not efficient for large numbers
			var hit : RaycastHit;
			if (Physics.Raycast(v, Vector3.down, hit, 5.0f)) {
				// collider.bounds.extents.y will be half of the height of the bounding box
				// only useful if your pivot point is in the center, if it's at the feet you don't need this
				v.y = hit.point.y + collider.bounds.extents.y;
			}
			// set our position to the new destination
			transform.position = v;
		}
	}
}

function MoveTo (vPoint:Vector3) {
	vDestination = vPoint;
	isMoving = true;
}

I commented in-line, but essentially what his does is stores a Vector3 for the destination, and whether the unit is moving or not (optional), plus the units movement speed.

When it gets told to MoveTo all it does is set the new destination point based on what ShootRay() sent it. Then it says it’s moving. FixedUpdate then Lerps between the current point and the destination adjusting by movespeed.

I also added a little piece of code here that raycasts down from the unit to the surface below to adjust the height of the destination point so that it travels across uneven terrain. I am unsure if this is the best or most efficient way to do this, but thought I would include it.

Hope this helps you get started.

What I chose to do is make a selection manager object. Which I believe you have. Then I assign it a changeCommand(int i) method to give it a command. In the move command I can have a target location or give a noted path function to move to the location based on an array list of positions (avoiding obstacles) to get to that location. I used a transform lerp command to move the unit alwaysnforward and then used look at to turn it to the destination location. Make your code modular so you can reuse it for other units and change the specific behavior. You can ignore the path nodes for now if you just need a simple turn and move operation right now though.