Hello, when a player joins the game, I want to clone a part, then re-position it to where the players camera is, and make it stick to it. (AKA weld it) I’ve tried a few things so far but the closest I could get was where it only worked on the client-side, meaning the player could only see the part positioned at their camera, not anyone else’s. Also, it’s really laggy being re-positioned over and over again, so I’d rather it got welded than re-positioned.
Client Script:
local PartClone = game.ReplicatedStorage.TestPart:Clone()
PartClone.Parent = game.Workspace
while wait() do
PartClone.Position = game.Workspace.CurrentCamera.CFrame.Position
end
I would like it to be positioned on the server-side, but you can’t access the players’ current camera there, which is a problem.
If you give client network ownership of the part via part:SetNetworkOwner(plr), the player can use a LocalScript to position the part on RenderStepped. The position will be 100% smooth on the client, and the server will get updates as fast as possible, without clogging up your RemoteEvent queue. Other players will see this.
Just make sure the part is unanchored before you try to set the network owner. The part also has to be created on the server & SetNetworkOwner can only be called on the server.
It works exactly how I said. All you have to do is call part:SetNetworkOwner(plr), and then when that player uses LocalScripts to move the part, it will move for everyone in the game
Here’s an example. Server script:
local part = game:GetService('ReplicatedStorage').TestPart
local function playerAdded(plr)
local function characterAdded(char)
local clone = part:Clone()
clone.Parent = char
-- This `if` statement needs to be here because Roblox is about to break `:Wait()` with Deferred Events
if not char:IsDescendantOf(workspace) then char.AncestryChanged:Wait() end
clone:SetNetworkOwner(plr)
end
plr.CharacterAdded:Connect(characterAdded)
if plr.Character then characterAdded(plr.Character) end
end
local players = game:GetService('Players')
players.PlayerAdded:Connect(playerAdded)
for _, plr in ipairs(players:GetChildren()) do
playerAdded(plr)
end
So much boilerplate just to parent a part to a character. Whatever…
LocalScript (in StarterPlayer.StarterCharacterScripts):
local part = script.Parent:WaitForChild('TestPart')
game:GetService('RunService').RenderStepped:Connect(function()
part.CFrame = workspace.CurrentCamera.CFrame
part.AssemblyLinearVelocity *= 0
part.AssemblyAngularVelocity *= 0
end)
It gave an error saying Can only call Network Ownership API on a part that is descendent of Workspace on the line that says clone:SetNetworkOwner(plr).
Oh, forgot CharacterAdded is called before the character is parented to Workspace. Might want to slap a wait() in there, right before the call to SetNetworkOwner, since char.AncestryChanged:Wait() would stop working once Roblox finishes butchering events.