I want to know which vector (upvector, lookvector, rightvector, -upvector, -lookvector, or -rightvector) is the side of the part that faces most up. I need this for my code of adding snow on top of all parts. Some are rotated a little, so i used upvectors. But some are rotated more than 90 degrees and I can’t use upvector anymore because then it would be upside down (upside down snow doesn’t seem that realistic) please help me here is the code
for i,v in pairs(game.Workspace:GetChildren()) do
if v:IsA("Part") and v.Name ~= "Baseplate" then
local snow = v:Clone()
snow.Parent = v
snow.Size = snow.Size-Vector3.new(0,snow.Size.Y-0.1,0)
snow.Anchored = true
snow.BrickColor = BrickColor.new("White")
snow.Material = "Sand"
local num = (v.Size.Y/2)+0.05
snow.CFrame = snow.CFrame + snow.CFrame.UpVector * num
end
end
Why not just fire raycasts down from the sky and when that ray comes in contact with a part, you can use the NormalId to find out where to position the snow? (Haven’t used Raycasts in awhile so I’m not gonna pseudo-code it rn and look silly :P).
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
That’s just one function I wrote to make the dice work - it’s not the whole thing. You could use that function in your own code; however the article has download a download link to the completed dice model at the bottom.
ok. Is there a way I can implement that into my script here? I need to replace “upVector” with something else (the top side of the part)
for i,v in pairs(game.Workspace:GetChildren()) do
if v:IsA("Part") and v.Name ~= "Baseplate" then
local snow = v:Clone()
snow.Parent = v
snow.Size = snow.Size-Vector3.new(0,snow.Size.Y-0.1,0)
snow.Anchored = true
snow.BrickColor = BrickColor.new("White")
snow.Material = "Sand"
local num = (v.Size.Y/2)+0.05
snow.CFrame = snow.CFrame + snow.CFrame.UpVector * num -- what do i replace this line with?
end
end
Here’s my attempt, using Ozzypig’s getHighestFace method. It works, but I feel slightly uncomfortable with the math that I did to achieve it (namely, the “positive” normal variable thing that I do in order to figure out the size feels icky). I’m pretty awful with math so I’m sure there’s a far better way to do this portion.
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))+(normal*thickness/2)
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
Seems like you modified the code a bit, and I’m not sure what you changed. The code that I sent is only 43 lines long, while your error shows that you’re running some code that’s 49 lines long. I need to see the changes in order to figure out what’s wrong, because the script that I sent you works just fine.
oh no it’s some comments above the code. I found out why. It’s because I have a part, and in that part there is a particle emitter called “Snow”. It broke your code. Can you make it so the name won’t be affected? Change this line of code: