Ive been switching between Body POsition and AlignPosition I’ve been able to recreate it so some extent. The issue is that sometimes you cant move laterally at all really and after you’ve been sucked into the middle you walk right out like the gravity doesn’t exist, I tried altering the force many times but I just cant seem to get it right or another problem arises here’s an example and my code: https://i.gyazo.com/773371b66d02b17f4dd1c16a2ea9f55d.mp4
It might be worth taking a different approach with LinearVelocity here, too.
You can use something like this to pull a body towards another:
local a: Vector3 = player.Character.PrimaryPart.Position
local b: Vector3 = gravity_sphere.Position
local force = 50
local linear_velocity: LinearVelocity = Instance.new("LinearVelocity")
linear_velocity.VectorVelocity = (b - a).Unit * force
linear_velocity.Parent = player.Character.PrimaryPart
That way, you don’t have to worry about forces and can adjust the value of force to suit what strength you need.
Well as the player jumps the pull affects them more as they aren’t grounded so you would need a way to fix that, though that would be a difficult task. As you would need it to make it think as if it was still grounded when the character is jumping.
Using this method ive gotten very close to what I’m trying to achieve, my only issue is that the velocity doesn’t seem to be constant, what I mean is when you stay still inside the field the pull isn’t as strong as the initial pull as well as when you can only walk a certain distance before the force starts to dissipate Heres my code any ideas?
local Part = workspace.UmbraField
local CharVel = Character.PrimaryPart.AssemblyLinearVelocity
local force = 1000
local linear_velocity: LinearVelocity = Instance.new("LinearVelocity")
local Att1 = Instance.new("Attachment")
local Att0 = Instance.new("Attachment")
Att1.Name = "Att1"
Att0.Name = "Att0"
Att0.Parent = RootPart
Att1.Parent = Part
linear_velocity.Parent = Character.PrimaryPart
linear_velocity.MaxForce = 3930
linear_velocity.Attachment0 = Att0
linear_velocity.Attachment1 = Att1
linear_velocity.Enabled = true
while true do
local A = Character.PrimaryPart.Position
local B = Part.Position
local CharVel = Character.PrimaryPart.AssemblyLinearVelocity
wait()
linear_velocity.VectorVelocity = (B - A).Unit * force
linear_velocity.VelocityConstraintMode = Enum.VelocityConstraintMode.Vector
linear_velocity.RelativeTo = Enum.ActuatorRelativeTo.World
end
I did that and it’s not changing much here’s the code I used.
while true do
wait()
if Partinbox == true then
linear_velocity.Enabled = true
local A = Character.PrimaryPart.Position
local B = Part.Position
local CharVel = Character.PrimaryPart.AssemblyLinearVelocity
local force = 4000 * (A - B).Magnitude
local VectorVel = (B - A).Unit * force
linear_velocity.VectorVelocity = VectorVel
else
linear_velocity.Enabled = false
end
end
Here you update the velocity to be applied to the player with each iteration of the loop. Instead, you want to calculate the velocity to be applied when the player first enters the gravitational field and then apply the velocity. That way, instead of updating the velocity in a loop, you remove the velocity when the player has left the gravitational field.
Let me know if you need some pseudocode demonstrating this!
First of all, avoid using variable names like “A” and “B.” Use “characterPosition” and “partPosition” instead; these names are longer but nobody has to go back through the code to figure out what they are. Styling your code correctly is essential. (Including indentation and spacing)
Don’t use wait, use task.wait(); pretty sure it performs better in every way possible. You can also do: while task.wait() do instead of while true do task.wait().
Lastly, relating to your actual problem, your force is getting stronger the further from the center you are, that’s why you’re getting that back-and-forth motion you referred to. Instead, the force should get weaker the further the player is. You can use division for this, though I assume you still want it to suck in the player momentarily at the beginning; you can do what you’re currently doing at the start, wait for a second or 2, then switch to the other one. OR, just math.max() the force to something reasonable.
Code for math.max() method
while task.wait() do
linear_velocity.Enabled = Partinbox
if not Partinbox then continue end
-- Get properties
local characterPosition = Character.PrimaryPart.Position
local partPosition = Part.Position
-- Calculate force
local force = 4000 * (characterPosition - partPosition).Magnitude
local forceMaxed = math.max(force, 20000)
-- Apply force
linear_velocity.VectorVelocity = (partPosition - characterPosition).Unit * forceMaxed
end
Using this method however I haven’t seen much change, I still get the back-and-forth movement. I tried messing with the force values but that didn’t help I could tweak them a little more but I’m unsure if that would actually fix the issue. Additionally, I still get moments where I walk into the circle and get pulled walk halfway out and then the force pulling me into the circle is less strong than the initial pull. I want the force to be consistent if that makes sense, I don’t want it to get lesser or greater the farther from the center you get but rather a consistent force being applied.
Heres my full code again to see if there’s something else that’s wrong.
--Services
local Replicated = game:GetService('ReplicatedStorage')
local UIS = game:GetService('UserInputService')
--
--Character/Player
local Players = game:GetService('Players')
local Player = Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild('Humanoid')
local Animator = Humanoid:WaitForChild('Animator')
local RootPart = Character:WaitForChild('HumanoidRootPart')
local Mouse = Player:GetMouse()
local Animator = Humanoid:WaitForChild('Animator')
local TweenService = game:GetService("TweenService")
local Partinbox = false
--Body
local Part = workspace.UmbraField
local linear_velocity = Instance.new("LinearVelocity")
local Att1 = Instance.new("Attachment")
local Att0 = Instance.new("Attachment")
Att1.Name = "Att1"
Att0.Name = "Att0"
Att0.Parent = RootPart
Att1.Parent = Part
linear_velocity.Parent = Character.PrimaryPart
linear_velocity.Attachment0 = Att0
linear_velocity.Attachment1 = Att1
linear_velocity.Enabled = true
linear_velocity.MaxForce = 4032
local params = OverlapParams.new()
params.FilterType = Enum.RaycastFilterType.Include
params.FilterDescendantsInstances= {RootPart}
coroutine.wrap(function()
while task.wait() do
local PartsInBox = workspace:GetPartBoundsInRadius(Part.Position,24.6,params)
if PartsInBox[1] == RootPart then
Partinbox = true
else
Partinbox = false
end
end
end)()
while task.wait() do
linear_velocity.Enabled = Partinbox
if not Partinbox then continue end
-- Get properties
local characterPosition = Character.PrimaryPart.Position
local partPosition = Part.Position
-- Calculate force
local force = 4000 * (characterPosition - partPosition).Magnitude
local forceMaxed = math.max(force, 20000)
-- Apply force
linear_velocity.VectorVelocity = (partPosition - characterPosition).Unit * forceMaxed
end
For a constant force applied (no matter how far away you are), you’ll want to use this code:
Constant force code
while task.wait() do
linear_velocity.Enabled = Partinbox
if not Partinbox then continue end
-- Get properties
local characterPosition = Character.PrimaryPart.Position
local partPosition = Part.Position
-- Calculate force
local force = 4000
local characterToPartVector = (partPosition - characterPosition).Unit
-- Apply force
linear_velocity.VectorVelocity = characterToPartVector * force
end
It just sets the force to 4000 instead of the complicated math. You’ll have to change the force value to something greater if it doesn’t do anything.
Just a suggestion, but instead of using the LinearVelocity body mover you could adjust the velocity of the character directly; something like:
Adding force to character code
This likely has errors.
--[[ Services ]]--
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
--[[ Variables ]]--
local localPlayer = Players.LocalPlayer
local character = localPlayer.Character or Player.CharacterAdded:Wait()
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
local umbraField = workspace.UmbraField
local params = OverlapParams.new()
params.FilterType = Enum.RaycastFilterType.Include
params.FilterDescendantsInstances= {RootPart}
--[[ Functions ]]--
while task.wait() do
-- Check if the character is touching part
local umbraFieldPosition = umbraField.Position
PartsInBox = workspace:GetPartBoundsInRadius(umbraFieldPosition, 24.6, params)
if PartsInBox[1] ~= humanoidRootPart then continue end -- sus >_>
-- Get properties
local characterPosition = humanoidRootPart.Position
-- Calculate force
local characterToPartVector = (umbraFieldPosition - characterPosition).Unit
local force = characterToPartVector * 5
-- Apply force
humanoidRootPart.AssemblyLinearVelocity += force
--[[or "humanoidRootPart:ApplyImpulse(force)"]]
end
Again, if it doesn’t do anything, increase the force.
Well I believe you should switch how the distance is calculated as the further you are the stronger it gets because of how you set up this:
local force = 4000 * (A - B).Magnitude
--example: 4000 * 70(further away) = 280,000 , 4000 * 4 (closer) = 16,000
-- I believe it should be divided maybe that'll work,
- I believe this will work:
local force = 4000 / (A - B).Magnitude
After trying all the solutions you recommended, I found that adjusting the character’s velocity directly worked best. However, the only issue I found with that was when you get dragged into the middle of the circle walk a few steps towards the edge and stop you don’t get pulled back to the center with the same amount of force you got pulled in with. I’m content with leaving this as it is because I’m starting to think that maybe my goal isn’t achievable. If you guys have any clue on how to fix that issue, please tell me but if not, thanks for the help!
Interesting, not sure why that’d be happening, but here are my two guesses:
The line of code if PartsInBox[1] ~= humanoidRootPart then continue end is passing true more than it should be after the beginning. This would cause the code not to apply force to the character despite them being in the radius. If you want to fix this, then you’d have to check every part the GetPartsInRadius returned to see if it’s the humanoidRootPart.
or
The character stands still, and there isn’t a counterforce in the beginning like when you’re walking away.
It also might be that something else is adjusting the force of the character like a separate script.