Getting part to follow mouse when tweening?

I have this part that I want to tween. However, when it is tweening, it can’t move. For reference, the part moves every frame to follow the mouse. I want it to properly tween.

I’m not going to share my exact script, but here’s a script that’ll replicate the issue.
(yes. i know the part flies up to the sky when you rotate it, its just a replication that when you’re changing the cframe it just simply won’t move)

--local script!!
--press R to perform the tween
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local part = Instance.new("Part")
part.Anchored = true
part.Parent = game.Workspace
part.Size = Vector3.new(4,4,4)
mouse.TargetFilter = part

game:GetService("RunService").Heartbeat:Connect(function()
	part.Position = mouse.Hit.Position + Vector3.new(0, part.Size.Y / 2, 0)
end)

game:GetService("UserInputService").InputBegan:Connect(function(key, ischat)
	if ischat then return end
	local targetrotation = CFrame.new(Vector3.new(0,90,0))
	local tweeninfo =  TweenInfo.new(1, Enum.EasingStyle.Cubic, Enum.EasingDirection.Out, 0, false, 0)
	local tween = game:GetService("TweenService"):Create(part, tweeninfo, {CFrame = targetrotation})
	tween:Play()
end)

How do I fix this?

The reason the tween doesn’t work is because you’re overwriting it every frame with part.Position = mouse.Hit.Position + Vector3.new(0, part.Size.Y / 2, 0), try replacing it with

part.CFrame = CFrame.new(mouse.Hit.Position + Vector3.new(0, part.Size.Y/2, 0)) * rotation

and tell me if it works

yeah sadly this happens

You could add a debounce variable to stop overwriting the mouse position while the Tween plays and continue it when it stopped

local debounce = false
game:GetService("RunService").Heartbeat:Connect(function()
    if debounce then return end
	part.Position = mouse.Hit.Position + Vector3.new(0, part.Size.Y / 2, 0)
end)

game:GetService("UserInputService").InputBegan:Connect(function(key, ischat)
	if ischat then return end
	local targetrotation = CFrame.new(Vector3.new(0,90,0))
	local tweeninfo =  TweenInfo.new(1, Enum.EasingStyle.Cubic, Enum.EasingDirection.Out, 0, false, 0)
	local tween = game:GetService("TweenService"):Create(part, tweeninfo, {CFrame = targetrotation})
    debounce = true
	tween:Play()
    tween.Stopped:Wait()
    debounce = false
end)
  1. i did sort of fix that error aforementioned in my previous post
  2. sadly, it’s not really the issue that i’m trying to fix. i want it to go and overwrite the mouse position while still tweening

Correct me if I’m wrong, but you’re trying to move the part, while also tweening correct?

uh huh, trying to move while tweening

I think an animation would be better (unless if you want it to go to a specific spot)

If you dont wanna use animation, maybe can make 2 parts, part2 will be anchored to part1, part1 will be teleported using the RunService, and Part2 will be doing the tweening (idk if this will work or not, just a theory)

The reason your tween isnt working is because your setting the parts Position every frame in the Heartbeat connection.

That assignment is overwriting the tween so the part never actually moves along the tween path. Tweens in Roblox work by gradually changing the property over time but if you immediately set that property every frame, the tween has no chance to do anything.


You can disconnect or temporarily ignore your Heartbeat code when performing the tween.

local moving
game:GetService("RunService").Heartbeat:Connect(function()
	if not moving then
		part.Position = mouse.Hit.Position + Vector3.new(0, part.Size.Y / 2, 0)
	end
end)

game:GetService("UserInputService").InputBegan:Connect(function(key, ischat)
	if ischat then return end
	moving = true
	local targetCFrame = CFrame.new(0, 90, 0)
	local tweenInfo = TweenInfo.new(1, Enum.EasingStyle.Cubic, Enum.EasingDirection.Out)
	local tween = game:GetService("TweenService"):Create(part, tweenInfo, {CFrame = targetCFrame})
	tween:Play()
	tween.Completed:Connect(function()
		moving = false
	end)
end)

Here the part only follows the mouse when moving is false. When the tween starts, it stops following and once the tween completes, it can follow again!!


OR Option two would be tweening Position instead of CFrame

Since your already controlling the parts Position every frame you could tween the Position rather than the CFrame. That way the tween and the movement system dont conflict as badly, though you may need to stop the per-frame updates briefly for smooth results!


You cant tween a property if your actively setting it every frame elsewhere. Either pause your updates during the tween or restructure your code so the tween dosent fight the per-frame assignments!!

Hope that helps!!

2 Likes

You cannot move the part while also tweening it at the same time. One will always be overwritten

exactly, i need to try bypass that

i guess i’ll send my actual code here:

local adjustedpos = hitpos + surfacenormal * 0.5 * gridsize
	local snappedpos = Vector3.new(
		math.floor(adjustedpos.X / gridsize.X) * gridsize.X + gridsize.X / 2,
		math.floor(adjustedpos.Y / gridsize.Y) * gridsize.Y + gridsize.Y / 2,
		math.floor(adjustedpos.Z / gridsize.Z) * gridsize.Z + gridsize.Z / 2
	)
	local info = TweenInfo.new(0.35, Enum.EasingStyle.Quint, Enum.EasingDirection.Out)
	local endcframe = CFrame.new(snappedpos) * newrotation
	local tween = TweenService:Create(block, info, {CFrame = endcframe})
	tween:Play()
	local finished = false
	local previouspos = block.Position
	rotation = newrotation
	print(block.CFrame)
	print(endcframe)
	if mob then
		refreshblockproperties(false, snappedpos - Vector3.new(0, block.Size.Y / 2, 0))
	end

now, i actually align to a grid every heartbeat or so. however, the code in this rotation tween prevents the block from moving until the tween is finished.

Two different strategies I came up with.

  1. Use a Model, Attachment, or other PVInstance to parent the tweened object. The tween only affects the child part, and the connection only affects the parent’s position.
  2. Create a CFrame to store rotation and use TweenService.GetValue to manually do the tween yourself in the same connection that you update position. Then you can offset your rotation by the position.