Hello! This is my second topic / post on the dev forum, so apoligies if I do anything wrong. So, I will get straight to the point. My script will not delete / destroy the items in my player’s character.
Here is the code that I have set up:
function destroy_Hats(char)
print("Starting to Destroy things in Character.")
for i,v in pairs(char:GetChildren()) do
if v:IsA("Hat") then
v:Destroy()
print("Removed: "..v.Name)
elseif v:IsA("CharacterMesh") then
v:Destroy()
print("Removed: "..v.Name)
elseif v:IsA("BodyColors") then
v:Destroy()
print("Removed: "..v.Name)
elseif v:IsA("Shirt") then
v:Destroy()
print("Removed: "..v.Name)
elseif v:IsA("Pants") then
v:Destroy()
print("Removed: "..v.Name)
elseif v:IsA("ShirtGraphic") then
v:Destroy()
print("Removed: "..v.Name)
elseif v:IsA("Accessory") then
v:Destroy()
print("Removed: "..v.Name)
end
end
end
game.Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(char)
local folder = player:WaitForChild("Items")
local charValue = folder:WaitForChild("Character")
if charValue.Value ~= "Default Avatar" then
destroy_Hats(char)
-- There is more to my code, and that part works. The destroy_Hats() function does not work.
end
end)
end)
I did include some deprecated things such as Hats because I had no clue why stuff wasn’t disappearing.
THINGS TO NOTE:
The script is a server script in ServerScriptService
charValue.Value IS Default Avatar.
In destroy_Hats(), the first print statement prints. (Starting to destroy things in character.)
BTW, the other part of my code is a function that adds accessories from a folder in replicated storage into the character.
It does not print anything at all. Maybe the for loop isn’t working / starting?
The only things in the output / dev console is the prints from other scripts I have.
EDIT: I tried again, and this time the print ran. It prints all the parts in my players character and all of the names of the scripts in the character. It seems to work when I respawn but not when my character gets added for the first time.
CharacterAdded seems to fire “too early”, too early that the character has no children yet. You could try waiting a heartbeat (RunService.Heartbeat:Wait()) before continuing.
Your destroy_Hats function is also a mess! Take advantage of the fact that all those classes inherit from CharacterAppearance. While Hats and Accessories don’t, they inherit from Accoutrement. Roblox doesn’t use Hats anymore though.
local function destroy_hats(char)
print("Starting to Destroy things in Character.")
for _, v in pairs(char:GetChildren()) do
if v:IsA("CharacterAppearance") or v:IsA("Accoutrement") then
v:Destroy()
print("Removed", v)
end
end
end
Using a standard wait(x) will not be reliable enough, instead wait for HumanoidRootPart.
game.Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(char)
char:WaitForChild("HumanoidRootPart")
local folder = player:WaitForChild("Items")
local charValue = folder:WaitForChild("Character")
if charValue.Value ~= "Default Avatar" then
destroy_Hats(char)
-- There is more to my code, and that part works. The destroy_Hats() function does not work.
end
end)
end)
Back to square one, this time with another issue… whenever I join the game, I still have my normal character. Also, when I reset, it still doesn’t work. While the value has the custom outfit, it only loads it when I use player:LoadCharacter(). Also, the items in my character still aren’t going away.
I have no idea why nobody mentioned this in any of the replies but you can just switch CharacterAdded with CharacterAppearanceLoaded event so you can be sure that player character is fully loaded when function is called instead of using unrealiable methods like using wait() or anything that is a variation of wait():
Hey! It works! It only works though when I call the player:LoadCharacter() event. Otherwise, the script never even fires… If I reset before I call the event, It still doesn’t work. Reseting only works if I have already called player:LoadCharacter().
I call the player:LoadCharacter() event by pressing a gui button.
Interesting, that means script is not passing the if charValue.Value ~= "Default Avatar" then check. Can you talk a bit more about that charValue in that folder inside player’s character?
Sure. I have a separate script that handles making the folder + values inside of it. It also handles saving for all of those items. I think what is happening is that the script is running before the datastore can set the value to what it actually is.Therefore, the value IS actually Default Avatar because that is the value I set it to when the value is created (this way, it won’t bug out for new players). Is there a way I can wait for the player’s data to load before I run the script?
I mean, parenting the folder to character after actually getting the data from datastore and changing the stringvalue’s value should work just fine. Though I want to know how you implemented this system in your code.
I don’t really know how I would do that without breaking something else, so I will just give you my datastore’s code. It isn’t efficient and it is a bit messy, but I am happy with it because it works. I know I could just be using tables to save large amounts of data but I have no clue how to do that. I can give you the first part, which loads the data. The saving part shouldn’t be needed.
local DataStoreService = game:GetService("DataStoreService")
local myDataStore = DataStoreService:GetDataStore("DataSave4")
game.Players.PlayerAdded:Connect(function(player)
local folder = Instance.new("Folder")
folder.Parent = player
folder.Name = "Items"
local knife = Instance.new("StringValue")
knife.Parent = folder
knife.Name = 'Knife_Skin'
knife.Value = "Default"
local gun = Instance.new("StringValue")
gun.Parent = folder
gun.Name = 'Gun'
gun.Value = "Stock Revolver"
local knife_effect = Instance.new("StringValue")
knife_effect.Parent = folder
knife_effect.Name = 'Knife_Effect'
knife_effect.Value = "Default"
local char = Instance.new("StringValue")
char.Parent = folder
char.Name = 'Character'
char.Value = "Default Avatar"
local knifeskin,gunskin,knife_effect_,character
local success, errormessage = pcall(function()
knifeskin = myDataStore:GetAsync(player.UserId.."-knife_skin")
print(knifeskin)
gunskin = myDataStore:GetAsync(player.UserId.."-gun_skin")
print(gunskin)
knife_effect_ = myDataStore:GetAsync(player.UserId.."-knife_effect")
print(knife_effect_)
character = myDataStore:GetAsync(player.UserId.."-char")
print(character)
end)
if success then
if knifeskin then
knife.Value = knifeskin
gun.Value = gunskin
knife_effect.Value = knife_effect_
end
else
warn(errormessage)
print("There was an error getting your items.")
end
end)
Sorry for keep you waiting for this long but you can fix this by moving the folder.Parent = player part to the end of function and you also forgot to set the character in your script after getting the data from datastore.
if success and knifeskin then
knife.Value = knifeskin
gun.Value = gunskin
knife_effect.Value = knife_effect_
char.Value = character or "Default Avatar"
else
warn(errormessage)
print("There was an error getting your items.")
end
folder.Parent = player
end)
I already thought of a solution, but thank you! If you are wondering, I made a separate datastore for the player’s character / outfit. I also moved the code for setting the value and creating to the character script. It works perfectly now, and thank you to everyone else who helped