Casting a ray down relative to the orientation of a part

I have a 1x1x1 part from which I want to cast downward a variable amount of studs (call it 20).
Initially, I wrote the following code and thought it was fine.

local rayDown = Ray.new(wheelBase.Position,Vector3.new(0,-maxSuspensionStretch,0))


(Blue is cast node and red is intersection)

The issue is when I threw this node at an angled surface, I found that the ray casts down relative to the world, not the part, which makes sense considering I only passed it a Vector3:


(Terribly sorry for the markup quality, Snip and Sketch is broken)

I looked for solutions concerning conversion from object space to world space, but I can’t seem to get the CFrame related functions working correctly. I’ve already tried variations of trigonometry with the node’s orientation, but its been ~3 hours and me and the poor friends who I dragged into this are sad. I’d appreciate any help u guys can provide.

Latest attempt:

-- maxSuspensionStretch is 20 and wheelBase is the node
local orientedX = maxSuspensionStretch * math.sin(wheelBase.Orientation.Z)
local orientedY = -maxSuspensionStretch * math.cos(wheelBase.Orientation.X)
local orientedZ = maxSuspensionStretch * math.sin(wheelBase.Orientation.X)
-- These individual coords are combined into a Vector3 in the ray definition
2 Likes

Hey there!

You could use UpVector and inverse it.

local rayDown = Ray.new(wheelBase.Position,wheelBase.CFrame.UpVector * -maxSuspensionStretch,0)
2 Likes

The solution that Sougood posted works perfectly! Here’s an alternative way of doing it:

You want the down direction relative to the part, converted to world-space coordinates because that’s what Ray.new() expects.

--"down", as seen from the perspective of the part. 
--It's like pointing at your feet while standing on the ceiling, I guess.
--It's like left and right, bacause it's relative to the observer (the part)
local partSpaceDownDirection = Vector3.new(0, -1, 0)

--The orientation of the part. It's like an observer standing normally on the floor, 
-- seeing the weird orientation you're in. In Roblox terms, it's relative to the "default" CFrame.
local worldSpacePartCFrame = part.CFrame

--The observer on the floor says "no that's not actually *down*. This the direction
-- that you're *actually* pointing".
local worldSpacePartDownDirection = worldSpacePartCFrame:VectorToWorldSpace(partSpaceDownDirection)


--Here's the whole thing more succintly:
local partDownDirection = part.CFrame:VectorToWorldSpace(Vector3.new(0, -1, 0))
3 Likes