How to instantiate a prefab to mouse location

i need help, i’m a little new to unity,
i need a script that will get a prefab to follow the mouse anywhere on the terrain.
when the mouse button is pressed anywhere on that terrain then the object will be placed there.
i made an attempt that really failed and instead the prefab will place everytime the mouse is moved.
and will also let the prefab be placed under the terrain to. any help would be awesome it’s worth noting the game is 3d perspective if anyone could be so kind to help correct the code, and explain it i would be so thankfull, any advice would also be nice :slight_smile:

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

public class Test : MonoBehaviour {
	public Camera cam;
	public GameObject ItemNameBought;
	public GameObject fakeitem; //usally left empty 
	// Use this for initialization
	void Start(){
		
	}
	
	// Update is called once per frame
	void Update () {
		RaycastHit hit;
		Ray ray = cam.ScreenPointToRay(Input.mousePosition);

		if (Physics.Raycast(ray, out hit)) {
			Transform objectHit = hit.transform;
			if (objectHit.name == "Plane") {
				// Do something with the object that was hit by the raycast.
				Debug.Log (objectHit.name);
				fakeitem = Instantiate (ItemNameBought, ray.GetPoint (10), Quaternion.identity) as GameObject;
			}
		}
	}
}

The problem is each time the raycast hit something you instantiate the object at the ray’s position.

To solve that you need the make a preview GameObject which we will use to know where we place the object (the preview one) and then you instantiate the final object at the position you want only when you click or whatever you want.

I’ve made some changes to your code and done very basic stuff and can really be improved, but i hope you got the idea.

EDIT : made the code more cleaner added a few lines

Here’s the code :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour {
public Camera cam;
public GameObject objToPlace;
private GameObject previewObj;

	void Update () {
		RaycastHit hit;
		Ray ray = cam.ScreenPointToRay(Input.mousePosition);
	
		if (Physics.Raycast(ray, out hit)) {
			Transform objectHit = hit.transform;
			//instanciate the preview of the object if it's not already
			if(previewObj == null){
				previewObj = Instantiate(objToPlace, ray.GetPoint(10), Quaternion.identity) as GameObject;
				
				//we disable the collider of the preview object to not interfer with the raycast 
				Collider collider = previewObj.GetComponent<Collider>();
				if(collider){
					previewObj.GetComponent<Collider>().enabled = false;
				}
			}

			//moving the object while not clicked
			previewObj.transform.position = hit.point;
		
			//place the object when left click is pressed
			if(Input.GetMouseButtonDown(0) && previewObj != null){
				Instantiate (objToPlace, previewObj.transform.position, Quaternion.identity);
				Debug.Log ("Placed " + objToPlace.name + " on " + objectHit.name);
			}
		}
	}
}