How to: Lock onto NPC's when in certain range

How would i go about adding a camera lock feature that locks on to NPC’s when the player is within a certain radius? Basically an auto aim function.

Well first off, I’d make sure that this script is client-side only. There’s no need for any sort of server script.

I would make sure that all the enemies in your game are organized in a folder in workspace or something. Then you could just gather them into a table like so:

local enemies = workspace.Enemies:GetChildren()

Then I’d run a RenderStepped function to constantly check which enemy is closest every frame. If an enemy is too far away, let the player’s camera move normally. If it is close enough to an NPC, lock onto it. If there is more than one possible NPC to lock onto, lock onto the closest one.

local closeEnemies = {}
local closestEnemy = nil

local RS = game:GetService("RunService")
local maxDistance = 10 -- 10 studs is the farthest as an example
local player = game.Players.LocalPlayer
local character = player.Character

RS.RenderStepped:Connect(function()
    if not player.Character then -- ensure character exists
        character = player.CharacterAdded:wait()
    else
        local hrp = character.HumanoidRootPart
        for _, enemy in pairs(enemies) do -- get the closest enemy
            local dist = (enemy.HumanoidRootPart.Position - hrp.Position).Magnitude
            if dist <= maxDistance then
                table.insert(closeEnemies, {dist, enemy.Name})
            end
        end
        for _, enemy in pairs(closeEnemies) do
            if closestEnemy == nil or enemy[1] < closestEnemy[1] then
                closestEnemy = enemy -- closest enemy stored here
            end
        end
        -- take appropriate camera action below here
        if closestEnemy == nil then -- if there are no close enemies
            -- set camera back to player. default view
        else -- if there is one
            -- set cframe of camera to CFrame.new(hrp.Position, closestEnemy.HumanoidRootPart.Position) * CFrame.new(0, 0, -10)
            -- will have to set cameraType to scriptable
        end
        closestEnemy = nil -- reset info for next loop
        table.clear(closeEnemies)
    end
end)

This is a good foundation you could build off of.

3 Likes

Physicism the GOAT. Appreciate it man!