I created a 2D sprite character system for a top-down 2D game I’m working on. Everything works as expected and the character system replicates across clients correctly. But I’m concerned that it might cause too much lag on the server, especially if theres multiple players.
heartbeat = game:GetService("RunService").Heartbeat:Connect(function()
local root = char:FindFirstChild("HumanoidRootPart")
if root then
updateSpritePosition(char, CharacterModel, root)
end
end)
Inside the movement script, there’s a function that uses a heartbeat connection to continuously update the sprite. This works well for a small number of players, but because the updateSpritePosition
function involves several calculations, it could lead to performance issues as the player count increases.
Here is the updateSpritePosition
function:
if root then
-- Update the position of the character model to follow the root part's X and Z position
CharacterModel.Position = Vector3.new(root.Position.X, 0.003, root.Position.Z)
-- Get the direction the player is facing
local facingDirection = root.CFrame.LookVector
local angle = math.deg(math.atan2(facingDirection.X, facingDirection.Z))
local directions = {"Right", "UpRight", "Up", "UpLeft", "Left", "DownLeft", "Down", "DownRight"}
-- Normalize the angle to fall between 0 and 360 degrees
angle = (angle + 360) % 360
-- Find the index of the direction based on the angle
local directionIndex = math.floor((angle + 22.5) / 45) % 8 + 1
local direction = directions[directionIndex]
-- Update the X and Y indices based on the direction
local XIndex = SpriteData.XAxis.DirectionXIndex[direction]
local YIndex = SpriteData.YAxis.MovementFrameYs[1]
-- Calculate the X and Y offsets for the sprite sheet
local spriteXOffset = XIndex * SpriteData.XAxis.XMultiplier
local spriteYOffset = YIndex
local velocity = root.Velocity
local velocityMagnitude = velocity.Magnitude
-- Check if the player is moving or idle based on velocity magnitude. Also checks if the character model still exists to prevent errors
if velocityMagnitude > movementThreshold and CharacterModel then
if CharacterModel:FindFirstChild("SurfaceGui") then
local currentTime = tick()
local frameIndex = math.floor(currentTime * 6) % 2 + 1
local spriteYOffset = SpriteData.YAxis.MovementFrameYs[frameIndex]
local spriteXOffset = SpriteData.XAxis.DirectionXIndex[direction] * SpriteData.XAxis.XMultiplier
CharacterModel.SurfaceGui.ImageLabel.ImageRectOffset = Vector2.new(spriteXOffset, spriteYOffset)
end
else
if CharacterModel:FindFirstChild("SurfaceGui") then
local spriteXOffset = SpriteData.XAxis.DirectionXIndex[direction] * SpriteData.XAxis.XMultiplier
local spriteYOffset = SpriteData.YAxis.IdleFrameY
CharacterModel.SurfaceGui.ImageLabel.ImageRectOffset = Vector2.new(spriteXOffset, spriteYOffset)
end
end
else
if game:GetService("RunService"):IsClient() then
heartbeat:Disconnect() -- Disconnect the heartbeat connection if no root found
end
return
end
end
I tried making other player’s movement and sprite animations run on the client using remote events, but everything I’ve tried causes the entire character replications to break.