Never ever put a while loop in a renderstepped (or vise versa), your game will crash very quickly.
RenderStepped is fired every frame, if you connect a loop every frame it will quickly be running many thousands of instances of that loop and it will keep piling up.
This line does not make any sense, :GetChildren() returns an array of instance’s children and takes 0 parameters.
You have to have some code that decides which player to “lock on” to, you’ll probably want to do that on User Input or something
I’ve been trying to get a player’s HumanoidRootPart. Should I just resort to using a different part of the player instead? Also I’ll use “If Focus then” instead of the loop. I also get Vector3 errors for my CFrame.
I suggest to put all the players in a folder within the workspace when they spawn. Then you could easily loop through the folder, then search for the nearest target.
For the collision you could use rays to check if there is an object in the way.
To make it not target players that are already dead, you could use the CollectionService to tag players that are dead, then untag them when they respawn.
*Edit
Try making separate functions like this.
1 : A function that returns a target to lock on to
Example:
local function identifytarget()
-- Loop folder, find nearest target, return target
maybetarget = torso.Parent
return target
end
--then u can refer the target somewhere in the script
Target = identifytarget()
2: A function that does the camera lock on thing
local function lockon()
--lock camera to target
end
3: A function that runs the above functions after getting the input
local Target = nil
-- left alt pressed event
Target = identifytarget() -- returns the target (refer to the function above)
if Target then -- check if there is a target
RunService:BindToRenderStep("lockontarget"),203,lockon)
end
This is just an idea for the script
Not an actual how to do
You should use local scrip
and
You could, if u want, do two local scripts, one for listening to the input, and one for doing the camera lock on. Then bind them using bindable events or something
For the putting players character in one folder thing should be in a server script. You can put in the script in the server script service or something. If this is what you mean for “re-parent” the player.
Made the script today, using your template. Also I couldn’t move the player to a folder so I just made a local script and put it in the StarterPlayer. Everything is fine except that I have an error with TargetHRP
local RS = game:GetService("RunService")
local UIS = game:GetService("UserInputService")
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local HRP = Character:WaitForChild("HumanoidRootPart")
local Camera = game.Workspace.CurrentCamera
local Target = nil
local Distance = 50
local function DetectingTarget()
for _,v in pairs(game.Players:GetChildren()) do
local TargetHRP = v:FindFirstChild("HumanoidRootPart")
local TargetHumanoid = v:FindFirstChild("Humanoid")
if TargetHRP and TargetHumanoid ~= script.Parent and Player.Name then
if (HRP.Position - TargetHRP.Position).Magnitude < 50 then
Distance = (HRP.Position - TargetHRP.Position).Magnitude
end
end
return v
end
end
Target = DetectingTarget()
local function CameraTarget()
Camera.CameraType = Enum.CameraType.Scriptable
local TargetHRPPos = Target.TargetHRP.Position
local HRPPos = HRP.Position
local Offset = Vector3.new(10,10,10)
local CamPos = TargetHRPPos + ((HRPPos + Offset) - TargetHRPPos).Unit * ((HRPPos - TargetHRPPos).Magnitude + 12)
Camera.CFrame = CFrame.new(CamPos, TargetHRPPos)
RS.RenderStepped:Wait()
end
UIS.InputBegan:Connect(function(Input)
if Input.KeyCode == Enum.KeyCode.LeftAlt then
if Target then
RS:BindToRenderStep("CameraLockOn", 203, CameraTarget)
elseif Input.KeyCode == Enum.KeyCode.LeftAlt and Target then
Camera.CameraType = Enum.CameraType.Scriptable
Target = nil
RS:UnbindFromRenderStep("CameraLockOn")
end
end
end)
I think the issue is that, you are currently looping the player not the character.
What makes the character different is because it is a model, when u test the game, you could see your character in the workspace. Also, if u have trouble putting all the characters in a folder here you go:
Make a folder in workspace.
Add a script in serverscriptservice
Then copy this.
local function onPlayerAdded(p)
p.CharacterAdded:Connect(function(character)
task.wait(0.1)
character.Parent = game.Workspace.AllCharacters -- this is your folder that u added
end)
end
game.Players.PlayerAdded:Connect(onPlayerAdded)
However, in the future, you need to add a safety measure so that a hacker cannot put their character out of the folder.
local function DetectingTarget()
for _,v in pairs(game.Workspace.AllCharacters:GetChildren()) do
local TargetHumanoid = v.Character:FindFirstChild("Humanoid")
end
end
Solved the small problem, I just couldn’t use the Character for some reason since it isn’t part of the folder I hold all the players in. Thanks for the help though!
I have a problem with an “else if” statement I made for the key bind whenever the player presses on the key bind again. It shows no errors though, but doesn’t go back to custom.
UIS.InputBegan:Connect(function(Input, Processed)
if Input.KeyCode == Enum.KeyCode.LeftAlt then
Target = FindTarget()
Camera.CameraType = Enum.CameraType.Scriptable
elseif Input.KeyCode == Enum.KeyCode.LeftAlt and Target ~= nil then
Target = nil
Camera.CameraType = Enum.CameraType.Custom
end
end)
I prefer not using a folder to store players in so that when an exploiter gets his character out of the folder, it doesn’t remove the target lock-on.
Here is the script:
local function FindTarget()
for _,v in pairs(game.Players:GetChildren()) do
if v ~= Player.Name then
local TargetHum = v:FindFirstChild("Humanoid")
local TargetHRP = v:FindFirstChild("HumanoidRootPart")
return v
end
end
end
UIS.InputBegan:Connect(function(Input, Processed)
if Input.KeyCode == Enum.KeyCode.LeftAlt then
Target = FindTarget()
if Target then
Camera.CameraType = Enum.CameraType.Scriptable
local TargetHRPPos = Target.TargetHRP.Position
local HRPPos = HRP.Position
print(TargetHRPPos)
end
end
end)
I’ve tried removing the local from function and it seems like its not a scoping problem.
task.wait(5)
for i , v in pairs (game.Players:GetChildren())do
print(i,v)
local children= v:GetChildren()
print(children)
end
And look at the output.
The second print function prints =
{
[1] = StarterGear,
[2] = Backpack,
[3] = PlayerGui
}
If you don’t want to use a folder, you would have to find a way to get all the players’s character.
I don’t seem to know the alternate way right now, but I am going to try to search for it. Once I have an alternate that I found for you I will inform u