I am trying to make a target lock-on in which it will lock on a player’s movement once a certain key bind is pressed. I also want to make so that there could be a certain distance for the lock to be on and that the lock-on doesn’t go through collisions
The issue is, I can’t use it on players, if I try to make Target.Position it would not be a valid member of CurrentCamera
I’ve tried using i v pairs and adding “.Position”.
local UIS = game:GetService("UserInputService")
local RS = game:GetService("RunService")
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Mouse = Player:GetMouse()
local Camera = game.Workspace.CurrentCamera
local Focus = false
UIS.InputBegan:Connect(function(Input, Processed)
if Input.KeyCode == Enum.KeyCode.LeftAlt and not Focus and not Processed then
Camera.CameraType = Enum.CameraType.Scriptable
Focus = true
wait()
spawn(function(Position)
for _,Target in pairs(game.Workspace:GetChildren()) do
if Target:FindFirstChild("Humanoid") and Target:FindFirstChild("HumanoidRootPart") and Target ~= script.Parent or Player.Name then
local HumanoidRootPartPosition = Character.HumanoidRootPart.Position
local OffSet = Vector3.new(10,4,0)
local ViewTarget = Target + ((HumanoidRootPartPosition + OffSet) - Target).Unit * ((HumanoidRootPartPosition - Target).Magnitude + 12)
Camera.CFrame = CFrame.new(ViewTarget, Target)
end
end
end)
end
end)
So you want it to lock on the closest target to players camera? You could use the camera’s LookVector and find the closest player in that direction.
Anyway to make the code I would firstly use ContextActionService and bind the action to a key, then use BindToRenderStepped to find and update the players camera cframe.
I used UserInputService instead is there any difference if I used ContextActionService? I also used RunService (Forgot to put RenderStepped) but the main problem I have is trying to identity a player’s HumanoidRootPart so I could lock the player’s camera to that certain player’s HumanoidRootPart (if that makes sense) as I got an error with my script.
ContextActionService allows you to bind functions to “actions” like key presses. In this scenario I would use it.
take out the “wait()” and take out the spawn()
Use Renderstepped and do
for _,player in ipairs (game.Players:GetPlayers()) do
local HumanoidRootPart = player.Character.HumanoidRootPart -- assuming the player has a character
-- the "camera cframe setting" needs to go in a RenderStepped
-- so that it updates every frame
end
local UIS = game:GetService("UserInputService")
local RS = game:GetService("RunService")
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Mouse = Player:GetMouse()
local Camera = game.Workspace.CurrentCamera
local Focus = false
UIS.InputBegan:Connect(function(Input, Processed)
if Input.KeyCode == Enum.KeyCode.LeftAlt and not Focus and not Processed then
Camera.CameraType = Enum.CameraType.Scriptable
Focus = true
while Focus do
for _,Player in ipairs(game.Players:GetPlayers()) do
if Player:FindFirstChild("Humanoid") and Player:FindFirstChild("HumanoidRootPart") and Player ~= script.Parent or Player.Name then
local HumanoidRootPart = Player.Character.HumanoidRootPart
local HumanoidRootPartPosition = Character.HumanoidRootPart.Position
local OffSet = Vector3.new(10,4,0)
local ViewTarget = Player + ((HumanoidRootPartPosition + OffSet) - Player).Unit * ((HumanoidRootPartPosition - Player).Magnitude + 12)
Camera.CFrame = CFrame.new(ViewTarget, Player)
RS.RenderStepped:Wait()
end
end
end
elseif Input.KeyCode == Enum.KeyCode.LeftAlt and not Processed and Focus then
Focus = false
Camera.CameraType = Enum.CameraType.Custom
end
end)
Something doesn’t work. Is there anything I’m doing wrong?
You are trying to do math on an instance (player) plus there is no player.Unit or player.Magnitude and the braces are in the wrong place.
Anyway you have to figure out who you want to lock on to, right now you looping through each player and setting the cframe for one frame.
What you need to do is pass or bind a function to render stepped, within the function you need to do 2 things.
Calculate which player you will lock onto (assuming you want it to be based on the location of the player otherwise calculate it outside of renderstepped)
Set the camera cframe to lock onto the selected player
I’m not at my PC rn and I have to go for the night, good luck
Update: I’ve made a RenderStepped function for the camera lock. I watched some tutorials on how to make a lock-on and used one as a guide on how to adjust the camera CFrame onto a player. I’m still new to scripting so I have a vague understanding of camera manipulation and CFrame.
UIS.InputBegan:Connect(function(Input, Processed)
if Input.KeyCode == Enum.KeyCode.LeftAlt and not Focus and not Processed then
Camera.CameraType = Enum.CameraType.Scriptable
Focus = true
while Focus do
for _,Target in ipairs(game.Players:GetPlayers()) do
if Target:FindFirstChild("Humanoid") and Target:FindFirstChild("HumanoidRootPart") and Target ~= script.Parent or Player.Name then
local TargetRootPart = Target.Character.HumanoidRootPart
local LocalPlayerHumanoidRootPart = Player.Character.HumanoidRootPart
RS.RenderStepped:Connect(function() -- Added RenderStepped function
local TargetDistance = (LocalPlayerHumanoidRootPart - TargetRootPart).Magnitude
if 45 > TargetDistance then -- To detect if a player is close enough to lock on
local CameraViewPosition = CFrame.new(LocalPlayerHumanoidRootPart.Position, Target.Position)*CFrame.new(1,1,1).p -- Found a tutorial and used script as guide
Camera.CFrame = CFrame.new(CameraViewPosition, Target.Position)
end
end)
end
end
end
elseif Input.KeyCode == Enum.KeyCode.LeftAlt and not Processed and Focus then
Focus = false
Camera.CameraType = Enum.CameraType.Custom
end
end)
Since I used a tutorial’s script for the camera’s CFrame setting, I don’t get how it works. Also, when playing the RunService my game crashes even when I add a wait()
The client presses the key and automatically locks-on the nearest player. It stays locked on when a player until the client is out of range (Moves away) or dies. The lock-on has a range for players from the closest being the first to lock-on onto to but if it is in view of the client, if it is close to the client but either behind or out of view it won’t play. Also the lock-on should not clip through collisions like walls and floors. It will also have a BUI but I’ll take care of that. Also the lock-on should not work on a dead player’s HumanoidRootPart. The client should have his or her’s torso facing the player when locked on. Sort of like shift lock movement.
Sorry for the late response. I was busy maybe we could continue this tomorrow later in the afternoon? I have school so in 5:00 or 6:00 PM CDT I might be on.
Ok, so I made a lock-on script from a tutorial but modified it.
Here is the script:
local UIS = game:GetService("UserInputService")
local RS = game:GetService("RunService")
local Player = game:GetService("Players").LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Camera = game.Workspace.CurrentCamera
local Target = nil
UIS.InputBegan:Connect(function(Input)
if Input.KeyCode == Enum.KeyCode.LeftAlt then
for _,v in pairs(game.Players:GetChildren()) do
if v:IsA("Humanoid") then
Target = v
else
Target = nil
end
end
end
end)
RS.RenderStepped:Connect(function()
if Target then
local CameraPosition = CFrame.new(Character.HumanoidRootPart.Position, Target.PrimaryPart.Position)*CFrame(10,10,10).p
Camera.CameraType = Enum.CameraType.Scriptable
Camera.CFrame = CFrame.new(CameraPosition, Target.PrimaryPart.Position)
else
Camera.CameraType = Enum.CameraType.Custom
end
end)
I still have to add magnitude to add distance and much more other things.
Here is the video:
I’ve tested the script I made and when playing, it doesn’t show any errors but doesn’t lock-on to anything. I’ve tried altering the script, doesn’t work.
Is there any way I could get the HumanoidRootPart of the player (Not client) so that the camera can focus on the player? Do I still have to use I, v pairs or something else?
Changed the script, though I got a CFrame error I don’t know how to fix.
local UIS = game:GetService("UserInputService")
local RS = game:GetService("RunService")
local Player = game:GetService("Players").LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Camera = game.Workspace.CurrentCamera
local Focus = false
UIS.InputBegan:Connect(function(Input, Processed)
if Input.KeyCode == Enum.KeyCode.LeftAlt and not Focus and not Processed then
Focus = true
Camera.CameraType = Enum.CameraType.Scriptable
elseif Input.KeyCode == Enum.KeyCode.LeftAlt and Focus and not Processed then
Focus = false
Camera.CameraType = Enum.CameraType.Custom
end
end)
RS.RenderStepped:Connect(function()
while Focus do
local CameraTarget = game.Workspace:GetChildren(Character:WaitForChild("HumanoidRootPart"))
local CameraPosition = CFrame.new(Player.Character.HumanoidRootPart.Position, CameraTarget.Position)*CFrame(10,10,10).p
Camera.CFrame = CFrame.new(CameraPosition, CameraTarget.Position)
RS.RenderStepped:Wait()
end
end)