How to use script to cover everything in snow

Why don’t you just move the snow Part’s Position up .2 studs in the workspace?
All of your Parts would be raised that way and you wouldn’t have to worry about CFraming different Vectors.

because then this would happen
image

After a while I found a solution :slight_smile:

local function getHighestFace(part)
	local highestFace
	local height = -math.huge

	for k, normalId in pairs(Enum.NormalId:GetEnumItems()) do
		local y = part.CFrame:pointToWorldSpace(Vector3.FromNormalId(normalId)).y
		if y > height then
			highestFace = normalId
			height = y
		end
	end

	return highestFace
end

local function addSnow(part, thickness)
	local normal = Vector3.FromNormalId(getHighestFace(part))
	local offset = normal * part.Size * 0.5

	local positive = if normal.X<0 or normal.Y<0 or normal.Z<0 then normal*-1 else normal

	local existing = part:FindFirstChild("SnowPart");
	local snow = existing or Instance.new("Part")

	if not existing then
		snow.Name = "SnowPart"
		snow.Anchored = true;
		snow.BrickColor = BrickColor.new("White")
		snow.Material = Enum.Material.Sand
	end

	snow.Size = (positive*thickness)+(part.Size*-positive+part.Size)
	snow.CFrame = part.CFrame:ToWorldSpace(CFrame.new(offset))+Vector3.new(0, thickness/2, 0)

	snow.Parent = part
	return snow
end

for _,v in ipairs(workspace:GetChildren()) do
	if v:IsA("Part") and v.Name~="Baseplate" then
		addSnow(v, 0.25)
	end
end
1 Like

Actually the way I was referring to would be just to copy the Parts that are like roofs or trees, then copy them and raise them up.
I realized that this would cause issues with z-fighting at the end of the Parts, but here’s a diagram of what I meant.


The red Snow Parts are just copies that are moved straight up on the y axis which allows for items built like the Roof I outlined in black.

ohh ok. Is there anything i will have to do to the code like change some parts?

Copy the top layer of Parts in the entire map.
Put them in a model (for this example we’ll call the Model ‘snow’).
Make them white and whatever Material you choose for your snow.
Make them Transparent and CanCollide false.
Have the model in the workspace just slightly above the surfaces of the Parts they are copied from, say .01 studs.

When you want it to start snowing you can gradually lower the Transparency from 1 to 0 to create a dusting of snow that turns solid, then raise the entire ‘snow’ model you could create a kind of accumulation of the snow surfaces. It would look squared off and would have z-fighting because of the overlap of the edges of the Parts, but you could just decrease the length of the snow Parts so they are just inside of the outer edges it may fix that.

thanks! But, i was also thinking how do i calculate if there is a part on top of another part? Because right now the snow spawns on every part no matter if there is a part on top of it or now

That’s why making a script do the work is going to be pretty difficult, especially if you look at my quick drawing. A script designed to get the ‘top’ Part would only pick the black Part on the RH side since it’s above the Part on the LH side.

It may just mean you will have to create a ‘snow’ Model in your game and go through all the Parts you want snow to fall on and use Ctrl D to copy those then put them into the snow model.

but isn’t there some math that can do it? like use raycasting or sth?

The only thing I can think of is that you’d have to scan the entire map from straight above, using a raycast (or raycasts) from a moving point (like scanning paper for photocopying) and getting all those top Parts, copying them into their original Position, Size and Orientation, shrinking them by about .005 studs in the correct direction(s) to correct for z-fighting, and parenting them to the workspace.
Just sayin’, I would have gone the short route and just done all that manually 3 days ago.

1 Like

Hey! I tried my hand at this for a prototype I’m working on, including detecting if there is a “cover” by Raycasting upward. I don’t know of its efficiency, but I put this as a LocalScript for the Player.

--[[
"SnowOnSurfaceClient" for A Fire Made of Snowflakes
14 July 2023, 10:18 PM by G.R (CptRedder)

Reference: https://devforum.roblox.com/t/how-to-use-script-to-cover-everything-in-snow/1576234
--]]

--//----------------------------------------------------------------------------------------------------[Variables]
local SnowPartsFolder = workspace:WaitForChild("SnowParts") --//A folder in Workspace

--//----------------------------------------------------------------------------------------------------[Functions]
function RaycastUp(thePart)
	local length = 100
	local raycastParams = RaycastParams.new()
	raycastParams.FilterType = Enum.RaycastFilterType.Exclude
	raycastParams.FilterDescendantsInstances = {thePart}
	local raycastResult = game.Workspace:Raycast(thePart.CFrame.Position, Vector3.new(0, 1, 0) * length, raycastParams)

	local finalHit

	if raycastResult then
		finalHit = raycastResult.Position
		return raycastResult
	else
		finalHit = thePart.CFrame.Position + (Vector3.new(0, 1, 0) * length)
		return nil
	end
end

--//----------------------------------------------------------------------------------------------------[Main]
--//Main Loop
for i,v in ipairs(workspace:GetDescendants()) do
	if v:IsA("BasePart") and not v:IsA("Terrain") then
		if v.Transparency <= 0 and v:FindFirstAncestorWhichIsA("Humanoid") == nil and v.Anchored == true and v.Name ~= "SnowPart" then
			--//Check if Neon
			if v.Material ~= Enum.Material.Neon then
				--//Determine if under a cover
				if RaycastUp(v) == nil or v.Name == "Baseplate" then
					--//Create snow
					local snow = v:Clone()
					snow.Name = "SnowPart"
					snow.Parent = SnowPartsFolder
					snow.Size = snow.Size / 1.1
					snow.Anchored = true
					if snow:IsA("PartOperation") then --//For Unions
						snow.UsePartColor = true
					end
					snow.BrickColor = BrickColor.new("Institutional white")
					snow.Material = Enum.Material.Snow
					snow.CFrame = snow.CFrame + Vector3.new(0, 0.2, 0)
					snow.CanCollide = false
				end
			end
		end
	end
end

Nice, but the only thing would be that you need to create separate parts for floors indoors and outdoors. Because if you have a floor that is covered in the center but not on other areas, it wouldn’t generate the snow even on the outside since the code thinks that the entire part is covered.

1 Like

How did you make the foot steps?