# Is there a way to get the surface inclination angle of a part surface?

Is there a way to get the surface inclination of a sphere?
Like doing a raycast that hits a sphere and get the inclination angle of the hit point surface?

1 Like

Yes, it is possible to get the surface inclination of a sphere by doing a raycast and using the `SurfaceNormal` property of the `RaycastHit` object that is returned.

Here is an example of how you can do this in Roblox Lua:

``````local origin = Vector3.new(0, 0, 0) -- the starting point of the raycast
local direction = Vector3.new(0, 0, -1) -- the direction of the raycast
local range = 10 -- the maximum distance of the raycast
local sphere = game.Workspace.Sphere -- the sphere object to cast the ray on

-- Perform the raycast and get the hit object
local hit, position, normal = game.Workspace:Raycast(origin, direction, range)

-- If the raycast hits the sphere
if hit == sphere then
-- Calculate the inclination angle
local inclination = math.deg(math.acos(normal.Z))
print(inclination) -- print the inclination angle
end
``````

This code will perform a raycast from the origin point `(0, 0, 0)` in the direction `(0, 0, -1)` (straight down) with a maximum distance of `10` units. If the raycast hits the sphere object, it will calculate the inclination angle of the surface at the hit point and print it.

The inclination angle is calculated by using the `acos` function to get the angle between the surface normal and the `Z` axis (which is pointing upwards), and then converting it to degrees using the `deg` function. The `normal` vector is a unit vector that points in the direction of the surface normal at the hit point, so it has a length of `1` . The `Z` component of the `normal` vector is the projection of the normal vector onto the `Z` axis, and it ranges from `-1` (downwards) to `1` (upwards). The `acos` function returns the angle in radians between `0` and `Ď€` (180 degrees), so we need to use the `deg` function to convert it to degrees.

Keep in mind that this code is just an example and you will need to adjust it to fit your specific needs. You will need to specify the origin, direction, range, and sphere object appropriately in your own code

3 Likes

Thank you so much. It totally makes sense, thank you. But for some reason, Im getting `normal = nil` using this script, do you know what could be the reason?

``````local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {script.Parent}
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist

local rayOrigin = script.Parent.Position
local rayDestination = game.Workspace.Sphere.Attachment.WorldPosition

local rayDirection = rayDestination - rayOrigin

while true do
local hit, position, normal = game.Workspace:Raycast(rayOrigin, rayDirection, raycastParams)

if hit then
warn(hit.Instance) -- This is showing the sphere instance in output
warn(normal) -- This is nil
if normal then
local inclination = math.deg(math.acos(normal.Z))
print(inclination) -- print the inclination angle
end

end
wait()
end
``````

There are a few things you can try to fix the issue:

1. Make sure that the `hit` variable is not `nil` . If `hit` is `nil` , then the raycast did not hit anything, and `normal` will also be `nil` .
2. Make sure that the object that the raycast hit has a surface with a normal vector. Some objects, such as parts with the â€śSmoothâ€ť material, do not have a surface normal vector.
3. Make sure that the `normal` variable is being set correctly in the `Raycast` function. The `Raycast` function should return three values: a boolean value indicating whether the raycast hit something, a Vector3 value representing the position where the raycast hit, and a Vector3 value representing the normal vector at the point where the raycast hit. If the `normal` variable is not being set correctly, it could be because of an issue with the `Raycast` function itself.

Thats the reason then. Im using a simple part with ball shape. Then that part has not normals? Should be a sphere mesh?

If you are using a simple part with a sphere shape, and you want to use a raycast to get the normal vector at the point where it hits the object, you may need to use a different object or material. Alternatively, you could try adding a surface normal vector to the object manually, either by modeling the object with surface normals or by applying a normal map to the object.

I tried with a couple of sphere meshes from tool box, still not getting normals, I changed the part material of the simple ball part, still not getting normal result.
I know nothing about normal maps, I guess I should do a research

1 Like