Generated Trees are on top of other trees

local Random_X = Zone_CFrame.X + math.random(-Zone_Size.X/2, Zone_Size.X/2)
		local Random_Z = Zone_CFrame.Z + math.random(-Zone_Size.Z/2, Zone_Size.Z/2)

		local Origin = Vector3.new(Random_X, 319, Random_Z)
		local Direction = Vector3.new(0,-1,0) * 100
		
		local Params = RaycastParams.new() do
			
			Params.RespectCanCollide = true
			Params.FilterDescendantsInstances = {Zone}
			Params.FilterType = Enum.RaycastFilterType.Exclude
			
		end
		
		local Result = workspace:Raycast(Origin, Direction, Params)
		
		if Result then
			
			local Result_Instance : Instance = Result.Instance
			local Terrain_Index = Result_Instance:IsA("Terrain")
			
			if Terrain_Index then
				
				if Result.Material == Enum.Material.Water then
					return
				end
				
				if Result.Material == Enum.Material.Rock then
					return
				end
				
				local Model = Model:Clone() do
				
					Model.Parent = workspace.Foilage

				end
				
				local New_CFrame = CFrame.new(Random_X, Result.Position.Y -25, Random_Z)

				Model:MoveTo(New_CFrame.Position)

			end
			
			
		end

Here is the documentation for MoveTo which should help your issue:

" If there are any obstructions where the model is to be moved, such as Terrain or other BaseParts, the model will be moved vertically upward until there is nothing in the way. If this behavior is not desired, PVInstance:PivotTo() should be used instead."

You need to check if the instance that was hit by the raycast is a tree. I recommend doing this using the IsDescendantOf() function. To achieve this, you can create the tree inside a folder, and the script will understand that every descendant hitted by the raycast that is inside that folder should be considered a reason not to create a tree there, add one more conditional statement and create a new folder Like This:

local TreeFolder = Instance.new(“Folder”)
TreeFolder.Parent = Workspace

local Random_X = Zone_CFrame.X + math.random(-Zone_Size.X/2, Zone_Size.X/2)
local Random_Z = Zone_CFrame.Z + math.random(-Zone_Size.Z/2, Zone_Size.Z/2)



local Origin = Vector3.new(Random_X, 319, Random_Z)
	local Direction = Vector3.new(0,-1,0) * 100
	
	local Params = RaycastParams.new() do
		
		Params.RespectCanCollide = true
		Params.FilterDescendantsInstances = {Zone}
		Params.FilterType = Enum.RaycastFilterType.Exclude
		
	end
	
	local Result = workspace:Raycast(Origin, Direction, Params)
	
	if Result then
		
		local Result_Instance : Instance = Result.Instance
		local Terrain_Index = Result_Instance:IsA("Terrain")
		
		if Terrain_Index then
			
			if Result.Material == Enum.Material.Water then
				return
			end
			
			if Result.Material == Enum.Material.Rock then
				return
			end
			
             if Result.Instance:IsDescendantOf(TreeFolder) then
                      return
                end

			local Model = Model:Clone() do
			
				Model.Parent = workspace.TreeFolder

			end
			
			local New_CFrame = CFrame.new(Random_X, Result.Position.Y -25, Random_Z)

			Model:MoveTo(New_CFrame.Position)

		end
		
		
	end
    if Result:IsDescendantOf(TreeFolder) then
         return
   end

This is a RaycastResult, wouldn’t it be the raycast instance?

oh yeah mb it is

 if Result.Instance:IsDescendantOf(TreeFolder) then
         return
   end

image
image

It seems to just hit a plateau and continue making trees on top of each other

are you sure it is creating trees in top of trees and not on top of another thing?, you could maybe do a print for every single Result.Instance to check if it is hitting the terrain or even another part that isnt the tree