The thing I am doing is generating trees by creating a raycast into the sky, so that way nothing obstructs the tree for a realystic generation, but the raycast ignores blocks and makes the trees clip into mountains and hills.
local BLOCK_SIZE = 3.054
local MAP_SIZE = Vector3.new(100, 64, 100)
local MOUNTAIN_INTENSITY = 8
seed = workspace.SEED.Value
noisescale = 1/64
amplitude = 10
function get_density(v3)
local noise_value = math.noise(v3.X * noisescale, v3.Y * noisescale, v3.Z * noisescale + seed)*amplitude
local height_bonus = -v3.Y / MOUNTAIN_INTENSITY + 8
return noise_value + height_bonus
end
function is_on_boundary(v3)
if get_density(v3) <= 0 then
return false
end
for _, dirEnum in pairs(Enum.NormalId:GetEnumItems()) do
local dir = Vector3.FromNormalId(dirEnum)
local neighbor_pos = v3 + dir * BLOCK_SIZE
local neighbor_density = get_density(neighbor_pos)
if neighbor_density <= 0 then
return true
end
end
return false
end
for x = 0, MAP_SIZE.X do
for y = 0, MAP_SIZE.Y do
for z = 0, MAP_SIZE.Z do
local block_pos = Vector3.new(x, y, z) * BLOCK_SIZE
local density = get_density(block_pos)
if density > 0 and is_on_boundary(block_pos) then
local block = script.Block:Clone()
block.Parent = game.Workspace
block.CFrame = CFrame.new(block_pos)
if y > 25 then
local c = game.ReplicatedStorage.Blocks.Nature.Snow:Clone()
c:SetPrimaryPartCFrame(block.CFrame)
c.Parent = workspace.TerrainFolder
block:Destroy()
elseif y < 23 and y > 10 then
local c = game.ReplicatedStorage.Blocks.Nature.Grass:Clone()
c:SetPrimaryPartCFrame(block.CFrame)
c.Parent = workspace.TerrainFolder
block:Destroy()
local startPos = c.Grass.Position
local finishPos = Vector3.new(c.Dirt.Position.X, c.Dirt.Position.Y + 10000, c.Dirt.Position.Z)
local rayDirection = finishPos - startPos
local trees = game.ReplicatedStorage.Structures.Trees:GetChildren()
local ray = Ray.new(startPos, rayDirection)
local hit = workspace:Raycast(startPos, finishPos)
if math.random(1, 150) == 1 and hit == nil then
local tree = trees[math.random(1, #trees)]:Clone()
tree.Parent = workspace.TerrainFolder.Trees
tree:SetPrimaryPartCFrame(c.PrimaryPart.CFrame)
end
if hit == nil then
print("Nothing obstructed the tree!")
else
print(hit.Position)
end
elseif y <= 10 then
local p = Instance.new("Part")
p.Parent = workspace.TerrainFolder
p.Size = Vector3.new(3.054, 0.005, 3.054)
p.Anchored = true
p.CanCollide = false
p.Transparency = 0.01
p.Reflectance = 0.1
p.CFrame = CFrame.new(block.CFrame.X, 30, block.CFrame.Z)
p.Material = Enum.Material.SmoothPlastic
p.Name = "Water"
p.BrickColor = BrickColor.new("Electric blue")
local c = game.ReplicatedStorage.Blocks.Nature.Sand:Clone()
c:SetPrimaryPartCFrame(block.CFrame)
c.Parent = workspace.TerrainFolder
block:Destroy()
else
local c = game.ReplicatedStorage.Blocks.Nature.Stone:Clone()
c:SetPrimaryPartCFrame(block.CFrame)
c.Parent = workspace.TerrainFolder
block:Destroy()
end
end
end
end
wait(0.2)
end
Anything I could do? Something to fix?