Orienting a Part to Mouse TargetSurface

Hi, I have searched through many other similar topics with no avail.

What I am trying to achieve is to get the direction of surface (right, top, front, etc.) with something like Mouse.TargetSurface. To place an object parallel to something like a wall.

Simply, I am making a placement system that attaches a part smoothly to a wall.

Is this possible, or is brute forcing needed?

1 Like

If you know for a fact that the walls are going to be square and flat, I would use the dot product of the normal at the mouse ray hit.

1 Like

Can you explain how to get a dot product?

I would go about it by determining the direction with the greatest dot product with the normal. If you want to get the normal * direction, you can just do:

local dot = Normal:Dot(Direction)
1 Like

I have the dot product. But how would I convert that to a parts orientation?

local raycastResult = game.Workspace:Raycast(Mouse.UnitRay.Origin, Mouse.UnitRay.Direction * 50)
		
		if raycastResult then
			
			local Normal = raycastResult.Normal
			
			print(Normal:Dot(Mouse.UnitRay.Direction))
			
			
		else	
			print("false")
		end

The Direction should be positive and negative basis vectors (like +x, -x, +y, -y, +z, -z)

1 Like

Could you tell me how to get basis vectors and how to orient a part from the dot product

I think I misunderstood your problem…

Do you want to position it so it’s on the wall or snap to the direction the surface is closest to?

Snap to the direction the surface is closest to.

It would actually probably less expensive and less complex to just get the greatest (with absolute value) component of the normal vector and use that as the direction.

local normalDict = {
   ["X"] = normal.Unit * Vector3.new(1, 0, 0);
   ["Y"] = normal.Unit * Vector3.new(0, 1, 0);
   ["Z"] = normal.Unit * Vector3.new(0, 0, 1);
}

for axis, value in pairs(normalDict) do
   local sign = math.sign(value[axis])
   if value[axis] * sign > math.sqrt(3)/3 then
      local primaryAxis = value.Unit
   end
end

You can use CFrame.lookAlong() to get the cframe angles to position a part.

local angles = CFrame.lookAlong(Vector3.new(), primaryAxis)

Simpler solution with no math

if Mouse.TargetSurface == Enum.NormalId.Front then
			
			Real.Orientation = Mouse.Target.Orientation + Vector3.new(-90, 0, 0)
			
		elseif Mouse.TargetSurface == Enum.NormalId.Back then
			
			Real.Orientation = Mouse.Target.Orientation + Vector3.new(-90, 180, 0)
			
		elseif Mouse.TargetSurface == Enum.NormalId.Right then
			
			Real.Orientation = Mouse.Target.Orientation + Vector3.new(-90, -90, 0)
			
		elseif Mouse.TargetSurface == Enum.NormalId.Left then
			
			Real.Orientation = Mouse.Target.Orientation + Vector3.new(-90, 90, 0)
			
		elseif Mouse.TargetSurface == Enum.NormalId.Top then

			Real.Orientation = Mouse.Target.Orientation + Vector3.new(0, 90, 0)
			
		elseif Mouse.TargetSurface == Enum.NormalId.Bottom then

			Real.Orientation = Mouse.Target.Orientation + Vector3.new(-90, 90, 0)
			
		end

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.