Part weirdly offset when using look vector

Goal: I am trying to make a system where the part is at the position of the mouse cursor when within a certain range but when it is out of range it locks it at the max distance.

Problem: When the part is object is out of range it works fine, but when in range it is offset in weird positions but it is somewhat correct. idk why it doesn’t work

To replicate: This is used in a local script, first person!

repeat wait() until game.Players.LocalPlayer.Character
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()

local target = game.Workspace.WorldCursor -- A part that is both Anchored == True and CanCollide == False
mouse.TargetFilter = target

mouse.Move:Connect(function()
	
	local origin = player.Character.PrimaryPart.Position
	target.Position = origin
	
	local cx, cy, cz = math.abs(mouse.Hit.p.X - origin.X), math.abs(mouse.Hit.p.Y - origin.Y), math.abs(mouse.Hit.p.Z - origin.Z)
	target.CFrame = CFrame.new(target.Position, mouse.Hit.p)
	
	local maxDistance = 20
	if cx > maxDistance then cx = maxDistance end
	if cy > maxDistance then cy = maxDistance end
	if cz > maxDistance then cz = maxDistance end
	
	target.CFrame = target.CFrame + Vector3.new(target.CFrame.LookVector.X * cx, target.CFrame.LookVector.Y * cy, target.CFrame.LookVector.Z * cz) 
end)

You generally can’t manipulate a vector’s individual components like this.

Instead treat a vector as a “direction” and a “distance”—it’s individual components don’t really matter for most purposes.

local vector = mouse.Hit.Position - origin
local direction = vector.Unit
local distance = vector.Magnitude

Then you can clamp the distance and move along the direction by that amount:

if distance > maxDistance then distance = maxDistance end
target.Position = origin + direction * distance

Alternatively if you want to keep the lookAt thing (and ignore direction because it’s built-in to the CFrame * operator):

if distance > maxDistance then distance = maxDistance end
target.CFrame = CFrame.lookAt(origin, mouse.Hit.Position) * CFrame.new(0, 0, -distance)

I recommend watching this video to learn more about how to think about and visualize vectors:

4 Likes