Question about first person hands

So, I’m well aware there is 1000 topics on first person hands, I’ve looked for my question and the answer and have found neither.

If I make a view model and use tools, how will OTHER players see my animation and tool. Since the arms and the tool are technically client sided, I’m very very confused on how the other players are going to see me using animations, or how to even add animations that only other players will see.

1 Like

Animations replicate to the server and other clients when played on a client.

1 Like

I’m animating client sided fake hands that don’t exist on the server or other players clients

1 Like

So, try this. Use this LocalScript inside your tool.

local tool = script.Parent
local player = game.Players.LocalPlayer
local replicatedStorage = game:GetService(“ReplicatedStorage”)
local toolAnimationEvent = replicatedStorage:WaitForChild(“ToolAnimationEvent”)

local function onEquipped()

toolAnimationEvent:FireServer("Equipped", tool)

tool.Activated:Connect(function()
	
	local animation = tool:FindFirstChild("YourAnimation")
	if animation then
		local animator = tool:FindFirstChildOfClass("Animator")
		if animator then
			animator:LoadAnimation(animation):Play()
		end
	end
	
	toolAnimationEvent:FireServer("PlayAnimation", tool)
end)

end

local function onUnequipped()

toolAnimationEvent:FireServer("Unequipped", tool)

end

tool.Equipped:Connect(onEquipped)
tool.Unequipped:Connect(onUnequipped)

And use this for ServerScriptService:

local replicatedStorage = game:GetService(“ReplicatedStorage”)
local toolAnimationEvent = Instance.new(“RemoteEvent”)
toolAnimationEvent.Name = “ToolAnimationEvent”
toolAnimationEvent.Parent = replicatedStorage

toolAnimationEvent.OnServerEvent:Connect(function(player, action, tool)
if action == “PlayAnimation” then
– Broadcast to all other clients to play the animation
for _, otherPlayer in pairs(game.Players:GetPlayers()) do
if otherPlayer ~= player then
toolAnimationEvent:FireClient(otherPlayer, action, player, tool.Name)
end
end
elseif action == “Equipped” then
– Broadcast to all other clients that the tool is equipped
for _, otherPlayer in pairs(game.Players:GetPlayers()) do
if otherPlayer ~= player then
toolAnimationEvent:FireClient(otherPlayer, action, player, tool.Name)
end
end
elseif action == “Unequipped” then
– Broadcast to all other clients that the tool is unequipped
for _, otherPlayer in pairs(game.Players:GetPlayers()) do
if otherPlayer ~= player then
toolAnimationEvent:FireClient(otherPlayer, action, player, tool.Name)
end
end
end
end)

And last, use this in StarterPlayerScripts:

local replicatedStorage = game:GetService(“ReplicatedStorage”)
local toolAnimationEvent = replicatedStorage:WaitForChild(“ToolAnimationEvent”)

toolAnimationEvent.OnClientEvent:Connect(function(action, player, toolName)
local character = player.Character
if character then
local tool = character:FindFirstChild(toolName)
if tool then
if action == “PlayAnimation” then

			local animation = tool:FindFirstChild("YourAnimation")
			if animation then
				local animator = tool:FindFirstChildOfClass("Animator")
				if animator then
					animator:LoadAnimation(animation):Play()
				end
			end
		elseif action == "Equipped" then
			
		elseif action == "Unequipped" then
			
		end
	end
end

end)

1 Like

Make sure to add the RemoteEvent inside ReplicatedStorage

1 Like

Updated:

Try this instead. (StarterCharacterScripts - LocalScript)

local Players = game:GetService(“Players”)
local ReplicatedStorage = game:GetService(“ReplicatedStorage”)
local ToolUsedEvent = ReplicatedStorage:WaitForChild(“ToolUsed”)

local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()

local tool = character:WaitForChild(“YourToolName”)
local animation = Instance.new(“Animation”)
animation.AnimationId = “rbxassetid://YourAnimationId”
local animator = character:WaitForChild(“Humanoid”):WaitForChild(“Animator”)

local function onToolActivated()
local animationTrack = animator:LoadAnimation(animation)
animationTrack:Play()
ToolUsedEvent:FireServer(player)
end

tool.Activated:Connect(onToolActivated)

ServerScriptService:

local ReplicatedStorage = game:GetService(“ReplicatedStorage”)
local Players = game:GetService(“Players”)
local ToolUsedEvent = ReplicatedStorage:WaitForChild(“ToolUsed”)

local function onToolUsed(player)
for _, otherPlayer in pairs(Players:GetPlayers()) do
if otherPlayer ~= player then
ToolUsedEvent:FireClient(otherPlayer, player)
end
end
end

ToolUsedEvent.OnServerEvent:Connect(onToolUsed)

(StarterCharacterScripts - LocalScript:)

local Players = game:GetService(“Players”)
local ReplicatedStorage = game:GetService(“ReplicatedStorage”)
local ToolUsedEvent = ReplicatedStorage:WaitForChild(“ToolUsed”)

local function onOtherPlayerToolUsed(player)
local character = player.Character or player.CharacterAdded:Wait()
local animation = Instance.new(“Animation”)
animation.AnimationId = “rbxassetid://YourAnimationId”
local animator = character:WaitForChild(“Humanoid”):WaitForChild(“Animator”)
local animationTrack = animator:LoadAnimation(animation)
animationTrack:Play()
end

ToolUsedEvent.OnClientEvent:Connect(onOtherPlayerToolUsed)

What is all this even supposed to do? I’d rather not just steal a bunch of code so can you elaborate the purpose of this

1 Like

Synchronize animations with tools across all clients in your game

1 Like

Does it synchronize my hands too?

Create an animation like idle. Then replicate that animation to the viewmodel while it plays on character.