Last active
January 3, 2022 21:00
-
-
Save katsaii/05a405ed4f5aca2c068042c07fa2cbc6 to your computer and use it in GitHub Desktop.
A script for Roblox games that spawns parts within regions defined by `Start` and `End` controlpoints
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local manager = script.Parent | |
-- helper function for colliding with humanoids | |
local function TouchedHumanoid(f) | |
return function(collider) | |
local parent = collider.Parent | |
if parent:FindFirstChildWhichIsA("Humanoid") then | |
f(parent) | |
end | |
end | |
end | |
-- track button state | |
local enabled = false | |
local button = manager.ButtonToggle | |
local pause = false | |
local function UpdateButtonState() | |
if enabled then | |
print("ENABLE: " .. manager.Name) | |
button.BrickColor = BrickColor.new("Dark green") | |
else | |
print("DISABLE: " .. manager.Name) | |
button.BrickColor = BrickColor.new("Tr. Red") | |
end | |
end | |
UpdateButtonState() | |
button.Touched:Connect(TouchedHumanoid(function(player) | |
if pause then | |
return | |
end | |
pause = true | |
enabled = not enabled | |
UpdateButtonState() | |
wait(1) -- second | |
pause = false | |
end)) | |
-- loop through all regions we need to spawn particles for | |
local regions = { } | |
local mag_total = 0 | |
for i, model in ipairs(manager.Regions:GetChildren()) do | |
-- set each region to be invisible to players | |
for _, child in ipairs(model:GetChildren()) do | |
child.CanCollide = false | |
child.Anchored = true | |
child.CanTouch = false | |
child.Transparency = 1.0 | |
end | |
-- calculate region data | |
local pos_start = model.Start.Position | |
local pos_end = model.End.Position | |
local mag = (pos_end - pos_start).Magnitude | |
regions[i] = { | |
Part = model, | |
MinPos = Vector3.new( | |
math.min(pos_start.X, pos_end.X), | |
math.min(pos_start.Y, pos_end.Y), | |
math.min(pos_start.Z, pos_end.Z)), | |
MaxPos = Vector3.new( | |
math.max(pos_start.X, pos_end.X), | |
math.max(pos_start.Y, pos_end.Y), | |
math.max(pos_start.Z, pos_end.Z)), | |
Probability = mag, | |
} | |
mag_total = mag_total + mag | |
end | |
if mag_total > 0 then | |
-- normalise probabilities | |
for _, region in ipairs(regions) do | |
region.Probability = region.Probability / mag_total | |
end | |
end | |
-- handle the creation of new parts | |
local part_count = 0 | |
local part_limit = 100 | |
local function SpawnRandomParts() | |
if part_count >= part_limit then | |
return | |
end | |
for i, region in ipairs(regions) do | |
if math.random() > region.Probability then | |
continue | |
end | |
-- spawn a new part within this region | |
part_count = part_count + 1 | |
local random_pos = Vector3.new( | |
math.random(region.MinPos.X, region.MaxPos.X), | |
math.max(region.MinPos.Y, region.MaxPos.Y), | |
math.random(region.MinPos.Z, region.MaxPos.Z)) | |
local new_part = Instance.new("Part") | |
new_part.Parent = region.Part | |
new_part.Position = random_pos | |
new_part.Size = Vector3.new(1, 1, 1) | |
new_part.Shape = "Ball" | |
new_part.Anchored = true | |
-- delete the part if the player touches it | |
new_part.Touched:Connect(TouchedHumanoid(function(player) | |
part_count = part_count - 1 | |
new_part:Destroy() | |
end)) | |
end | |
end | |
-- spawn a service that creates parts periodically whilst active | |
local run_service = game:GetService("RunService") | |
local current_time = 0 | |
local duration = 0.5 -- second | |
run_service.Heartbeat:Connect(function(delta_time) | |
if not enabled then | |
return | |
end | |
current_time = current_time + delta_time | |
if current_time >= duration then | |
current_time = current_time - duration | |
SpawnRandomParts() | |
end | |
end) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment