So I have this customcharacter and when he eats a fly he will get bigger and that is visible to every player in the game.
However there is an issue where the customcharacter “teleports” somewhere when eating the fly. I understand why the issue occurs because I have read this devforum post Scaling the character makes it "teleport".
But I don’t know how I can fix it since its a custom character and I want it to be visible for the whole server.
Here is a video of the issue and a photo of how the character is built:
Here is the code that I made to handle the size of the custom character:
Size.Changed:Connect(function()
if Size.Value <= 200 then
Humanoid.WalkSpeed = (defaultWalkSpeed - Size.Value/10)
char:ScaleTo(1 + Size.Value/100)
Humanoid.JumpPower = 0
Points.Value = Size.Value
PointsLabel.Text = Size.Value
end
end)
What you mean by teleport is a lag that happens when you try to use a Serverscript to change humanoid scale. To get rid of the lag you should scale with a Localscript.
The first localscript that change the humanoid scale and does fireServer().
The server script does a FireAllClients() passing the player and scale
The second localscript receives the player, scale, and update if needed.
All humanoid.Scale changes are done with a Localscript. The local player by the 1st script and all the other connected players by the second script.
It has always been the rule, that anything applied to the character would replicate, but I haven’t tested it with new things like the Scale property. Sorry for the misleading advice.
This is the local script, it has all function no need to another script I am using the StaterCharacterScripts folder:
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local remoteEvent = game.ReplicatedStorage:WaitForChild("GrowScale") -- This event is the broadcast
-- This event get the broadcast of all players name and scale
local remoteEvent = game.ReplicatedStorage:WaitForChild("GrowScale")
remoteEvent.OnClientEvent:Connect(function(playerName, scaleValue)
-- print("Client Received GrowScale event on the client with playerName: " .. playerName .. " and scale: " .. scaleValue)
if game.Players.LocalPlayer.Name ~= playerName then
local Players = game:GetService("Players")
local player = Players:FindFirstChild(playerName)
if player then
--print("Player found: " .. player. Name)
local scaleCharacter = player. Character
scaleCharacter:ScaleTo(scaleValue) -- Change the scale for other players in the client
else
print("Player not found")
end
end
end)
-- This function broadcast to server the player name and model scale
function fireGrowScale (scaleValue)
local playerName = game.Players.LocalPlayer.Name
remoteEvent:FireServer(playerName, scaleValue)
end
-- This loop increase the player size if the player step on ice
while wait(1) do
if humanoid.FloorMaterial == Enum.Material.Ice then
print("Grow")
local growTo = character:GetScale()+0.01
character:ScaleTo(growTo) -- Change scale
fireGrowScale(growTo) -- Broadcast scale
end
end
Now the server script:
local remoteEvent = Instance.new("RemoteEvent")
remoteEvent.Name = "GrowScale"
remoteEvent.Parent = game.ReplicatedStorage
remoteEvent.OnServerEvent:Connect(function(player, playerName, scaleValue)
-- print(player.Name .. " triggered the GrowScale event with playerName: " .. playerName .. " and scale: " .. scaleValue)
remoteEvent:FireAllClients(playerName, scaleValue)
end)
I did some tests and the scale propagate fine. If you need extra help to adapt to your code you can ask.
So In my existing script i should fire to the client, change the size client sided, fire back to the server and make it fire all clients?? sorry i don’t really understand lol. The script that i showed is part of my “PlayerHandler” server script. What should i do from there… Fire all clients? And why the check for if the humanoid is walking on ice?
This is local-script. But I dont know how you initiate the Size variable.
-- This is a localscript
local remoteEvent = game.ReplicatedStorage:WaitForChild("GrowScale") -- Broadcast event
-- This will tell the server the Name of the player and his scale
function fireGrowScale (playerName,scaleValue)
remoteEvent:FireServer(playerName, scaleValue)
end
-- This receive the scale of other players and update local
local remoteEvent = game.ReplicatedStorage:WaitForChild("GrowScale")
remoteEvent.OnClientEvent:Connect(function(playerName, scaleValue)
if game.Players.LocalPlayer.Name ~= playerName then
local Players = game:GetService("Players")
-- Find the player, from the name sent by server
local player = Players:FindFirstChild(playerName)
if player then
local scaleCharacter = player. Character
-- Set scale that was passed by the server
scaleCharacter:ScaleTo(scaleValue)
end
end
end)
-- Must be localscript code :
Size.Changed:Connect(function()
if Size.Value <= 200 then
Humanoid.WalkSpeed = (defaultWalkSpeed - Size.Value/10)
char:ScaleTo(1 + Size.Value/100)
-- Get the Playername
local playerNameToSend = game.Players.LocalPlayer.Name
-- Tell the server Player and Scale
fireGrowScale(playerNameToSend, char:GetScale())
Humanoid.JumpPower = 0
Points.Value = Size.Value
PointsLabel.Text = Size.Value
end
end)
You need to add this script inside ServerScriptService folder:
local remoteEvent = Instance.new("RemoteEvent")
remoteEvent.Name = "GrowScale"
remoteEvent.Parent = game.ReplicatedStorage
remoteEvent.OnServerEvent:Connect(function(player, playerName, scaleValue)
-- print(player.Name .. " triggered the GrowScale event with playerName: " .. playerName .. " and scale: " .. scaleValue)
remoteEvent:FireAllClients(playerName, scaleValue)
end)
You must understand that the event that trigger the character size increase must be local.
So if i understnad correctly, I should add this code into my server script:
local remoteEvent = Instance.new("RemoteEvent")
remoteEvent.Name = "GrowScale"
remoteEvent.Parent = game.ReplicatedStorage
remoteEvent.OnServerEvent:Connect(function(player, playerName, scaleValue)
-- print(player.Name .. " triggered the GrowScale event with playerName: " .. playerName .. " and scale: " .. scaleValue)
remoteEvent:FireAllClients(playerName, scaleValue)
end)
Then create a new local script with this code
-- This is a localscript
local remoteEvent = game.ReplicatedStorage:WaitForChild("GrowScale") -- Broadcast event
-- This will tell the server the Name of the player and his scale
function fireGrowScale (playerName,scaleValue)
remoteEvent:FireServer(playerName, scaleValue)
end
-- This receive the scale of other players and update local
local remoteEvent = game.ReplicatedStorage:WaitForChild("GrowScale")
remoteEvent.OnClientEvent:Connect(function(playerName, scaleValue)
if game.Players.LocalPlayer.Name ~= playerName then
local Players = game:GetService("Players")
-- Find the player, from the name sent by server
local player = Players:FindFirstChild(playerName)
if player then
local scaleCharacter = player. Character
-- Set scale that was passed by the server
scaleCharacter:ScaleTo(scaleValue)
end
end
end)
-- Must be localscript code :
Size.Changed:Connect(function()
if Size.Value <= 200 then
Humanoid.WalkSpeed = (defaultWalkSpeed - Size.Value/10)
char:ScaleTo(1 + Size.Value/100)
-- Get the Playername
local playerNameToSend = game.Players.LocalPlayer.Name
-- Tell the server Player and Scale
fireGrowScale(playerNameToSend, char:GetScale())
Humanoid.JumpPower = 0
Points.Value = Size.Value
PointsLabel.Text = Size.Value
end
end)
And then in the server when the size change is supposed to be initiated i should fireclient?
Btw this is how i have the size variable:
Players.PlayerAdded:Connect(function(plr)
plr.CharacterAdded:Connect(function(char)
local plr = game:GetService("Players"):GetPlayerFromCharacter(char)
local leaderstats = plr:WaitForChild("leaderstats")
local Size = leaderstats:WaitForChild("Size")
--Here in between code for something else
Size.Changed:Connect(function()
if Size.Value <= 200 then
Humanoid.WalkSpeed = (defaultWalkSpeed - Size.Value / 10)
char:ScaleTo(1 + Size.Value / 100)
end
Humanoid.JumpPower = 0
Points.Value = Size.Value
PointsLabel.Text = Size.Value
end)
--Rest of the code
Or do i need to change that piece of code and do it in a local script and from there fire server?
Now create a new localscript inside StarterPlayer:
local remoteEvent = game.ReplicatedStorage:WaitForChild("GrowScale")
remoteEvent.OnClientEvent:Connect(function(theSize, theChar)
print("Got char:",theChar)
print("Got size:",theSize)
if theSize <= 200 then
theChar:ScaleTo(1 + theSize/100)
end
end)
Not the correct solution, but moving the ScaleTo to localscript, may be a solution.
The character killing and eating are in the server script. I made a max eat dist and Fov function and it just loop through the players and all the flies and checks how close the distance is between the fly/enemyplayer and the player and if its less than the eatDist and in the FOV.