-
What do you want to achieve? Keep it simple and clear!
I’m doing some tests with ray casting and trying to calculate proper angles for rotating and positioning parts dynamically. -
What is the issue? Include screenshots / videos if possible!
The surface normal is not being returned as a perpendicular vector from the part/terrain surface. -
What solutions have you tried so far?
I have been tracing out the cast ray (Grey) the up direction vector of the black part (Blue) and the surfaceNormal vector (Green)
My understanding is that the surface normal (green line) should be pointed directly upward (like the blue line). What is happening here?
Script:
--Create a CFrame to pull the direction vector from
local directionFrame = myPart.CFrame * CFrame.Angles(math.rad(20), math.rad(180), 0)
--Cast a ray from the position of myPart going in direction of the front face of the direction cframe
--(This is backface of myPart down toward the terrain at a 20deg angle)
local ray = Ray.new(myPart.Position, directionFrame.LookVector * 50)
local hitPart, hitPos, surfaceNormal = game.Workspace:FindPartOnRayWithWhitelist(ray, {game.Workspace.Terrain, game.Workspace.FakeTerrain}, false)
--Calculate Rotation angle
local normal = part.CFrame.RightVector --(Surface facing upward...)
local rotAngle = math.acos(normal:Dot(surfaceNormal) / (normal.Magnitude*normal.Magnitude))
print("Rotation Z: "..rotAngle)
--Trace the Ray and vectors
local rayDistance = (myPart.Position - hitPos).Magnitude
local rayTracer = Instance.new("Part")
rayTracer.Name = "Tracer"
rayTracer.Size = Vector3.new(0.2, 0.2, rayDistance)
rayTracer.Anchored = true
rayTracer.CanCollide = false
rayTracer.CFrame = CFrame.new(myPart.Position, hitPos) * CFrame.new(0,0,(-rayDistance/2))
rayTracer.Parent = game.Workspace
local normalTracer = rayTracer:Clone()
normalTracer.Name = "NormTracer"
normalTracer.BrickColor = BrickColor.Blue()
normalTracer.CFrame = CFrame.new(part.Position, normal*10) * CFrame.new(0,0,(-rayDistance/2))
normalTracer.Parent = game.Workspace
local surfTracer = rayTracer:Clone()
surfTracer.Name = "SurfaceTracer"
surfTracer.BrickColor = BrickColor.Green()
surfTracer.CFrame = CFrame.new(hitPos, surfaceNormal*10) * CFrame.new(0,0,(-rayDistance/2))
surfTracer.Parent = game.Workspace