game.ReplicatedStorage.EventsAndValues.Emote.OnServerEvent:Connect(function(player, Emote)
local Character = player.Character
local Values = game.ServerStorage.Emotes:FindFirstChild(Emote)
if not Data[player].EmoteData[Data] then
if not Values then return end
local val = Values:FindFirstChildOfClass("IntValue").Value
if player.leaderstats.Bits.Value >= val then
player.leaderstats.Bits.Value = player.leaderstats.Bits.Value - val
Good:Play()
else
print("Not enough!")
Bad:Play()
return
end
Data[player].EmoteData[Emote] = true
end
player:LoadCharacter()
local Character = player.Character
local Emote = Values
local clonedemote = Emote:Clone()
clonedemote.Name = Emote.Name
clonedemote.Parent = Character
end)
I have basically the same exact script for walking animations and trails and they work fine, this one buys but it doesn't save so you don't have to buy over and over again, I'm assuming I made a minor mistake that just causes it not to work, I have a module script that handles the data. Which would be this
local Store = DSS:GetDataStore(SERVER_STORE)
local DEFAULT_DATA = {
-- Change these up as you wish
Bits = 0;
Wins = 0;
TrailData = {};
EmoteData = {};
AnimationData = {};
--[[
INSERTING A DEFAULT VALUE:
YourStatNameHere = "Default Value Here";
-- Don't forget the semicolon (;) at the end!
To remove a value, simply remove the line that has that value!
]]--
-- Important Value, if this value is removed the entire datastore will break!
UpdateId = 0;
}
--[[
/// BEFORE YOU MOVE ON ///
The following is a short description of what happens (in order):
1. Player Data is retrieved and saved.
2. All data is retrieved using DataHandler:CheckStat() and updated using DataHandler:Update().
3. When player leaves, data is automatically saved and cached.
4. When server closes, all player data is saved quickly and efficiently.
]]--
-- Checks if the game is running in Studio or not
if Run:IsStudio() then
Store = DSS:GetDataStore(TEST_STORE)
end
-- START OF MODULE
local DataHandler = {}
-- Way more accurate than wait(number)
function DataHandler:AccuWait(n)
local t = tick()
while true do
if tick()-t >= n-0.005 then
return
end
Run.Stepped:Wait()
end
end
function DataHandler:CheckForInconsistencies(Data)
for Name, Val in pairs(DEFAULT_DATA) do
if not Data[Name] then
Data[Name] = Val
end
end
for Name, _ in pairs(Data) do
if not DEFAULT_DATA[Name] then
Data[Name] = nil
end
end
return Data
end
-- Gets and stores the player data
function DataHandler:Init(Player)
for i = 1, MAX_RETRIES do
local Success, Val = pcall(function()
return Store:GetAsync(Player.UserId) or DEFAULT_DATA
end)
if Success then
local Data = DataHandler:CheckForInconsistencies(Val)
if CREATE_LEADERSTATS then
local Leaderstats = Instance.new("Folder")
Leaderstats.Name = "leaderstats"
Leaderstats.Parent = Player
for Name, Val in pairs(Data) do
if Name == "UpdateId" then
continue
end
if type(Val) == "number" then
local newVal = Instance.new("IntValue")
newVal.Name = Name
newVal.Value = Val
newVal.Parent = Leaderstats
Data[Name] = nil
end
end
end
return Data
end
if DataHandler:GetReq("GetAsync") <= 5 then
DataHandler:AccuWait(7)
end
DataHandler:AccuWait(3)
end
end
-- Save player data
function DataHandler:Save(Player, Data)
for i = 1, MAX_RETRIES do
local Success, ErrorMessage = pcall(function()
Store:UpdateAsync(Player.UserId, function(OldData)
if not OldData or OldData.UpdateId == Data.UpdateId then
Data.UpdateId = Data.UpdateId + 1
return Data
end
return nil
end)
end)
if Success then
return
end
warn("Data was not saved! " .. ErrorMessage)
DataHandler:AccuWait(3)
end
end
-- Useful function that erases player data
-- For example, it can be used if a player wants to restart their game.
function DataHandler:Erase(Player)
for i = 1, 3 do
local Success = pcall(Store.RemoveAsync, Player.UserId)
if Success then
DataHandler[Player.UserId] = DEFAULT_DATA
return
end
if DataHandler:GetReq("RemoveAsync") <= 5 then
DataHandler:AccuWait(7)
end
DataHandler:Accuwait(3)
end
end
return DataHandler
-- [[ END OF MODULE ]] --
Again, the Trails and Animations work fine
