CFraming a part to another part with a set speed

I’ve been trying to script a turret that turns to the target it is set to, except it has a set speed when it goes to set its angle towards the target’s HumanoidRootPart. I’ve tried using CFrame:Lerp(), but it has proven to be lagging the turret’s fire rate, quite severely actually (which ends up not following the player anymore). How would I go about doing this?

Lerp code:

for i = 0, 1, 0.05 do
	RotPitch.CFrame = RotPitch.CFrame:Lerp(CFrame.new(RotPitch.CFrame.p, TargetRoot.CFrame.p), i)
	wait()
end
1 Like

You can use TweenService to smoothly transition between all sorts of values, including CFrames. It also saves you the trouble of keeping track of loops and progress variables!

Converting your code to using TweenService, it might look a little like this:

local TweenService = game:GetService("TweenService")

local waitTime = 0.03 --approximately how many seconds wait() waits for
local tweenTime = (waitTime / 0.05) --the 0.05 comes from your initial code example
local tweenInfo = TweenInfo.New( tweenTime ) --there are many more (optional) paramters to TweenInfo.New()

--each key in goal is a Property, each value is a goal value for that Property
local goal = { CFrame = CFrame.new(RotPitch.CFrame.p, TargetRoot.CFrame.p) } 
local tween = TweenService:Create(RotPitch, tweenInfo, goal)
tween:Play()

EDIT: oh, and definitely check out the wiki pages! 1 2 3. One important thing to note is that Tween:Play() is asynchronous, meaning the script won’t wait for the tween to finish before continuing with the next line of code (if I recall correctly, someone please confirm or deny).

1 Like

I’ve considered using TweenService but took into account the memory usage the server would need to use for calculating the tweening (since the sentry is server sided). I’ll probably resort to using TweenService but I’ll wait for further replies.

To smoothly transition a part, with a speed that can be set, use a script in the part
(part1) and part2(part_to_go_to) is the part part1 will move to
here is the script/not a local one, use this in the part :

local go_to_part = workspace.part2.CFrame  
--define the variable as the second part's CFrame, the one this will move to

local speed = 2--how fast it should lerp

game:GetService('RunService').Heartbeat:connect(function(step)  
	
	
	script.Parent.CFrame = script.Parent.CFrame:lerp(go_to_part,step/speed)
	
end)

[tested, it works]

Didn’t think about it that way, I’ll check this out later, thank you!

@ThanksRoBama

Yep, TweenBase:Play() is asynchronous however if you want it to be Synchornous you can wait on it’s Completed event:

TweenBase.Completed:Wait()

@XxELECTROFUSIONxX
Great method, just remember to :Disconnect() the event after it’s finished Lerping otherwise it can cause a memory leak

Here’s an example based on your example:

local runService = game:GetService("RunService")
local destinationCFrame = workspace.part2.CFrame
local speed = 2

local heartbeat do --Pushing it into a do block for clean syntax
    heartbeat = runService.Heartbeat:Connect(function(step)
        script.Parent.CFrame = script.Parent.CFrame:Lerp(destinationCFrame, step/speed)

        if script.Parent.CFrame == destinationCFrame then
            heartbeat:Disconnect()
            return
        end
    end)
end
2 Likes