So I am making a game that generates a random terrain map using perlin noise and I am now trying to add chests generating but I run into the problem of, when the chests are on a hill, they stick out rather than being flat on the floor.
Example of the issue:
If the image is hard to understand, basically the ground is a declining hill but the chest has generated to be sticking out rather than being parallel with it. I was wondering if I could use raycasting or something to make it parallel with the ground. Any suggestions would be nice!
Here is the script that generates the world (The tree and chest in ServerStorage are just parts):
local size = Vector3.new(8,8,8)
local seed = math.random(1, 10e6)
local frequency = 3
local power = 32
local resolution = 200
local Parts = {}
for x = 1, resolution do
for z = 1, resolution do
local y1 = math.noise(
(x*frequency)/resolution,
(z*frequency)/resolution,
seed
)
local y2 = math.noise(
(x*frequency*.125)/resolution,
(z*frequency*.125)/resolution,
seed
)
local y3 = math.noise(
(x*frequency*4)/resolution,
(z*frequency*4)/resolution,
seed
)
local y = (y1*y2*power*power)+y3
if y > -3 then
game.Workspace.Terrain:FillBall(Vector3.new(x * size.X, y, z * size.Z), size.X, Enum.Material.Grass)
else
game.Workspace.Terrain:FillBall(Vector3.new(x * size.X, y, z * size.Z), size.X, Enum.Material.Sand)
end
local SpawnChance = math.random(1, 100)
if SpawnChance > 99 then
local SpawnLocation = game.ServerStorage.SpawnLocation:Clone()
SpawnLocation.Position = Vector3.new(x * size.X, y + size.Y/2, z * size.Z)
SpawnLocation.Parent = game.Workspace
end
local chestConstant = 7500
local chestThreshold = .1
local ChestChance = math.noise(x * frequency * chestConstant / resolution, z * frequency * chestConstant / resolution, seed)
if ChestChance > chestThreshold then
local ChestNum = math.random(1,300)
local ChestSpawnChance = 295
if ChestNum > ChestSpawnChance then
local Chest = game.ServerStorage.Chest:Clone()
local ChestHeight = Chest.Size.Y
local PartHeight = size.Y
local ChestY = y + ((ChestHeight / 2) * PartHeight)
if ChestY - (ChestY/2) <= 0 then
Chest:Destroy()
else
Chest.Position = Vector3.new((x * size.X) + math.random(-size.X/2, size.X/2), ChestY, (z * size.Z) + math.random(-size.Z/2, size.Z/2))
Chest.Orientation = Vector3.new(0,math.random(0,360),0)
Chest.Parent = workspace
end
end
end
local c = 5 -- c is some constant you use to customise how the noise feels
local threshold = 0.1 -- the TreeChance needs to be greater than this to spawn a tree
local TreeChance = math.noise(x * frequency * c / resolution, z * frequency * c / resolution, seed)
if TreeChance > threshold then
local TreeNum = math.random(1,100)
local TreeSpawnChance = 95
if TreeNum > TreeSpawnChance then
local Tree = game.ServerStorage.Tree:Clone()
local TreeHeight = Tree.Size.Y
local PartHeight = size.Y
local TreeY = y + PartHeight / 2 + TreeHeight / 2
if TreeY - (TreeY/2) <= 0 then
Tree:Destroy()
else
-- I changed it to Tree.Position instead of Tree.CFrame because the tree is a cylinder, so would spawn flat if I updated the CFrame instead of the position.
Tree.Position = Vector3.new((x * size.X) + math.random(-size.X/2, size.X/2), TreeY, (z * size.Z) + math.random(-size.Z/2, size.Z/2))
Tree.Orientation = Vector3.new(0,math.random(0,360),0)
Tree.Parent = workspace
end
end
end
end
end
print("World has finished generating")