Get coords of MouseClick on Terrain

Hello Unity users :slight_smile:

A friend and I are currently starting up with Unity and trying hard to grasp the basics.
However we’ve encountered a problem with a small “game” which involves selecting a GameObject (via left click) and moving it to a selected area on a terrain (via left click again).

We’ve tried it with Input.mousePosition, only to realize that it gives you the screen coords and not the coords of the pixel clicked on.

How can we accomplish this?

Here’s our current script:

function OnMouseDown() {
	
	if(this.name != "Terrain"){
		DataPass.isClicked= true;
		DataPass.clickedGo = this;
	}
	else if(this.name == "Terrain"  DataPass.isClicked){
		DataPass.isClicked= false;
		DataPass.clickedGo.transform.position = Input.mousePosition;
	}
}
public static class DataPass{
	public var isClicked:boolean = false;
	public var clickedGo:Object = null;
}

The first script is assigned to the GameObject and the Terrain. DataPass is responsible for passing data between the two.
It works, however the objects only get moved to x and y values equivalent to the screen coordinates.

We would be glad to recieve some help.
Thank you :slight_smile:

Hello!

You can trace to the position with the help of “ScreenPointToRay” and then use the hit point as the coordinate.

Ah, that sounds good thanks.

But how do I go about doing it? I’ve attached the following script to my camera:

function Update () {

	if(Input.GetMouseButtonDown(0)){
		var ray : Ray = this.ScreenPointToRay(Input.mousePosition);
		Debug.DrawRay (ray.origin, ray.direction * 10, Color.yellow);
	}

}

However I keep getting MissingMethodException: Method not found: ‘Camera.ScreenPointToRay’

I think that in calling this.ScreenPointToRay() you are attempting to call the method/function from the MonoBehaviour class i.e. your script. MonoBehaviour doesn’t have this method available, only the Camera class/object. Monobehavior has the variable camera which points to the camera component on your Gameobject. So try

camera.ScreenPointToRay() instead.

Here’s my code which works. I create a variable called mycamera and then in the Inspector drag and drop the relevant camera onto the script before executing:

// 1. MOVE THE CURSOR IN 3D AS PER THE MOUSE

//Gets the mouse position as Vector3
mpos = Input.mousePosition;  
xcor = mpos.x;
ycor = mpos.y;

//Get the ray from the screen point to the camera and draw it
var ray : Ray = mycamera.ScreenPointToRay (Vector3(xcor,ycor,0));
Debug.DrawRay (ray.origin, ray.direction * 100, Color.yellow);

//Get the hit point of the ray on any object and moves the cursor to that point
var hit : RaycastHit;		
if (Physics.Raycast(ray, hit) ) 
{
	cursor3dpos = hit.point; //copy to variable for external use.
	transform.position = cursor3dpos;
}

Hey johan, thanks for your help!

I got it to kind of work now. However it’s giving me the wrong coordinates, and I can’t really fathom which ones exactly.
Here’s a list from clicks in every direction from the object:

The y-axis seems to be just fine, however the other two just seem to get added up or something :frowning:

My Camera script looks like this now:

function Update () {

	if(Input.GetMouseButtonDown(0)){
		var ray : Ray = camera.ScreenPointToRay(Input.mousePosition);
		Debug.DrawRay (ray.origin, ray.direction * 10, Color.yellow);
		
		var hit : RaycastHit;    
		
		// getCoords of Point
		if(Physics.Raycast(ray, hit))
			DataPass.curser3dPos = hit.point;
	}
}

And my Control script:

function OnMouseDown() {
	
	if(this.name != "Terrain"){
		DataPass.isClicked = true;
		DataPass.clickedGo = this;
	}
	else if(this.name == "Terrain"  Datenweitergabe.clicked){
		DataPass.isClicked = false;
		DataPass.clickedGo.transform.position = Datenweitergabe.curser3dPos;
		Debug.Log(DataPass.curser3dPos);
	}
}