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
task.wait(.01)
local secondVelocity = math.round(getVelocity()[axis] * 100) / 100
task.wait(.01)
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.
task.wait(2)
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