Hi, I need to create a mechanism that continuously updates an event, so that when a player buys or equips a weapon, the writing on it changes, and if the player switches the equipped weapon from one to another, the writing on the weapon that is no longer equipped changes, and instead of remaining “Selected” it becomes “Owned”.
This is what I tried, but this line result:GetPropertyChangedSignal():Connect(function(), instead of solving the issue, seems to mess up
this is what I have so far:
frame.Button.MouseButton1Click:Connect(function()
print(v.Name)
local result = game.ReplicatedStorage.Buy:InvokeServer(v.Name,"weapon")
result:GetPropertyChangedSignal():Connect(function()
if result == "equipped" then
for i, object in pairs(weapons.Folder:GetChildren()) do
if object:IsA("Frame") and object:FindFirstChild("Cost") then
if game.Players.LocalPlayer.Inventory:FindFirstChild(object.Name) then
object.Cost.Text = "Owned"
end
end
end
frame.Cost.Text = "Selected"
elseif result == "bought" or result ~= "equipped" then
frame.Cost.Text = "Owned"
end
end)
end)
:GetPropertyChangedSignal() needs to know which property you are referring to for example :GetPropertyChangedSignal(“Parent”) - The event would now fire every time the parent has changed.
I’m not sure what the server is returning to local result but if it’s returning the tool then you could just use result.Equipped:Connect() instead of the :GetPropertyChanged.
It looks like you’re on the right track, but there are a few issues with the code you provided that might be causing problems. Here are a few suggestions:
Check that result is the correct datatype: result might not always be a StringValue which is required for GetPropertyChangedSignal() to work. You can add a check to make sure that result is indeed a StringValue before connecting to its property changed signal.
Disconnect from the signal when the frame is no longer visible: If you don’t disconnect from the signal when the frame is no longer visible, it could cause problems with performance or memory usage. You can disconnect from the signal when the frame is destroyed or made invisible.
Move the check for ownership outside of the property changed signal: Since the result variable will only change when the weapon is equipped, you can move the check for ownership outside of the property changed signal. This will make the code cleaner and more efficient.
Here’s some updated code that takes these suggestions into account:
frame.Button.MouseButton1Click:Connect(function()
print(v.Name)
local result = game.ReplicatedStorage.Buy:InvokeServer(v.Name,"weapon")
-- check that result is a StringValue before connecting to its property changed signal
if typeof(result) == "Instance" and result:IsA("StringValue") then
local connection
connection = result:GetPropertyChangedSignal("Value"):Connect(function()
if result.Value == "equipped" then
-- move the check for ownership outside of the property changed signal
local owned = game.Players.LocalPlayer.Inventory:FindFirstChild(v.Name)
for i, object in pairs(weapons.Folder:GetChildren()) do
if object:IsA("Frame") and object:FindFirstChild("Cost") then
object.Cost.Text = owned and "Owned" or "Cost"
end
end
frame.Cost.Text = "Selected"
elseif result.Value == "bought" or result.Value ~= "equipped" then
frame.Cost.Text = "Owned"
end
end)
-- disconnect from the signal when the frame is destroyed or made invisible
frame.AncestryChanged:Connect(function()
if not frame:IsDescendantOf(game) then
connection:Disconnect()
end
end)
end
end)
Note that I’ve also added a check to make sure that result is a valid instance before connecting to its property changed signal. This is important because InvokeServer() might not always return a valid instance.
I hope this helps! Let me know if you have any further questions.
game.ReplicatedStorage.Buy.OnServerInvoke = function(player,itemname,itemtype)
local item
local inInventory
if(itemtype == "weapon") then
item = game.ReplicatedStorage.Weapons:FindFirstChild(itemname)
if player.WeaponInventory:FindFirstChild(item.Name) then
inInventory = true
end
end
if item then
if item:FindFirstChild("Cost") then
if not inInventory then
if item.Cost.Value <= player.Coins.Value then
player.Coins.Value = player.Coins.Value - item.Cost.Value
local stringValue = Instance.new("StringValue")
stringValue.Name = item.Name
if itemtype == "weapon" then
stringValue.Parent = player.Inventory
end
return "bought"
else
return "failed"
end
else
if itemtype == "weapon" then
player.EquippedWeapon.Value = itemname
end
return "equipped"
end
end
else
print("No skin found")
return "failed"
end
end
i recommend using other methods of getting data, u might wanna rework the whole script and instead just make a function in localscript that resets the info and put the new info when OnClientEvent instead of always checking which takes more resources in computer power