Camera has a property called CameraSubject. You can raycast (or utilize mouse.Hitmouse.Target) after a player clicks and determine whether that object belongs to another player through a simple conditional. Simply set CameraSubject to the head of the opposing player. If you’d like the camera to stay at its location while rotating according the other player’s direction, you can set a property of camera called CameraType to Enum.CameraType.Watch.
Sure thing! Here’s a little script that I believe completes part of what you want accomplished:
local uis, plrs = game:GetService'UserInputService', game:GetService'Players';
local plr, char = plrs.LocalPlayer, script.Parent; --StarterCharacterScripts allows us to fetch Character without referencing Player!
local mouse, cam = plr:GetMouse(), workspace.CurrentCamera;
if processed or input.UserInputType ~= Enum.UserInputType.MouseButton1 then return; end --ensure the input was a left click and wasnt intended for clicking a GUI
local hit = mouse.Target; --you can also raycast from the camera to mouse.Hit.Position for more customizability
if not hit then return; end --the player probably had their mouse on the skybox when they clicked
local head = hit.Parent:FindFirstChild'Head';
if not head then return; end --the parent of the target doesnt own a child named 'head' so that probably means the target wasnt a player; you should probably implement further verifcation to ensure a player is clicked
cam.CameraType = Enum.CameraType.Watch; --can set to anything but if you want the camera to be dead stationary you could set this to scriptable and change the cframe every renderstep
cam.CameraSubject = head;
If you’d like the camera to be stationary, you could change CameraType to Enum.CameraType.Scriptable and alter the CFrame every frame (RenderStepped) to keep the camera fixated towards the opposing player (as I suggested), but there could be another method of forcing the camera to stay where it is whilst having CameraType on Watch.
Here’s how I would go about the former option:
cam.CameraType = Enum.CameraType.Scriptable;
runSvc:BindToRenderStep('camUpdate', Enum.RenderPriority.Camera.Value + 1, function()
cam.CFrame = CFrame.new(char.Head.Position, head.Position); --create a new cframe located at the head of the current player oriented towards the other player's head
end) --unbind 'camUpdate' and revert to camera's original settings as AstralBlu_e suggested you preserve when no longer needed
The code snippet should supersede anything under the conditional for verifying the head of the other player. Do note that since we are utilizing RunService:BindToRenderStep(), the variable runSvc should be replaced with a reference to that service. I’ve also made some edits to the snippet due to some minor details I overlooked.
To get a service, we call :GetService() on the ServiceProvider (predefined variable game). :GetService() accepts a single string value representing the name of the service you want referenced as an argument; in this case, "RunService".