basically, i created a script for my game “escape from florida” that would hopefully optimize the performance of obstacles and their spawning mechanics as previous versions of my game relied on several unecessary copies and clones of scripts instead of one centralized manager. this obstacle manager seemed to work for a while (even with the cons being that obstacles no longer damage you in the way that i originally intended), but then mysteriously cut out and made obstacles lag down their physics calculations to about a frame per second. i tried to use :clearallchildren() in order to clean up obstacles when their count reached over 100, but that only led to them being cleared very frequently and making the overall experience unenjoyable. ive left a copy of my script down below. any ideas for how to fix both the slowed calculations and make the damage work by a singular touch and not a frame check?
p.s.
i left the link to the game down below. check it out live if that helps:
local RS = game:GetService("ReplicatedStorage")
local RunS = game:GetService("RunService")
local TS = game:GetService("TweenService")
local DS = game:GetService("Debris")
local spawn_area = script.Parent
local spawners = spawn_area.Parent
local main_map = spawners.Parent
local florida = main_map.Parent
local spawned_obstacles = florida:WaitForChild("spawned obstacles")
local obstacle_delete_Y = workspace.FallenPartsDestroyHeight
local obstacles = RS:WaitForChild("obstacles")
local fireball = obstacles:WaitForChild("fireball")
local gator = obstacles:WaitForChild("gator")
local palm_tree = obstacles:WaitForChild("palm_tree")
local fireball_tick = 0.1
local gator_tick = 0.1
local palm_tree_tick = 0.1
local set_fireball_tick = 0.12
local set_gator_tick = 1.25
local set_palm_tree_tick = 10
RunS.Heartbeat:Connect(function(delta_time)
if fireball_tick > 0 then
fireball_tick -= delta_time
if fireball_tick <= 0 then
fireball_tick = set_fireball_tick
spawnobstacle(fireball,10,spawn_area,1,true,true)
end
else
fireball_tick = set_fireball_tick
--spawnobstacle(fireball,60,spawn_area,30)
end
if gator_tick > 0 then
gator_tick -= delta_time
if gator_tick <= 0 then
gator_tick = set_gator_tick
spawnobstacle(gator,10,spawn_area,2.5,true,true)
end
else
gator_tick = set_gator_tick
--spawnobstacle(gator,60,spawn_area,75)
end
if palm_tree_tick > 0 then
palm_tree_tick -= delta_time
if palm_tree_tick <= 0 then
palm_tree_tick = set_palm_tree_tick
spawnobstacle(palm_tree,15,spawn_area,5,true,false)
end
else
palm_tree_tick = set_palm_tree_tick
--spawnobstacle(palm_tree,60,spawn_area,100)
end
for i,obstacle in pairs(spawned_obstacles:GetChildren()) do
obstacle_damage = nil
obstacle_sit_bool = nil
if obstacle:IsA("Part") or obstacle:IsA("MeshPart") or obstacle:IsA("BasePart") or obstacle:IsA("WedgePart") or obstacle:IsA("TrussPart") or obstacle:IsA("PartOperation") then
--print("recognized "..obstacle.Name.." as an obstacle")
if obstacle:FindFirstChild("damage") then
if obstacle:FindFirstChild("damage"):IsA("NumberValue") then
obstacle_damage = obstacle:FindFirstChild("damage").Value
else
obstacle_damage = nil
end
end
if obstacle:FindFirstChild("sit") then
if obstacle:FindFirstChild("sit"):IsA("BoolValue") then
obstacle_sit_bool = obstacle:FindFirstChild("sit").Value
else
obstacle_sit_bool = nil
end
end
obstacle.Touched:Connect(function(otherpart)
if otherpart then
if otherpart.Parent:FindFirstChildOfClass("Humanoid") then
--print("obstacle "..obstacle.Name.." hit character "..otherpart.Parent.Name)
local touched_humanoid = otherpart.Parent:FindFirstChildOfClass("Humanoid")
if obstacle_damage then
touched_humanoid.Health -= obstacle_damage
else
touched_humanoid.Health -= 0.00001
end
if obstacle_sit_bool then
if obstacle_sit_bool == true then
touched_humanoid.Sit = true
else
end
end
else
--print("obstacle "..obstacle.Name.." hit part "..otherpart.Name)
end
end
end)
if obstacle.Position.Y <= obstacle_delete_Y + 10 then
if obstacle then
DS:AddItem(obstacle,0)
end
if obstacle then
obstacle:Destroy()
end
end
--if i%100==0 then
-- print("obstacle "..obstacle.Name.." is number "..i.." of this check at "..time().." since start of simulation")
--end
if i>100 then
print("attempting full wipe on "..spawned_obstacles.Name)
spawned_obstacles:ClearAllChildren()
end
end
end
end)
function spawnobstacle(obstacle,debristime,spawnpart,damage,sit_on_hit,random_rotation)
local selected_spawn_position = spawnpart.Position + Vector3.new(math.random(-spawnpart.Size.X/2, spawnpart.Size.X/2),math.random(-spawnpart.Size.Y/2, spawnpart.Size.Y/2),math.random(-spawnpart.Size.Z/2, spawnpart.Size.Z/2))
local obstacle_clone = obstacle:Clone()
obstacle_clone.Parent = spawned_obstacles
if obstacle_clone.ClassName == "Part" or obstacle_clone.ClassName == "MeshPart" then
if random_rotation then
obstacle_clone.Rotation = Vector3.new(
math.random(0,360),
math.random(0,360),
math.random(0,360)
)
end
obstacle_clone.Anchored = false
obstacle_clone.Position = selected_spawn_position
local damage_value = Instance.new("NumberValue",obstacle_clone)
damage_value.Value = damage
damage_value.Name = "damage"
local sit_bool = Instance.new("BoolValue",obstacle_clone)
if sit_on_hit then
sit_bool.Value = true
else
sit_bool.Value = false
end
sit_bool.Name = "sit"
end
end