Hello, I am currently trying to teach myself how to script and i stumbled upon this problem:
Whenever i press E, the animation plays but the hat does not go invisible
The following script is placed inside StarterCharacterScripts, and is a localscript
Heres my script:
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local hat = character:FindFirstChild("New SophisticatedAccessory")
local keybind = Enum.KeyCode.E
local function onInput(input, gameProcessed)
if gameProcessed then
return
end
if input.KeyCode == keybind then
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://12997870281"
local track = humanoid:LoadAnimation(animation)
track:Play()
if hat then
if hat.Transparency == 1 then
hat.Transparency = 0
else
hat.Transparency = 1
end
end
end
end
UserInputService.InputBegan:Connect(onInput)
I assume that hat in this case is an accessory and not a part
accessories themselves do not have a transparency property, it is the part inside them that is visible and has a transparency property.
If you look inside an accessory inside your character, youâll usually see a part named âHandleâ inside the accessory, thatâs the part that you have to edit.
local hatAccessory = character:FindFirstChild("New SophisticatedAccessory")
local hatPart = hatAccessory:FindFirstChild("Handle")
now you can make your hat invisible using hatPart.Transparency
furthermore. You probably already know this, but remember that local scripts only runs locally for the player and that other players will not see the hat disappear.
Ah okay, I have modified the code but now i get the error
âattempt to index nil with âFindFirstChildââ at line 9 which is:
local hatPart = hatAccessory:FindFirstChild(âHandleâ)
I donât see what the problem is as the hatAccessory is defined correct
âlocal hatAccessory = character:FindFirstChild(âNew SophisticatedAccessoryâ)â
hatAccessory might be defined correct, but it could still return nil if it canât find the first child with that name.
Where is the script located? If itâs in StarterPlayerScripts the script might load before the character does, causing it to read nothing as the hataccessory.
Also consider changing local hatAccessory = character:FindFirstChild(âNew SophisticatedAccessoryâ)
to local hatAccessory = character:WaitForChild(âNew SophisticatedAccessoryâ).
This helped a lot thx!
How would I make it so that other players can see the hat disappear? A normal script doesnât seem to do the job, so learning how to do this would greatly help me
In order for other players to see this you will have to use a server script at some point. Actions that server scripts perform are replicated to each client in the game. So you will have to use a server script. Can you send your attempt at trying to use a server script for making the hat disappear? It would be nice to have a point from which we can work with.
Depends, if you use an UI element you can use a server script directly linked to the UI element using MouseButton1Click:Connect(function), however this is not advised, since itâs easy to have yourself a severe security risk on your hands.
However, since you use UserInputService we will have to use a RemoteEvent to send a signal to the server.
You can decide to keep animation inside the client script since it bypasses the client-server barrier.
Lets put the RemoteEvent inside a folder which is inside ReplicatedStorage. Make a folder for events if you want to be tidy, since ReplicatedStorage can get pretty cluttered if you donât. Good practice to hold on to.
CLIENT:
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local hatAccessory = character:WaitForChild("New SophisticatedAccessory")
local hatPart = hatAccessory:FindFirstChild("Handle")
local hatEvent = ReplicatedStorage.EVENTFOLDER.REMOTEEVENT -- (change this)
local keybind = Enum.KeyCode.E
local function onInput(input, gameProcessed)
if gameProcessed then
return
end
if input.KeyCode == keybind then
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://12997870281"
local track = humanoid:LoadAnimation(animation)
track:Play()
-- send the hatPart instance through the remote event so we can use it on the server
hatEvent:FireServer(hatPart)
end
end
UserInputService.InputBegan:Connect(onInput)
SERVER:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local hatEvent = ReplicatedStorage.EVENTFOLDER.REMOTEEVENT -- (change this too)
-- catch Player, and the hatPart that we sent through. Important to keep the same order.
local function toggleHat(player: Player, hatPart: Instance)
-- IMPORTANT: make sure that the values after player are what you expect,
-- since exploiters can easily send any bogus value through remote events.
-- Which will brick your script or worse: give them an unfair advantage.
if not hatPart or not hatPart:IsA("Instance") then return end -- stop the script if a bogus value is entered.
if hatPart.Transparency == 1 then
hatPart.Transparency = 0
else
hatPart.Transparency = 1
end
end
-- on the server side of remote events the event will always return
-- the player that fired the event, following any other information you send through.
hatEvent.OnServerEvent:Connect(toggleHat)
I havenât tested this, but it should work. Hopefully the comments will guide you in how remote events work and good luck, if you want more help we can continue here or move somewhere where itâs easier to talk. Iâm more than happy to contact you somewhere else where I can continue to help you.