-
What do you want to achieve?
A fully automated aiming system. -
What is the issue?
The turret aims above the target. -
What solutions have I tried so far?
I tried adding offsets to the final values and that didn’t work.
local function hasHumanoid(part)
if part and part.Parent then
return part.Parent:FindFirstChild("Humanoid") ~= nil
end
return false
end
local function isTargetVisible(target)
if not target then return false end
local direction = (target.Position - stubreff.Position)
local distance = direction.Magnitude
if distance > maxRange then return false end
direction = direction.Unit
local result = workspace:Raycast(stubreff.Position, direction * distance, raycastParams)
if result then
return result.Instance == target or
(result.Instance.Parent and result.Instance.Parent == target.Parent)
end
return false
end
local function findTarget()
local nearestDistance = maxRange
local nearestTarget = nil
local function scanParts(parent)
for _, child in ipairs(parent:GetChildren()) do
if child ~= myModel then
if child:IsA("BasePart") and hasHumanoid(child) then
local humanoid = child.Parent:FindFirstChild("Humanoid")
if humanoid and humanoid.Health > 0 and isTargetVisible(child) then
local distance = (child.Position - stubreff.Position).Magnitude
if distance < nearestDistance then
nearestDistance = distance
nearestTarget = child
end
end
end
scanParts(child)
end
end
end
scanParts(workspace)
return nearestTarget
end
local function calculateTargetAngles(target)
if not target then return 0, 0 end
local targetHRP = target.Parent:FindFirstChild("HumanoidRootPart")
if not targetHRP then return 0, 0 end
local targetPosition = targetHRP.Position
local turretPosition = stubreff.Position
local directionToTarget = targetPosition - turretPosition
local yaw = math.atan2(directionToTarget.X, directionToTarget.Z)
local horizontalDistance = Vector3.new(directionToTarget.X, 0, directionToTarget.Z).Magnitude
local pitch = math.atan2(directionToTarget.Y, horizontalDistance)
return math.deg(yaw), math.deg(pitch)
end
local function rotatePitchSmoothly(targetPitch, deltaTime)
local currentPitchRad, _, _ = Pitch6d.C0:ToEulerAnglesYXZ()
local currentPitchDeg = math.deg(currentPitchRad)
local deltaPitch = (targetPitch - currentPitchDeg + 180) % 360 - 180
local maxDeltaThisFrame = turretPitchSpeed * deltaTime
deltaPitch = math.clamp(deltaPitch, -maxDeltaThisFrame, maxDeltaThisFrame)
local newPitchDeg = currentPitchDeg + deltaPitch
Pitch6d.C0 = CFrame.Angles(math.rad(newPitchDeg), 0, 0)
end
local function rotateTurretSmoothly(targetAngle, deltaTime)
local _, currentRotationRad, _ = Yaw6d.C0:ToEulerAnglesYXZ()
local currentRotationDeg = math.deg(currentRotationRad)
targetAngle = targetAngle + 180
local deltaAngle = (targetAngle - currentRotationDeg + 180) % 360 - 180
local maxDeltaThisFrame = turretYawSpeed * deltaTime
deltaAngle = math.clamp(deltaAngle, -maxDeltaThisFrame, maxDeltaThisFrame)
local newRotationDeg = currentRotationDeg + deltaAngle
Yaw6d.C0 = CFrame.Angles(0, math.rad(newRotationDeg), 0)
end
local function fire()
if not canFire then return end
canFire = false
fireSound:Play()
BulletModule.fireRay(firePoint, {myModel})
task.delay(fireRate, function()
canFire = true
end)
end
local function trackTarget()
while isTracking and task.wait(0.05) do
currentTarget = findTarget()
if currentTarget then
local targetHumanoid = currentTarget.Parent:FindFirstChild("Humanoid")
local targetHRP = currentTarget.Parent:FindFirstChild("HumanoidRootPart")
if targetHRP and targetHumanoid and targetHumanoid.Health > 0 then
local targetCenter = targetHRP.Position + Vector3.new(0, targetHRP.Size.Y/2, 0)
local targetYaw, targetPitch = calculateTargetAngles(currentTarget)
rotateTurretSmoothly(-targetYaw, 0.05)
rotatePitchSmoothly(-targetPitch, 0.05)
local directionToTarget = (targetCenter - firePoint.Position).Unit
local fireDirection = firePoint.CFrame.LookVector
local dotProduct = fireDirection:Dot(directionToTarget)
if (targetCenter - stubreff.Position).Magnitude <= maxRange and canFire and dotProduct > 0.95 then
fire()
end
else
currentTarget = nil
end
end
end
end