I have this problem that I don’t really know how to begin to solve. I created a turret that shoots at players and it works fine. I use TweenService to make the turret rotate towards players’ heads. I scripted it so the turret waits to turn before shooting. The fire rate is slower when it turns as it has to wait. However, if a player targeted by it even moves slightly (for example from an idle animation) the fire rate will slow down as it has to tween to the new position of the player head. It will take the same amount of time to rotate small distances vs larger distances. How would I make it so that the turret’s rotational speed depends on the distance it needs to rotate towards a target?
I’ve tried to make the turret not tween when it doesn’t need to, but again, this doesn’t work as a slight movement can cause it to need to tween again.
Test with Dummy:
Test with a player:
As you can see, the fire rate for the Dummy is faster since it does not move at all.
Code used to tween:
local tweeninfo = TweenInfo.new(.25,Enum.EasingStyle.Linear,Enum.EasingDirection.InOut)
local LookAt = Vector3.new(target.Position.X, Turner.Position.Y, target.Position.Z)
if Turner.CFrame ~= CFrame.lookAt(Turner.Position, LookAt) then
local goal = {}
local goal2 = {}
goal.CFrame = CFrame.lookAt(Turner.Position, LookAt)
goal2.CFrame = CFrame.lookAt(Turner2.Position, target.Position)
local TurnerTween = TS:Create(Turner,tweeninfo,goal)
local TurnerTween2 = TS:Create(Turner2,tweeninfo,goal2)
TurnerTween:Play()
TurnerTween2:Play()
TurnerTween2.Completed:Wait()
end
“Turner” and “Turner2” are invisible parts welded to the turret to make it turn.
Using tween services might be the not recommended solution here as you said you will need to change the 0.25 and possible create a new tween info every time which is doable but it just feels odd in my opinion.
Anyways, to ensure constant turret speed you can use CFrame lerping between the turrets current CFrame and the goal CFrame through the following formula by measuring the angular distance between current and goal. I believe you can also apply this to tween service but well it’s up to you.
local adjustedLerpAlpha
if step and self.ConstantSpeed then
local angularDistance = VectorUtil.AngleBetween(currentRotation.LookVector,goalRotationCFrame.LookVector)
local estimatedTime = self.AngularSpeed/angularDistance
adjustedLerpAlpha = math.min(step*estimatedTime,1)
elseif step then
--other stuff
end
Also I don’t recommend this.
When working with numbers like CFrames you will always run into floating point errors hence it’s not exactly sure if this condition can be true at all, I would recommend measuring the angle instead if its in a certain range to see if the turret is pointing close to the target to avoid the floating point error.