-- // Satisfying part tweening by yite_mc \\
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
--local remotes = ReplicatedStorage:WaitForChild("Remotes")
--local modifyRemote = remotes:WaitForChild("Modify")
local fieldSize = 35
local radius = 16
local partHeight = 5
local lerpSpeed = 0.5
local defaultNoiseScale = 0.1
local defaultHeightMultiplier = 20
local defaultSeed = 50
local originalHeights = {}
-- Generates a hill like field using parts with a noise-based heightmap. Adjusting the noiseScale and heightMultiplier can create different terrains
local function generateField(noiseScale, heightMultiplier, seed)
for i, v in pairs(workspace.Field:GetChildren()) do
v:Destroy()
end
for x = -fieldSize, fieldSize do
for z = -fieldSize, fieldSize do
local part = Instance.new("Part")
part.Size = Vector3.new(1, partHeight, 1)
local noiseValue = math.clamp(math.noise(x * (noiseScale or defaultNoiseScale), z * (noiseScale or defaultNoiseScale), seed or defaultSeed), 0, math.huge)
local hillHeight = noiseValue * (heightMultiplier or defaultHeightMultiplier)
part.Position = Vector3.new(x, hillHeight, z)
part.Anchored = true
part.Color = Color3.new(0, 0, 0)
part.Parent = workspace.Field
originalHeights[part] = hillHeight
end
task.wait(0.00001)
end
end
-- Smoothly animate the parts based on the player's distance from them
game.Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(character)
local hrp: BasePart = character:WaitForChild("HumanoidRootPart")
RunService.Heartbeat:Connect(function()
for _, v in pairs(workspace.Field:GetChildren()) do
if v:IsA("BasePart") then
local distance = (v.Position - hrp.Position).Magnitude
local progress = 0
if distance <= radius then
-- If the player is within the radius, smoothly interpolate between the base height and the target height, looks better with HSV (imo)
progress = 1 - (distance / radius)
local hue = (distance / radius) % 1
local color = Color3.fromHSV(hue, hue, hue)
v.Color = color
else
v.Color = Color3.new(0, 0, 0)
end
local baseY = originalHeights[v]
local targetY = baseY - (progress * partHeight)
local currentPos = v.Position
local targetPos = Vector3.new(currentPos.X, targetY, currentPos.Z)
v.Position = currentPos:Lerp(targetPos, lerpSpeed)
end
end
end)
end)
end)
generateField()
-- Optional remote event to modify the field
--[[modifyRemote.OnServerEvent:Connect(function(player, inputs)
generateField(inputs.Scale, inputs.HeightMultiplier, inputs.Seed)
end)]]