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.
Okay I’ll see what I can do thanks for the clarification
Take a look at this
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.
You are looping through players and checking whether its a Humanoid, when its a player.
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?
(I’ll have to go now so I’ll be on tomorrow.)
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)
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
Should I use a local script or a server script?
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
Oh, I was planning on using a remote event or moduleScript to “re-parent” the player
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)
Sorry for the late reply,
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.
Tried to call the character, got an error though.
local function DetectingTarget()
for _,v in pairs(game.Workspace.AllCharacters:GetChildren()) do
local TargetHumanoid = v.Character:FindFirstChild("Humanoid")
end
end
I’m a terrible scripter but you could try finding all humanoids in an area, locating its parent, and making a GUI that tracks the model’s location.
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!