Tween with changing goal

Okay. So I know how to tween. However, I wanted to make an Aiming system for my turret direction for a tank. I want to be able to control the amount of time it takes for the tanks turrent to reach its target. But the problem is that I don’t know what would be the best way to have a tween with a moving target.

I thought creating a tween every frame seemed unreasonable. Also the reason why I wanted to do this is to control the time and I still don’t think that would even be a way to control the amount of time it takes for the turret to face the target.

I considered lerp. But I still don’t think I am able to control time accurately there either. Also, it for very far distances takes even longer to reach the target due lerp never achieving the goal.

Any ideas?

1 Like

RunService with Stepped/HeartBleed, while task.wait() do loop, GetPropertyChangedSignal()/.Changed events for movement of the mouse etc.

That doesn’t answer my question.

I want to know how I can Tween a CFrame with a changing goal.

It does, but if you need a more direct answer.

local part = script.Parent
local ts = game:GetService("TweenService")

while task.wait(1) do --set delay between each cycle/pass of the loop to the length of time the tween takes to play
	local tween = ts:Create(part, TweenInfo.new(1), {Position = part.Position + Vector3.new(1, 0, 1)})
	tween:Play()
end
local part = script.Parent
local ts = game:GetService("TweenService")

while task.wait(1) do --set delay between each cycle/pass of the loop to the length of time the tween takes to play
	local tween = ts:Create(part, TweenInfo.new(1), {["CFrame"] = part.CFrame * CFrame.new(1, 0, 1)})
	tween:Play()
end

and for CFrame as requested.

“Tween with a changing goal” sounds just like a Spring. Here’s a Spring implementation by Quenty NevermoreEngine/Spring.lua at 5a429e871d54646ba54011c18321e77afa76d657 · Quenty/NevermoreEngine · GitHub

The problem with springs is that you can’t control their time. If your goal is changing then you will inevitably sacrifice knowing the exact time your object will reach the goal. But, of course, you can always adjust their speed!

Here’s some code example of how springs work:

local RunService = game:GetService("RunService")
local Spring = require(...moduleLocation.Spring)
local part = script.Parent

local spring = Spring.new(part.Position) --// Create a spring and set its current position to the part's position
spring.Speed = 2 --// Put the speed that you want
spring.Damper = 1 --// This value decides how "springy" your object's motion is! At 1 there's no spring effect at all, and at 0 it's at maximum.

RunService.Heartbeat:Connect(function() --// Update our object's position every frame
	part.Position = spring.Position --// Set the part's position to current spring's value
end)

while task.wait(1) do --// Now let's create a loop that will change the goal every second
	spring.Target = spring.Position + Vector3.new(math.random(-10, 10), math.random(-10,10), math.random(-10,10))
	--// The part will move to a randomized goal around itself
end

It’s important to note that springs can only operate with number and Vector3 values. That means that if you need to both rotate the part and change its position you’ll have to create two springs: one for Position and one for Orientation! Springs can’t operate with CFrames.

Hope that helped a little bit!

How would that apply for a rotating turret?

I need to be able to control the amount of time it takes for a turret to rotate to meet a moving target.

I need to be able to control the time. Even if controlling the time accurately isn’t possible I still need to be able to have a turret rotate consistently and reach a goal.

@Forummer That doesn’t work. This is what the turret looks like with your method:


It really fails to reach the moving target at all. I need to be able to change the goal constantly.

For reference the turret will be a part of a spaceship and basically the turrent will have an aimtime from when the enemy ship appears on radar and then after the aimtime the turret will fire. But the enemy ship doesn’t stay still and if I am using a tween then the turret usually does not aim correctly and misses

The best solution to this would be a loop of some sort that runs a new tween whilist stopping the previous tween:Cancel() . To achieve seemless transition use Enum.EasingStyle.Linear and perhaps dont tween:Cancel() the previous tween until the new one begins playing.

Also maybe you want to calculate the length of the Vector3 distance btween the two to get the speed of the turret.
Something similar i used is
local Vectir= (Target.Position-Subject.HumanoidRootPart.Position).Magnitude
if Vectir<40 then
tweenInfo = TweenInfo.new(Vectir/10)
else
tweenInfo = TweenInfo.new(4)
end

Thanks for your answer. Someone from the play canvas forum has answered this for me now.

Yes just to clarify my method would be good for tweening a projectile. For example the variable “Vectir” is say 80, divided by 10 to get 8 seconds, a variable of 20 would be reach its goal in 2 seconds, for a speed of 10 units per second no matter the distance.
I used this method recently, I read this post while researching ideas i had. For an energy ball projectile. I use that algorithm and multiply it by the Speed modifier and there you have a projectile that moves at a constant speed and that adjusts its goal position based on the new position of the target.