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
After a while I found a solution
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
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.
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.
How did you make the foot steps?