Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- [ Charged Particles/Atoms Simulation Source Code Basics ] --
- -- For archived versions, visit my pastebin: https://pastebin.com/u/1m1m0
- local particle = script.Parent
- local attractionPower = 5 -- Attraction strength between attracting particles
- local halfLife = 60 -- Time for a particle to flip it's charge
- local radiateThreshold = {1, 2, 3} -- Amount/s of particles a particle with an opposite charge is touching to eject itself
- --[ VELOCITY PRESET ]
- -- Function to apply electromagnetic force
- function ApplyElectromagneticForce(object1, object2)
- local direction = object1.Position - object2.Position
- local distance = direction.Magnitude
- -- Do not apply the force if the objects are too close to each other
- if distance <= 0.9 * object1.Size.X then
- return -- This prevents velocities from approaching infinity
- end
- local forceMagnitude = (attractionPower * object1.Size.X * object2.Size.X) / (distance * distance)
- local force = direction.Unit * forceMagnitude
- -- Check the charges of the objects
- local charge1 = object1:FindFirstChild("Charge") and object1.Charge.Value
- local charge2 = object2:FindFirstChild("Charge") and object2.Charge.Value
- -- If the charges are the same, they attract eachother (I know, it violeates real world laws)
- if charge1 == charge2 then
- object1.Velocity = object1.Velocity - force
- object2.Velocity = object2.Velocity + force
- -- If the charges are different, they repel each other
- else
- object1.Velocity = object1.Velocity + force
- object2.Velocity = object2.Velocity - force
- end
- end
- --]]
- --[[ [ BODYFORCE PRESET ]
- -- Function to apply electromagnetic force using BodyForce
- function ApplyElectromagneticForce(object1, object2)
- local direction = object1.Position - object2.Position
- local distance = direction.Magnitude
- -- Do not apply the force if the objects are too close to each other
- if distance <= 0.9 * object1.Size.X then
- return
- end
- local forceMagnitude = (attractionPower * object1.Size.X * object2.Size.X) / (distance * distance)
- local force = direction.Unit * forceMagnitude
- -- Check the charges of the objects
- local charge1 = object1:FindFirstChild("Charge") and object1.Charge.Value
- local charge2 = object2:FindFirstChild("Charge") and object2.Charge.Value
- -- If the charges are the same, they repel each other
- if charge1 == charge2 then
- force = -force -- Reverse the direction of the force
- end
- -- Apply the force using a BodyForce instance
- local bodyForce = object1:FindFirstChild("ElectromagneticBodyForce")
- if not bodyForce then
- bodyForce = Instance.new("BodyForce")
- bodyForce.Name = "ElectromagneticBodyForce"
- bodyForce.Force = force
- bodyForce.Parent = object1
- else
- bodyForce.Force = force
- end
- end
- --]]
- -- Function to check and apply electromagnetic force
- local function CheckAndApplyElectromagneticForce(obj)
- if not obj:IsA("BasePart") or obj:IsA("Model") or obj:IsA("Union") or obj:IsA("Tool") or obj:IsA("MeshPart") or obj:IsA("Mesh") then
- return -- BasePart means everything in Workspace, some may not be included and you may need to add "obj:IsA("")" with their classname in the list above.
- end
- if obj == particle or obj == obj:IsA("Player") then
- return -- Excludes the players and particle itself from electromagnetic force, feel free to add more.
- end
- if obj.Anchored then
- return -- Prevents particle from applying force to the anchored objects. (Saves resources and computation power)
- end
- -- Randomly assign a charge to the object if it doesn't have one
- if not obj:FindFirstChild("Charge") then
- local boolValue = Instance.new("BoolValue")
- boolValue.Name = "Charge"
- boolValue.Value = math.random() > 0.5 -- Get rid of this line for identical xharges if you want
- boolValue.Parent = obj
- -- Start a coroutine to flip the charge at a random interval
- coroutine.wrap(function()
- while obj do
- wait(math.random() * halfLife) -- Wait for a random time up to 60 seconds (Default half life)
- boolValue.Value = not boolValue.Value -- Flip the charge
- -- Break any existing constraints when the charge flips
- for _, child in pairs(obj:GetChildren()) do
- if child:IsA("RodConstraint") then
- child:Destroy()
- end
- end
- end
- end)()
- end
- ApplyElectromagneticForce(particle, obj)
- end
- game:GetService("RunService").Heartbeat:Connect(function()
- for _, object in pairs(game.Workspace:GetDescendants()) do
- CheckAndApplyElectromagneticForce(object)
- end
- end)
- -- Function to create a RodConstraint between particles with the same charge
- local function CreateConstraint(part)
- local otherPart = part:GetTouchingParts()[radiateThreshold] -- Get the first 1, 2 or 3 parts that is touching the current part
- if otherPart then
- local charge1 = part:FindFirstChild("Charge") and part.Charge.Value
- local charge2 = otherPart:FindFirstChild("Charge") and otherPart.Charge.Value
- if charge1 == charge2 then
- local attachment0 = Instance.new("Attachment", part)
- local attachment1 = Instance.new("Attachment", otherPart)
- local constraint = Instance.new("RodConstraint")
- constraint.Attachment0 = attachment0
- constraint.Attachment1 = attachment1
- constraint.Length = part.Size.X/2 + otherPart.Size.X/2 -- Set the length to the sum of the radii of the parts
- constraint.Parent = part
- end
- end
- end
- particle.Touched:Connect(CreateConstraint)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement