# Attempting to apply a no gravity effect on the character

I have recently started delving into Roblox Physics. More specifically, I have been struggling to make an antigravity script properly affect the character, as demonstrated in the video below.

The video demonstrates that the magnitude of the calculated force for gravity is less than the magnitude of the actual force of gravity on the character, which is less than ideal for my case. The code that is demonstrated within this video is below.

``````local player = game.Players.LocalPlayer
local character = player.Character
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")

--[[
--Returns the current gravity of the workspace
--]]
local function getGravity() : number
return game.Workspace.Gravity
end

--[[
--Returns the mass of the character
--]]
local function getMass() : number
local mass = 0
for i, v in pairs(character:GetChildren()) do
if v:IsA("Part") or v:IsA("MeshPart") or v:IsA("BasePart") then
mass += v.Mass --v:GetMass() is depreciated
end
end
return mass
end

--[[
--	Returns a newly instantiated vector force, which is parented to the humanoidRootPart.
--]]
local function createVectorForce() : VectorForce
local vectorForce = Instance.new("VectorForce")
vectorForce.RelativeTo = "World"
vectorForce.ApplyAtCenterOfMass = true;
vectorForce.Parent = humanoidRootPart
vectorForce.Force = Vector3.new(0, 0, 0)
return vectorForce
end

--[[
--	Creates and applies a force that acts to counteract gravity.
--	Uses the equation F = ma to determine the force that should be applied
--]]
local function counteractGravity()
local vectorForce = createVectorForce()
vectorForce.Force = Vector3.new(0, getMass() * getGravity(), 0)
end

--[[
--	Only used for testing.
--	Teleports the character high in the air.
--]]
local function teleportCharacter() : nil
humanoidRootPart.CFrame = CFrame.new(0, 10000, 0)
return
end
--[[
--	Returns the current linear velocity of the assembly that the HumanoidRootPart is apart of.
--]]
local function getVelocity() : number
return humanoidRootPart.AssemblyLinearVelocity
end
--[[
--	Determines if the character (humanoidRootPart) is accelerating by sampling three points in time,
--  .01 seconds apart
--]]
local function isAccelerating(axis : String) : boolean
local initialVelocity = math.round(getVelocity()[axis] * 100) / 100
local secondVelocity = math.round(getVelocity()[axis] * 100) / 100
local finalVelocity = math.round(getVelocity()[axis] * 100) / 100

return not ((initialVelocity == secondVelocity) and (secondVelocity == finalVelocity))
end

counteractGravity()

teleportCharacter()
--Wait acts to ensure that no 'funny business' ensues by the Roblox Scheduler.
print("Character is Accelerating: " .. tostring(isAccelerating("Y")))
``````

One source of error could be using the wrong measurements for gravity. But because I am using the workspace’s gravity property for my measurement of gravity, which defaults to 196.2, this is likely not the cause of my issue.
In addition to this, it is likely not a client-server interaction issue. I am creating a vector force on the server when I am applying it to a part and creating a vector force on the client when I am applying it to the character.
Another source of error that I have thought over is whether or not an initial force is acting on the object. However, I rule out this source of error with my sampling of velocity over time within the isAccelerating function. This works because, without a net force, acceleration must be constant.
My last source of error that I have thought about is the location of the force. After all, different limbs may have differing masses. But, because I apply the force at the center of mass, it should counteract these differing masses, allowing us to model the character as a single point. (The above code does not accommodate this because of a misunderstanding, but I end up fixing this later on in the post)

And so, with this, I am stuck. I am out of ideas for what could be causing this irregularity.

All help is greatly appreciated,
Bees

Vectorforces require an attachment 0 in order to know which part to apply the forces to. Adding one should fix the issue.

On a side note nice organization there, the functions make it neat.

Yes, you are correct. This is something that I had originally within my program, which I had decided to comment out because I had missread the wiki page, making me think it was redundant in this case.

When I apply the vectorForce to the humanoidRootPart’s attachment ‘RootAttachment’ using `vectorForce.Attachment0 = humanoidRootPart.RootAttachment`, I still have the same issue. I could very well be mistaken, but it seems to be producing the same result. However, when I was rereading the documentation to reply to this answer, I realized the CenterOfMass it uses is the Attachment 0’s parent part’s center of mass and not the character’s center of mass. I am currently working on creating a fix for this within my code and will update this thread on the result of that.

Also, thank you. It’s something I have been trying to improve upon, especially recently.

I am now finding the center of mass of the character, creating a attachment at this position, and then applying the force to this attachment. However, I am still facing the same issue as before with the code below.

``````--[[
--  Finds the character's center of mass
--]]
local function getCenterOfMass() : number
local totalWeightedSections = Vector3.new(0,0,0)
local totalMass = getMass()
local origin = humanoidRootPart.CFrame.Position
for i, v in pairs(character:GetChildren()) do
if v:IsA("Part") or v:IsA("MeshPart") or v:IsA("BasePart") then
totalWeightedSections += v.Position * v.Mass
end
end

end

--[[
--  Creates an attachment at the position.
--]]
local function createAttachment(pos : Vector3) : Attachment
local attachment = Instance.new("Attachment")
attachment.CFrame = CFrame.new(getCenterOfMass() - humanoidRootPart.CFrame.Position) --I am basically undoing what the attachment does by default.
attachment.Name = "CenterOfMass"
attachment.Parent = humanoidRootPart

end

--[[
--	Returns a newly instantiated vector force, which is parented to the humanoidRootPart.
--]]
local function createVectorForce() : VectorForce
local vectorForce = Instance.new("VectorForce")
vectorForce.RelativeTo = "World"
vectorForce.Attachment0 = humanoidRootPart:FindFirstChild("CenterOfMass")
vectorForce.ApplyAtCenterOfMass = true;
vectorForce.Parent = humanoidRootPart
vectorForce.Force = Vector3.new(0, 0, 0)
return vectorForce
end
``````

I believe I calculated everything right, but I am much less than perfect, so please correct me if I did not.

Btw there is no need to do the center of mass calculation due to this line.

Also parts have an .AssemblyMass property and .CenterOfMass property as well now.

Assuming network ownership is correct. (Trusting your word at this point)

Assuming the script prints and runs normally with no errors.

Have you tried editing the vectorforce in the explorer to ensure it is adding force? Even setting it to a high value.

Have you also tried jumping? There might be a timing delay when the script is added so there is some initial downwards acceleration before antigravity is added.

Thats all my ideas for now.

I have uncopyrighted my test place that I am working on so that you no longer have to just take my word of it.

I stared at the documentation for a long time trying to find these properties. I guess I truly am blind. I have updated my functions to incorporate these new features.

Scaling the force up, I multiplied the force by 1000, does end up moving the character upwards.

The way the script is currently set up, you are not able to jump. I have tried jumping in the past using the same logic, and it produces similar results. However, with the current implementation, I tried implementing a counter measure to initial forces which I will explain in greater detail. Let us assume that at the time of calculation, that gravity is properly canceled out by a upward force. In this assumption, the total sum of the forces is zero. Using the equation F=MA, we can rewrite it as 0=MA, requiring acceleration to also be equal to 0. Therefore, if my script properly canceled out the force, the acceleration should also be zero. I measure this by measuring the velocity over time, as roblox lacks an acceleration property. Therefore, this measurement is independent of any initial force and measures the current acceleration, and in turn forces at a given instance.

I am still troubleshooting this problem, however, I came across an interesting discovery. I tried applying this anti-gravity script to other types of rigs with success. In fact, every rig type that I have tried is successful, other than my character. The uncopyrighted place above has been updated to accommodate these tests. In other words, if I create a new rig with my skin, it works. But if I were to copy the character and paste into the workspace so that I can run it on the server, I replicate the issue.

I don’t know if anyone as already said this, but you CAN change the gravity in the workspace locally, which would cause the character to achieve lower gravity.

But it isn’t secure.

Funnily enough I can confirm it works, just only changed the teleport height.

I am guessing it’s a rig problem, perhaps the rig changed and is destroyed, then the vector force won’t apply as it only applies to the destroyed vector force object on an old destroyed gone character model and not the current one (I have seen multiple issues with a similar scenario).

Solution: I added a wait of .1 seconds before I call any of my functions and it seems to work perfectly now. My final script can be found here

The underlying problem: I was experimenting with the program a bit and I realized that the mass that it was calculating was incorrect. My best hypothesis for what is occurring is that Roblox must load the character, and then assign the physical properties of the character, as my program runs fine if it yields before calculating everything.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.