I’m currently working on a bee swarm simulator inspired game and so far I have been focusing on programming the bee movement using movement interpolation and proper networking. This is my first time doing something like this so I would like to get some improvement suggestions to make it more optimised and stable.
Server script
local PLAYERS = game:GetService("Players")
local REPLICATED_STORAGE = game:GetService("ReplicatedStorage")
local function createBee(player, hrp, folder)
local Bee = game.ReplicatedStorage.Bee:Clone()
Bee.Parent = folder
Bee.CFrame = hrp.CFrame
return Bee
end
local function spawnBees(player, hrp, folder, number)
for _, v in pairs(folder:GetChildren()) do
v:Destroy()
end
for i = 1, number or 10, 1 do
createBee(player, hrp, folder)
end
task.wait(0.5)
REPLICATED_STORAGE.IdleBees:FireAllClients(player, folder:GetChildren())
end
PLAYERS.PlayerAdded:Connect(function(player) -- this function is just here for testing it will probably get moved later on for organisation
player:SetAttribute("State", "Idle") -- the state doesn't really do anything yet but as I add more features to bees it will
local BeeFolder = Instance.new("Folder", workspace); BeeFolder.Name = "Bees_"..player.Name
local character = player.Character or player.CharacterAdded:Wait()
local humanoidRootPart = character.HumanoidRootPart
local Humanoid = character.Humanoid
--spawnBees(player, humanoidRootPart, BeeFolder)
end)
REPLICATED_STORAGE.BeeDestinationReached.OnServerEvent:Connect(function(player, bee, endGoal)
local character = player.Character
local HumanoidRootPart = character:WaitForChild("HumanoidRootPart")
local distance = (HumanoidRootPart.Position - bee.Position).Magnitude
bee.CFrame = HumanoidRootPart.CFrame.Rotation + endGoal
if distance < 15 then -- if the player is close for the bees allow the bees to wait a bit before moving randomly again
task.wait(math.random(1, 7))
else -- if not the bees have no time to waste and have to move and catch up to the player
task.wait()
end
REPLICATED_STORAGE.MoveBee:FireAllClients(player, bee, player:GetAttribute("State"))
end)
REPLICATED_STORAGE.SpawnBees.OnServerEvent:Connect(spawnBees)
Client Script
local RUN_SERVICE = game:GetService("RunService")
local REPLICATED_STORAGE = game:GetService("ReplicatedStorage")
local PLAYERS = game:GetService("Players")
local Player = PLAYERS.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
local TEST_BEE_SPEED = 10
local function getRandomPos(origin)
local posX = math.random(-25, 25)
local posZ = math.random(-25, 25)
local newPosition = origin.Position + Vector3.new(posX, 0, posZ)
return newPosition
end
local function performMovement(bee, newPosition, speed)
local StartPosition = bee.Position
local difference = (StartPosition - newPosition)
local distance = difference.Magnitude
local direction = difference.Unit
local duration = distance / speed
local connection
local alpha = 0
connection = RUN_SERVICE.RenderStepped:Connect(function(delta)
if not bee then connection:Disconnect() return end -- mightve been destroyed
alpha = math.clamp(alpha + (speed * delta) / distance, 0, 1)
bee.Position = StartPosition:Lerp(newPosition, alpha)
bee.CFrame = CFrame.lookAlong(bee.Position, -direction)
if alpha >= 1 then
connection:Disconnect()
REPLICATED_STORAGE.BeeDestinationReached:FireServer(bee, newPosition)
end
end)
end
local function compute(player, bee)
local hrp = player.Character.HumanoidRootPart
local newPosition
if player:GetAttribute("State") == "Idle" then
newPosition = getRandomPos(hrp)
end
performMovement(bee, newPosition, TEST_BEE_SPEED)
end
REPLICATED_STORAGE:WaitForChild("IdleBees").OnClientEvent:Connect(function(player, bees)
warn(bees)
for _, bee in bees do
compute(player, bee, player:GetAttribute("State"))
end
end)
REPLICATED_STORAGE:WaitForChild("MoveBee").OnClientEvent:Connect(compute)
Thanks for reading be sure to drop your feedback below!