How can i make a radius for a planet that acts like gravity

  1. I am making a sandbox universe like game with planet destruction and more

  2. I made a hitbox that when a planet is touched it attracts the other planet into it and explodes

  3. I was thinking i can use some kind of radius script or something so it wont be that buggy

After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

FIRST SCRIPT

local mainPart = script.Parent
local copy = script:Clone()

script.Parent.Touched:Connect(function(B)
task.wait(0.2)
local tee = Instance.new(“Explosion”)
tee.Parent = game.Workspace
tee.BlastRadius = 0.5
tee.TimeScale = 0.1
tee.Position = B.Position
local otherParts = {B}
if B.Transparency == 0 then
local success, newSubtract = pcall(function()
return mainPart:SubtractAsync(otherParts)
end)

-- If operation succeeds, position it at the same location and parent it to the workspace
if success and newSubtract then
	local velocity = Instance.new("BodyVelocity")
	velocity.Name = "Sway"
	velocity.Parent = newSubtract
	local cc = script.Parent.ClickDetector:Clone()
	local weld = script.Parent.GravityWeld:Clone()
	local h = script.Parent.Highlight:Clone()
	local ss = script.Parent.Scriptd:Clone()
	local hh = script.Parent.Mars:Clone()
	weld.Parent = newSubtract
	weld.Part0 = newSubtract
	hh.Parent = newSubtract
	newSubtract.Name = "Mars"
	cc.Parent = newSubtract
	h.Parent = newSubtract
	ss.Parent = newSubtract
	copy.Parent = newSubtract
	newSubtract.Position = mainPart.Position
	newSubtract.Parent = workspace
	newSubtract.UsePartColor = true
		script.Parent.Front.Touched:Connect(function()
			velocity.MaxForce = Vector3.new(math.huge, 0, 0)
			velocity.Velocity = Vector3.new(1, 0, 0)
		end)
		task.wait(0.1)
end

-- Destroy original parts which remain intact after operation
mainPart:Destroy()
for _, part in otherParts do
	part:Destroy()
end
end

end)

VIDEO PROOF:

SECOND UPDATED SCRIPT
local mainPart = script.Parent
local copy = script:Clone()

script.Parent.Touched:Connect(function(B)
task.wait(0.2)
local tee = Instance.new(“Explosion”)
tee.DestroyJointRadiusPercent = 0
tee.Parent = game.Workspace
tee.BlastRadius = 0.5
tee.TimeScale = 0.1
tee.Position = B.Position
local otherParts = {B}
if B.Transparency == 0 then
local success, newSubtract = pcall(function()
return mainPart:SubtractAsync(otherParts)
end)

-- If operation succeeds, position it at the same location and parent it to the workspace
if success and newSubtract then
	local velocity = Instance.new("BodyVelocity")
	velocity.Name = "Sway"
	velocity.Parent = newSubtract
	local cc = script.Parent.ClickDetector:Clone()
	local weld = script.Parent.GravityWeld:Clone()
	local h = script.Parent.Highlight:Clone()
	local ss = script.Parent.Scriptd:Clone()
	local hh = script.Parent.Mars:Clone()
	local fr = script.Parent.Front:Clone()
	fr.Parent = newSubtract
	ww.Parent = newSubtract
	ww.Part0 = newSubtract
	ww.Part1 = fr
	weld.Parent = newSubtract
	weld.Part0 = newSubtract
	hh.Parent = newSubtract
	newSubtract.Name = "Mars"
	cc.Parent = newSubtract
	h.Parent = newSubtract
	ss.Parent = newSubtract
	copy.Parent = newSubtract
	newSubtract.Position = mainPart.Position
	newSubtract.Parent = workspace
	newSubtract.UsePartColor = true
		script.Parent.Front.Touched:Connect(function()
			velocity.MaxForce = Vector3.new(math.huge, 0, 0)
			velocity.Velocity = Vector3.new(1, 0, 0)
		end)
		task.wait(0.1)
end

-- Destroy original parts which remain intact after operation
mainPart:Destroy()
for _, part in otherParts do
	part:Destroy()
end
end

end)

VIDEO PROOF:

Both the first and the second scripts have a script that in wich a part called front is touched it generates a body velocity to know in whick way to go (EX: planet A hits the other planet B in the front resulting in planet B backing up)

Gravity Hitbox Script:

script.Parent.Touched:Connect(function(t)
if t.Name == “BasePlate” then
task.wait(0.1)
else
if t.Name == “Gravity” then
task.wait(0.1)
else
if t.Name == “Mars” then
task.wait(0.1)
else
if t.Name == “Front” then
task.wait(0.1)
else

		t.BodyVelocity:Destroy()
		local c = game.ReplicatedStorage.BodyPosition:Clone()
		c.Parent = t
		c.Position = script.Parent.Position
	end
		end
		end
		end

end)

This gravity script attracts other planets into it, as the first and second script taking actions

it is very buggy, first the planet was exploding like crazy and was multiplying at an infinite rate
and now idk why it does this…

1 Like
Gravity Script

Lineforces are more realistic than hitboxes

Place1.rbxl (43.6 KB)
2 parts and a script that connects the parts together u can add as many and u can edit the part’s size / mass on server side to make the lineforces weaker / stronger

(You can copy my script from the place)

(For gravity script!!!)


For the second updated script

The reason why it was buggy is because you were using .Touched, it fires each time the part is touching and the part keeps touching the part so thats why just use

local connection = script.Parent.Touched:Connect(function()
--Put some code here
--End of script you can put anywhere to end the code
connection:Disconnect()
end)

Note: This will only run once, if this script runs once then it suits ur needs

1 Like

Yep I can help you sorry if im like a month late. You need to copy in newtons universal law of gravitation
image

The strength of gravity is inversely proportional to the distance from the two bodies Big G is the gravitational constant you can decide what you want it to be. I’ve written a script for something Im working on. This script updates the positions directly and simulates it without using any roblox physics. The one down side is that if you have large complicated models it will lag really badly also the movement will appear jittery if the physics time step isn’t fast enough you can increase the physics time steps but at the cost of increased lag or you can tween it but it will cause inaccuracies in theoretical models. Here’s the script




local CelestialBody = {}
CelestialBody.__index = CelestialBody

local C = 318.549479287
local K = 2.507


function CelestialBody.new(planet, mass, initialVelocity)
	local self = setmetatable({}, CelestialBody)
	self.planet = planet
	self.mass = mass  
	self.velocity = initialVelocity  
	self.G = 6.67 * 10^1  -- Gravitational constant
	return self
end

-- Method to update velocity based on gravitational force from other bodies
function CelestialBody:updateVelocity(otherBodies, timeStep)
	for _, other in pairs(otherBodies) do
		if other.planet ~= self.planet then
			local direction = other.planet.PrimaryPart.Position - self.planet.PrimaryPart.Position
			local distanceSquared = direction.Magnitude ^ 2
			local forceMagnitude = (self.G * self.mass * other.mass) / distanceSquared

			-- Calculate acceleration based on force and mass
			local acceleration = direction.Unit * (forceMagnitude / self.mass)

			-- Update velocity
			self.velocity = self.velocity + (acceleration * timeStep)
		end
	end
end

-- Method to directly update the position based on velocity and physics timestep
function CelestialBody:updatePosition(timeStep)
	local newPosition = self.planet.PrimaryPart.Position + (self.velocity * timeStep)
	self.planet:SetPrimaryPartCFrame(CFrame.new(newPosition))
end

-- Simulation setup
local planets = {
	{name = "Planet1", mass = 32361001.793, initialVelocity = Vector3.new(0, 0, 0)},
	{name = "Planet2", mass = 30000, initialVelocity = Vector3.new(0, 0, 3303.2365451)},
	{name = "Planet3", mass = 30000, initialVelocity = Vector3.new(0, 0, 2000)},
	{name = "Planet4", mass = 30000, initialVelocity = Vector3.new(0, 0, 2000)},

	-- Add more planets as needed
}

local celestialBodies = {}


for _, planetData in pairs(planets) do
	local planet = game.Workspace.Planets:WaitForChild(planetData.name)
	local body = CelestialBody.new(planet, planetData.mass, planetData.initialVelocity)
	table.insert(celestialBodies, body)
end

-- Simulation loop variables
local fixedTimeStep = 0.1  -- Fixed time step for physics calculations/ decreasing = higher accuracy however more lag
local timeScale = 0.01  -- This value controls how much faster the simulation appears to run
local accumulator = 0  -- fastforward in the simulation 


while true do
	local startTime = tick() 

	
	accumulator = accumulator + task.wait() * timeScale  


	while accumulator >= fixedTimeStep do
		for i = 1, #celestialBodies do
			celestialBodies[i]:updateVelocity(celestialBodies, fixedTimeStep)
		end

		for i = 1, #celestialBodies do
			celestialBodies[i]:updatePosition(fixedTimeStep)
		end

		accumulator = accumulator - fixedTimeStep  
	end
end

If you want to test out the accuracy of the script just plug in this formula and set the speed equal to your calculation and you will get a near perfectly circular orbit
image

Alternatively an easier way to do this would be to use lineforces however it is kind of frustrating to use them as you will need to specify magnitude depending on assemblymass of the object because of inertia. If you want more information feel free to ask. Hope this helps out!

EDIT: I made a mistake. In the code I mean’t to use task.wait() in one of the lines not wait() thats why the motion looks jittery you can now prob get away with a physics timestep equal to the framerate and it will look very smooth.

3 Likes

Oh, didn’t know it was possible to do it that way without using roblox’s physics, I thought it would have performance issues.

2 Likes

It does have performance issues it doesn’t even come close to how optimized roblox’s physics is. However if your using it for like a very simple solar system where each planet is just a part its pretty good and defenitely better then using lineforces or bodyforces to simulate the motion. Its very useful if you want to use it as a solver for a 3 body problem you simply run this at a very quick timestep trace the points the planets draw and you have a very easy orbital render. The numerical time intergration isn’t very efficent it uses eulers method you can easily optimize this far more by using higher order methods like verlet intergration etc

2 Likes