Surface position

I want to get the CFrame at the center of the top of the cube.

I’ve tried raycasting but then I realized that means I would need the position of the center to raycast to which is what I’m trying to find.

How would I achieve this?

I’m not smart but this might work. There’s probably a more straightforward way but this might work.

local part = workspace.Part
local point do
	local matrix = {part.CFrame:components()}
	local x,y,z = math.abs(matrix[5]), math.abs(matrix[8]), math.abs(matrix[11])
	if x > y and x > z then
	    if matrix[5]>0 then
	    	point = (part.CFrame*CFrame.new(Part.Size.X/2, 0, 0)).p
	    else
	    	point = (part.CFrame*CFrame.new(Part.Size.X/-2, 0, 0)).p
	    end
	elseif y > x and y > z then
		if matrix[8]>0 then
	    	point = (part.CFrame*CFrame.new(0, Part.Size.Y/2, 0)).p
	    else
	    	point = (part.CFrame*CFrame.new(0, Part.Size.Y/-2, 0)).p
	    end
	else
		if matrix[11]>0 then
			point = (part.CFrame*CFrame.new(0, 0, Part.Size.Z/2)).p
		else
			point = (part.CFrame*CFrame.new(0, 0, Part.Size.Z/-2)).p
		end
	end
end
print(point)
1 Like

This doesn’t seem to work, but could you explain the code and idea behind this?

local part = workspace.Part
local cframe = part.CFrame * CFrame.new(0, part.Size.Y/2, 0)

or

local part = workspace.Part
local cframe = ( part.CFrame * CFrame.new(0, part.Size.Y/2, 0) ).Position

for the position

I fixed it, I was using rows instead of columns. CFrames consist of XYZ positions and a rotation matrix. The matrix consists of an X Y and Z vector. Basically, the vectors describe where each side of the part is facing. It looks like this
image
In this case, the right face of the part is pointing up (Y=1, X/Z = 0), the top of the part is pointing +X, and the back of the part is pointing to -Z. If the part was angled, these would all be ugly decimals like .7073. What I am doing is finding out which side of the part has a higher Y value, meaning that side of the part is pointing the most upwards. Then I just do what maumaumaumaumaumua did.

Here is the fixed and tested code.

local part = workspace.Part
local point do
	local matrix = {part.CFrame:components()}
	local x,y,z = math.abs(matrix[7]), math.abs(matrix[8]), math.abs(matrix[9])
	if x > y and x > z then
	    if matrix[7]>0 then
	    	point = (part.CFrame*CFrame.new(part.Size.X/2, 0, 0)).p
	    else
	    	point = (part.CFrame*CFrame.new(part.Size.X/-2, 0, 0)).p
	    end
	elseif y > x and y > z then
		if matrix[8]>0 then
	    	point = (part.CFrame*CFrame.new(0, part.Size.Y/2, 0)).p
	    else
	    	point = (part.CFrame*CFrame.new(0, part.Size.Y/-2, 0)).p
	    end
	else
		if matrix[9]>0 then
			point = (part.CFrame*CFrame.new(0, 0, part.Size.Z/2)).p
		else
			point = (part.CFrame*CFrame.new(0, 0, part.Size.Z/-2)).p
		end
	end
end

Here’s one idea that I’ve been working on. You should implement it into a module.

function module:GetSurfacePosition(part: Instance, surface: string)
    
    local s = string.lower(surface)
    
    local top = part.CFrame * CFrame.new(0, (part.Size.Y / 2), 0)
    local bottom = part.CFrame * CFrame.new(0, -(part.Size.Y / 2), 0)
    
    local right = part.CFrame * CFrame.new((part.Size.X / 2), 0, 0)
    local left = part.CFrame * CFrame.new(-(part.Size.X / 2), 0, 0)
    
    local back = part.CFrame * CFrame.new(0, 0, (part.Size.Z / 2))
    local front = part.CFrame * CFrame.new(0, 0, -(part.Size.Z / 2))
    
    local position = nil
    
    if s == "top" then
        
        position = top.Position.Y
        
    elseif s == "bottom" then
        
        position = bottom.Position.Y
        
    elseif s == "right" then

        position = right.Position.X
        
    elseif s == "left" then

        position = left.Position.X
        
    elseif s == "front" then

        position = front.Position.Z
        
    elseif s == "back" then

        position = back.Position.Z

    end
    
    return position
    
end
local top = part.CFrame * CFrame.new(0, part.Size.Y/2, 0)