First post, so I apologize if anything something breaks convention in this post.
TL;DR: I need help replicating GUI tweening animations to all clients. The GUI is a BillboardGui attached to a part that floats around the player. These parts and associated GUIs are created/cloned server-side and are currently styled client-side. This obviously does not replicate the styling to all players and I am unsure on how to address this. Solutions or resources greatly appreciated, code snippets below.
Hello, I’m pretty inexperienced developer and have recently had the pleasure of having to worry about the replication of client happenings to the server. Resources I’ve seen so far on the forums don’t seem to address this particular problem, generally seeming to be about the tweening part’s movement, or I have missed some fundamental concepts from them.
My problem is this - I need to replicate the styling of BillboardGUIs to every player in the experience. These GUIs are currently created by the server as an attachment to a part and set to follow the player around like your average pet collection game. For that I avoided worrying about replicating the part movement by using attachments, align position, and setting the network ownership of the part to the player when the part is created/cloned server-side. This “solution” is not applicable here, and I want to avoid doing the animations/tweening server-side for performance and visual reasons. The solutions I’ve seen frequently make use of FireAllClients, though I do not see how that would function in this use case.
Server-Side Creation
local globalCat = game:GetService("ReplicatedStorage"):WaitForChild("GlobalCatFunction")
--other irrelevant functions and requirements
function CatManager.CreateCats(player)
local userId = player.UserId
--destroys all cats that exist in the workspace for that player
local cats = game.Workspace.Cats:FindFirstChild(userId):GetChildren()
for _, cat in cats do
cat:Destroy()
end
--currently used to style the cats locally
local copyCats = {}
--Fetches the player's information to be used for styling, the "cat" is a table of values needed for styling
local ECats = PlayerManager.GetEquippedCats(player)
for _, cat in ECats do
table.insert(copyCats, table.clone(cat))
local copyCat = game.ServerStorage.WorldCard:Clone()
--This parents the cat to a folder in the workspace, with the folder having child folders of that player's userid
copyCat.Parent = game.Workspace.Cats:FindFirstChild(userId)
copyCat.Position = player.Character.HumanoidRootPart.Position + Vector3.new(0, 3, 0)
--Basic styling using the ECats
copyCat:SetNetworkOwner(player)
end
return copyCats
end
--listens for the call from from the client
globalCat.OnServerInvoke = function(player)
return CatManager.CreateCats(player)
end
Client-Side Handling/Styling
local globalCat = game:GetService("ReplicatedStorage"):WaitForChild("GlobalCatFunction")
local GuiManager = require(ReplicatedStorage:WaitForChild("GuiManager"))
--other irrelevant functions, requirements
--fires from the module that handles player data on join and when a cat is equipped/unequipped
equipEvent.OnClientEvent:Connect(function()
--globalEvent:FireServer()
--currently required for the styling
local ecats = globalCatFun:InvokeServer()
task.wait(.1)
local cats = game.Workspace.Cats:WaitForChild(playerId):GetChildren()
--positioning logic
--primarily used for positioning the parts the gui is attached to
for i, cat in cats do
--currently styles and applies the animations for the gui, works great - locally :) not that I expected anything different
GuiManager.CreateWorldCard(ecats[i], cat.BillboardGui.GenCard)
--more positioning logic
end
end)
Replicated-Storage Styling Module that is Effectively a Local Script
--Animation module that requires it be run from a local script as it requires a PlayerGui for many functions and bricks otherwise. Very bad planning in hindsight and makes this module effectively local as a result.
local AnimationModule = require(game.StarterGui.ScreenGui:WaitForChild("AnimationModule"))
function GuiManager.CreateWorldCard(cat : cat, uiElement : SurfaceGui)
--crucial styling function that requires cat to be passed
local rarityArr = GuiManager.GetRarity(cat)
--more styling that requires the cat to be passed here
--uses the animation module multiple times, and is the primary reason for this post, just some tweening of gui elements under the hood.
GuiManager.AnimationByRarity(rarityArr, uiElement)
end
I apologize to all for having to have read that code and understand the structure, but that should be all relevant pieces. As for solutions - I have considered moving the GuiManager.AnimationByRarity Call to the the client-side script and then loop through all of the players in the cat folder and apply the animations through that, but this sounds both inefficient and impossible to implement due to the cat data being required for the styling.