Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- [ Blackhole Alpha Experimental ] --
- -- Spring-based, Rope-based, Line-based, VectorForce-based, and LinearVelocity-based (velocity) gravity:
- -- Improved Stability, Performance, and Behavioral Control
- -- WARNING: Orbits are a bit whacky and INACCURATE!!! It's experimental, don't expect too much.
- -- More details in 'v5A_Documentation_READ' section V --
- local blackHole = script.Parent -- Reference
- local gravitationalStrength = 100 -- Controls the strength of the attraction
- local dampingFactor = 0 -- Controls oscillations/elasticity
- local detectionRange = 500 -- Range within which objects are affected
- local innerEventHorizon = 0 -- Factor in which springs stop pulling, but are still present
- local forceCap = 2000 -- The maximum force in which object cap at using line (when `realisticGravity` is true) and linear
- local visibleConstraints = false -- View active gravitations (forces and velocities do not support visual properties in all cases)
- local centerOfMassBased = true -- Toggle to apply forces to the center of masses
- local absorption = true -- Absorb objects on contact when true
- local realisticGravity = false -- Toggle inverse square law (weaker gravity the further it is)
- local toggleMicroGravity = true -- Disable gravity manually
- local cameraDistortion = true -- Toggle camera effects whenever within `detectionRange` (Only works with Run, may cause nausea!)
- local distortThreshold = 0.01 -- Factor (percentage) of the range to distort FOV
- -- "spring" (or "1"), "rope" (or "2"), "line" (or "3"), "vector" (or "4"), "linear" (or "5")
- -- linear subgroup - "linear1" or "5.1" for line velocity, and "linear2" or "5.2" for vector velocity}
- local constraintMode = "linear1" -- "linear1" is velocity-based gravity with MODEL SUPPORT! :D
- -- ADVANCED EXPERIMENTAL --
- local gravitationMode = "universal" -- Choose between "selective" (specific objects) and "universal" (everything) to be pulled in
- local attractionTag = "attractable" -- The tag that objects must have when in selective mode
- -- Disables other gravitational scripts to prevent conflictions
- if script.Enabled then
- blackHole.BHv5_ControlPanel.Enabled = false
- blackHole.BHv5_Alpha_MAIN.Enabled = false
- end
- local camera = workspace.Camera -- Reference for `cameraDistortion`
- -- Table to keep track of active constraints and attachments
- local activeConstraints = {}
- local blackHoleAttachment = Instance.new("Attachment")
- blackHoleAttachment.Parent = blackHole
- -- Function to apply gravity to an object
- local function ApplyGravity(object)
- -- Check if the object already has a constraint attached
- if activeConstraints[object] then return end
- -- Create an attachment on the object
- local objectAttachment = Instance.new("Attachment")
- objectAttachment.Parent = object
- -- Calculate distance from the black hole
- local distance = (blackHole.Position - object.Position).Magnitude
- if constraintMode == "spring" or constraintMode == "1" then
- local spring = Instance.new("SpringConstraint")
- spring.Attachment0 = blackHoleAttachment
- spring.Attachment1 = objectAttachment
- spring.FreeLength = 0
- spring.Stiffness = gravitationalStrength
- spring.Damping = dampingFactor
- spring.LimitsEnabled = true
- spring.MaxLength = detectionRange
- spring.MinLength = blackHole.Size.X * (innerEventHorizon * 0.1)
- if visibleConstraints then
- spring.Visible = true
- spring.Coils = 8
- spring.Color = BrickColor.new("Institutional white")
- end
- spring.Parent = script.ConstraintStorage
- activeConstraints[object] = { constraint = spring, attachment = objectAttachment }
- elseif constraintMode == "rope" or constraintMode == "2" then
- local rope = Instance.new("RopeConstraint")
- rope.Attachment0 = blackHoleAttachment
- rope.Attachment1 = objectAttachment
- rope.Length = distance
- rope.Visible = visibleConstraints
- rope.Color = BrickColor.new("Institutional white")
- rope.WinchEnabled = true
- rope.WinchForce = gravitationalStrength * 10
- rope.WinchSpeed = math.huge
- rope.WinchTarget = 0
- if dampingFactor >= 1 then
- rope.Restitution = 1
- elseif dampingFactor <= 0 then
- rope.Restitution = 0
- end
- rope.Parent = script.ConstraintStorage
- activeConstraints[object] = { constraint = rope, attachment = objectAttachment }
- elseif constraintMode == "line" or constraintMode == "3" then
- local lineForce = Instance.new("LineForce")
- lineForce.Attachment0 = objectAttachment
- lineForce.Attachment1 = blackHoleAttachment
- lineForce.ApplyAtCenterOfMass = centerOfMassBased
- lineForce.Magnitude = gravitationalStrength -- initial value
- if realisticGravity then
- lineForce.InverseSquareLaw = true
- lineForce.Magnitude = gravitationalStrength ^ 3
- lineForce.MaxForce = forceCap ^ 2
- end
- if visibleConstraints then
- lineForce.Visible = true
- lineForce.Color = BrickColor.new("Institutional white")
- end
- lineForce.Parent = object
- activeConstraints[object] = { constraint = lineForce, attachment = objectAttachment }
- elseif constraintMode == "vector" or constraintMode == "4" then
- -- Use VectorForce (force-based velocity)
- local vectorForce = Instance.new("VectorForce")
- vectorForce.Attachment0 = objectAttachment
- vectorForce.RelativeTo = Enum.ActuatorRelativeTo.Attachment1
- local initialDir = (blackHole.Position - object.Position).Unit
- if realisticGravity then
- vectorForce.Force = initialDir * (gravitationalStrength ^ 3)
- else
- vectorForce.Force = initialDir * gravitationalStrength
- end
- vectorForce.ApplyAtCenterOfMass = centerOfMassBased
- vectorForce.Parent = object
- activeConstraints[object] = { constraint = vectorForce, attachment = objectAttachment }
- elseif constraintMode == "linear1" or constraintMode == "5.1"
- or constraintMode == "linear2" or constraintMode == "5.2" then
- local linearVel = Instance.new("LinearVelocity")
- linearVel.Attachment0 = objectAttachment
- linearVel.RelativeTo = Enum.ActuatorRelativeTo.World
- linearVel.MaxForce = forceCap
- if constraintMode == "linear1" or constraintMode == "5.1" then
- -- Line velocity mode
- linearVel.VelocityConstraintMode = Enum.VelocityConstraintMode.Line
- local lineDir = (blackHole.Position - object.Position).Unit
- linearVel.LineDirection = lineDir -- Initial line direction
- -- Set the line velocity (magnitude) to gravitationalStrength
- linearVel.LineVelocity = (gravitationalStrength * 10) / (distance ^ 2) -- Distance squared
- elseif constraintMode == "linear2" or constraintMode == "5.2" then
- -- Vector velocity mode
- linearVel.VelocityConstraintMode = Enum.VelocityConstraintMode.Vector
- local velocityMagnitude = (distance > 0) and (gravitationalStrength / distance) or 0
- local initialDir = (blackHole.Position - object.Position).Unit
- linearVel.VectorVelocity = initialDir * velocityMagnitude
- end
- linearVel.Parent = object
- activeConstraints[object] = { constraint = linearVel, attachment = objectAttachment }
- end
- end
- -- Function to remove gravity from an object
- local function RemoveGravity(object)
- local data = activeConstraints[object]
- if data then
- data.constraint:Destroy()
- data.attachment:Destroy()
- activeConstraints[object] = nil
- end
- end
- -- Function to absorb an object
- local function AbsorbObject(object)
- RemoveGravity(object)
- object:Destroy()
- end
- -- Event listener for when an object touches the black hole
- if absorption then
- blackHole.Touched:Connect(function(hit)
- if hit:IsA("BasePart") and not hit.Anchored and hit ~= blackHole then
- AbsorbObject(hit)
- end
- end)
- end
- if toggleMicroGravity then
- workspace.Gravity = 0
- end
- -- Heartbeat event to enforce gravity on unanchored objects within range
- local CollectionService = game:GetService("CollectionService")
- game:GetService("RunService").Heartbeat:Connect(function()
- -- Existing gravity logic:
- for _, object in pairs(workspace:GetDescendants()) do
- if object:IsA("BasePart") and object ~= blackHole and not object.Anchored then
- local distance = (blackHole.Position - object.Position).Magnitude
- -- Check if the object has the required tag
- local hasTag = CollectionService:HasTag(object, attractionTag)
- if gravitationMode == "selective" and hasTag and distance <= detectionRange then
- ApplyGravity(object)
- elseif gravitationMode == "universal" and distance <= detectionRange then
- ApplyGravity(object)
- else
- RemoveGravity(object)
- end
- elseif activeConstraints[object] then
- RemoveGravity(object)
- end
- end
- -- Update any active velocity-based constraints so the effect always points toward the black hole
- for object, data in pairs(activeConstraints) do
- if object:IsDescendantOf(workspace) then
- local currentDistance = (blackHole.Position - object.Position).Magnitude
- if currentDistance <= detectionRange then
- local newDir = (blackHole.Position - object.Position).Unit
- if data.constraint:IsA("VectorForce") then
- if realisticGravity then
- data.constraint.Force = newDir * (gravitationalStrength ^ 3)
- else
- data.constraint.Force = newDir * gravitationalStrength
- end
- elseif data.constraint:IsA("LinearVelocity") then
- if data.constraint.VelocityConstraintMode == Enum.VelocityConstraintMode.Line then
- -- "linear1" / "5.1": update LineDirection and set constant LineVelocity
- data.constraint.LineDirection = newDir
- data.constraint.LineVelocity = gravitationalStrength
- else
- -- "linear2" / "5.2": update VectorVelocity based on gravity divided by distance
- local newVelocityMag = (currentDistance > 0) and (gravitationalStrength / currentDistance) or 0
- data.constraint.VectorVelocity = newDir * newVelocityMag
- end
- elseif data.constraint:IsA("LineForce") then
- if realisticGravity then
- data.constraint.Magnitude = gravitationalStrength ^ 3
- else
- data.constraint.Magnitude = gravitationalStrength
- end
- end
- end
- end
- end
- -- Camera Distortion Update:
- if cameraDistortion and camera then
- local camPos = camera.CFrame.Position
- local distance = (blackHole.Position - camPos).Magnitude
- local newFOV
- if distance >= detectionRange then
- newFOV = 70 -- Default FOV, but feel free to change it
- elseif distance <= detectionRange * distortThreshold then
- newFOV = 120 -- Maximum FOV, roblox does not allow higher
- else
- local t = (detectionRange - distance) / (detectionRange - distortThreshold)
- newFOV = 70 + t * (120 - 70)
- end
- camera.FieldOfView = newFOV
- end
- end)
- --[[
- -- SNIPPET OF SECTION V --
- ---------------
- V EXPERIMENTALS
- Automatically disables other BH scripts to prevent conflicts.
- For `Constraint-based gravity`: `gravitationalStrength` = `gravitationalConstant`, `absorption`, `toggleMicroGravity`, `constraintMode` = `gravityEngine`, and
- `detectionRange` = `rangeFactor` are the same as their main script counterparts EXCEPT:
- `dampingFactor` is the elasticity of constraints, 0 means no bouncy and 1 is bouncy. `damping` is reversed in logic.
- `innerEventHorizon` is similar to `infinityHandler` but the range is in studs in which constraints stop applying forces. more on `infinityHandler` next section.
- `visibleConstraints` simply allows you to see active constraints on objects for testing. this does not affect performance.
- `centerOfMassBased` sets if forces are applied at the center of MASS. force attachments are placed at the center of GEOMETRY.
- `forceCap` sets the maximum force for objects when using linear and realistic LineForce. this prevents infinite speed at singularity.
- `cameraDistortion` is a toggleable parameter that allows the camera to warp for realism (Warning! May be nausea-inducing. This only works with Run)
- `distortThreshold` is the factor (x100 for percentage) of `detectionRange` where the maximum FOV is achieved (min: 70 [default], max: 120 [absolute])
- `gravitationMode` toggles between universal and selective gravitation for specifc objects. requires tags in desired objects with the same value as `attractionTag`
- `attractionTag` is the specific id for the blackhole to pick out and apply gravity while leaving anything without the tag alone.
- Constraint modes:
- `spring` or `1` - pretty self-explanatory, uses elasticity to reel in objects, causing them to get jiggy with it.
- `rope` or `2` - just like spring, but with less jiggy, but both can have their jiggy-ness controlled with `dampingFactor`.
- `line` or `3` - a "constraint", but a force like BodyForce. this version may replace bodyforce-based gravity entirely, but I'll still keep the legacy mode.
- `vector` or `4` - similar to lineforces, but uses xyz distribution to apply gravity. generally how bodyforce-based gravity works.
- `linear1` or `5.1` - line-based linear velocity. the old velocity-based gravity and mat replace it, but it can also be accessed. THIS HAS MODEL SUPPORT! RAAAAAH
- `linear2` or `5.2` - vector-based linear velocity. does not support orbits and boring in my opinion.
- Experimentals doesn't have much freedom for parameters, only when they're fully integrated into the main scripts. a complete revamp of `gravityEngine` is underway!
- ---------------
- ]]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement