How to detect if what the player has clicked is terrain?

I am trying to make a tool that when a player clicks on the ground near them, a crate is spawned. I was wondering if it was possible to detect what the player has clicked is terrain. I’m just not sure how to approach it as I’ve never worked with terrain like this before, any help would be appreciated.

local plr = game:GetService("Players").LocalPlayer
local char = plr.CharacterAdded:Wait()
local h = char:WaitForChild("Humanoid")
local anim = h:LoadAnimation(script.Parent:WaitForChild("Hold"))
local humanoid = char:WaitForChild("Humanoid")
local spawnevent = game.ReplicatedStorage.Tools.PlaceCrate
local objectname = "MedicalCrate"

local tool = script.Parent

tool.Equipped:Connect(function(Mouse)
	anim:Play()
	Mouse.Button1Down:Connect(function()
		if plr:DistanceFromCharacter(Mouse.Hit.p) <= 10 and humanoid.Health > 0 then
			-- If it is terrain, then do the following:
			script.parent.PlaceCrate:Play()
			spawnevent:FireServer(objectname,Mouse.Hit)
			anim:Stop()
			tool:Destroy()
		end
	end)
end)

tool.Unequipped:Connect(function()
	anim:Stop()
end)

1 Like

Mouse.Target
Is it what you are looking for? I also made a script, which provides information about a player hovering with his mouse over terrain, something different than terrain and nothing:

local mouse = game:GetService("Players").LocalPlayer:GetMouse()
while wait() do
	if mouse.Target then
		if mouse.Target.Name == "Terrain" then
			print("Hovering over terrain")
		else
			warn("Hovering over something else")
		end
	else
		warn("Hovering over nothing")
	end
end

Inform me if I misunderstood your problem or for other reason.

They said “Whenever the player clicks on the ground”, use Tool.Activated and then add that function inside the Event without the while loop.

1 Like

I clearly understood you and I know that my script is not made to solve the crates placement problem. I made this script to show how to detect a player’s mouse hovering over world’s terrain, not a direct solution to the problem.

I want it so when it is clicked, not hovered over. But I will try the Mouse.Target property with the click and see if that works.

Mouse.Target == "Terrain"

This doesn’t seem to work for me. Nothing happens.

Try this: Mouse.Target.Name == "Terrain"

Yes, that’s what I just worked out. I had to get the .Name value.

So the solution was:

Mouse.Target.Name == "Target"

Thanks :+1:

Could use this instead, It only listens for when the Mouse is clicked instead of constantly running a loop and putting a slight impact on performance.

Also checks If it is the Actual Terrain Instance rather than the name to reduce the risk of it getting false positive from Terrain Parts.

local Mouse = game:GetService("Players").LocalPlayer:GetMouse()

Mouse.Button1Down:Connect(function()
	local TargetInstance = Mouse.Target

	if TargetInstance ~= nil and TargetInstance:IsA("Terrain") then
		warn("clicked")
	end
end)
1 Like

Yeah, that’s basically how I wrote in my script. I didn’t use the loop as I knew it would affect performance and likely mess up. Thanks.