Issue with GetMass() or with me?

I submitted a bug report, but I’m second guessing myself while waiting for post approval. Maybe some of you can help confirm that it isn’t just a scripting issue that I’m experiencing.

  1. What do you want to achieve? Keep it simple and clear!
    I’m trying to write a controller that allows a player to float in a specific way. I’d like to use forces, and something central to that approach is having the ability to reliably cancel the effects of gravity. The technique used is the standard anti-gravity approach that relies on BasePart:GetMass() to supply mass for parts of an assembly and then using those values to create a force that balances gravity (applied with BodyForce or VectorForce).
    (This is preamble: I don’t need help with scripting any of that)

  2. What is the issue? Include screenshots / videos if possible!
    The issue is that the approach works fine for models built in studio and with the default R15 character (avatar customization on website), but not for all parts. The player’s character is mostly what I’m concerned about, and if I use the default avatar, I can “levitate” the character with no drift in Y. If I then swap parts in the avatar customizer, the “Man Torso” for example, and re-run the game, the anti-gravity breaks down and I get unwanted movement in Y (down drift with torso, up with legs, etc). That’s with no changes to the script.

Swapping to a new part should not change the balance of forces if part:GetMass() is giving the same values that are being used by the physics engine. If one 2x2x2 plastic part floats using an anti-gravity script, then changing to another nxnxn plastic part (or any other material) should give similar results when the code is calculating forces based on part mass. Yes?

I’ve only seen the problem with parts like the “Man Torso” that are linked in with IDs from the website. This makes me wonder if there is an issue with how some models are being wired in to the game, or with how particular models/meshes are being created that causes an error when they are linked/imported. I haven’t explored possible root causes to any real extent. This is all conjecture and anecdotal.

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    For my game, the places where I would like players to float are such that I can force everyone to use the default avatar body parts (or others I create) without ruining the experience. I have a work-around. I’m mainly looking for a sanity check on what I think I’m seeing. Maybe it’s a dev issue and not a bug.

Support materials

Test Script
--[[ Anti-gravity test

	Script can be run from workspace.

	To test I created a short staircase in Studio and walked the character to the top and off the end.
	The character should hang in the air without drift when stepping off the stair.

	Leaving game and changing parts (eg. UpperTorso) of avatar on Roblox website breaks the anti-gravity
]]
local character = nil
local humanoid = nil
local bodyForceFlag = false

function GetMass(character)
	local m = 0
	for i,v in pairs(character:GetDescendants()) do
		if ((v:IsA("BasePart") or v:IsA("MeshPart")) and not v.Massless) then
			local vMass = v:GetMass()
			--[[ Seems to work for Man Torso
			if v.Name == "UpperTorso" then
				obj = v.Size.X * v.Size.Y * v.Size.Z * 0.887
			end
			]]
			m = m + vMass
		end
	end
	return m
end

function TestRun()
	if bodyForceFlag then
		-- antiGravity using BodyForce
		local bf = Instance.new("BodyForce")
		bf.Force = Vector3.new(0, workspace.Gravity * GetMass(character), 0)
		bf.Parent = humanoid.Parent.HumanoidRootPart
		
	else
		-- antiGravity using VectorForce
		local antiGravity = Instance.new("VectorForce")
		antiGravity.ApplyAtCenterOfMass = true
		antiGravity.Attachment0 = character.HumanoidRootPart.RootRigAttachment
		antiGravity.RelativeTo = Enum.ActuatorRelativeTo.World
		antiGravity.Force = Vector3.new(0, workspace.Gravity * GetMass(character), 0)
		antiGravity.Parent = character.HumanoidRootPart
	end
end

game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(char)
		character = char
		humanoid = char:FindFirstChild("Humanoid")
		TestRun()
	end)
end)

Default avatar works with anti-gravity as expected:
Default.wmv (817.9 KB)

Changing default torso to “Man Torso” and re-running produces markedly different results.
ManTorso.wmv (1.2 MB)


Edit:
It looks to be a scripting issue after all. In my test cases I am calling a fn (TestRun) to calculate mass and hook up the character when the CharacterAdded event is triggered. It appears that doing it this way will result in GetMass() passing the default avatar mass to the script for some body parts that are presumably still being loaded from the website, but the engine uses the correct mass of the actual parts once they are loaded when doing the simulation. This difference in mass values the script is using vs values used in the simulation causes the problem. Adding a wait() to the above script before calling TestRun() results in the expected behavior. Thanks to anyone who was looking into this. -Astr0

2 Likes

I’m guessing it modifies the mass by changing the CustomPhysicalProperties. Try connecting a function to the .Changed event of the parts that change mass and see if that’s the case (the parameter name that changed is passed to the listener function, so just print that).

If that’s the case, you need to update the Force every time a part changes mass, i.e. the CustomPhysicalProperties change.

Thanks for your thoughts. I’ll definitely add some checks for any changes to parts I’m trying to control.

The CustomPhysicalProperties and HumanoidDescription changes don’t seem to be triggering. I played around with a few other events and got the output below. In the first output the torso does appear to get added to the character after the VectorForce.Force is calculated, so maybe it is calling GetMass on default char parts. This thread suggests that polling a model for physics-related properties when a model isn’t parented to workspace can cause issues. Maybe this is related to that and the physical properties on the char haven’t been set while it’s in “the nether”. I don’t see (watching script events) where it shows the properties updating once the character is parented to workspace though.

Anyway, I won’t be adding anti-gravity to characters as they arrive in the actual game, so this shouldn’t be a problem for me. I’ll play around with ways to check for changes to the character model after it’s in the game, but It seems that I should have control over those kinds of changes once things are underway.

Printout of some events

Original script (order of operations)
(only Torso is not default)

TestRun called
GetMass called
Torso Size 2, 1.60003424, 1.00000036
mass: 14.322490110993
VectorForce changed Force
Descendant added to char: VectorForce
VectorForce changed Parent
Descendant added to char: UpperTorso
Descendant added to char: WaistRigAttachment
Descendant added to char: NeckRigAttachment
Descendant added to char: LeftShoulderRigAttachment
… etc (other parts added)
HumRoot Ancestry changed Astr0Derp Workspace
Descendant added to char: OriginalSize (x2)
Descendant added to char: OriginalPosition (x9)
Descendant added to char: OriginalSize
Descendant added to char: OriginalPosition (x7)
Descendant added to char: Status
Descendant added to char: ForceField
HumRoot change CFrame
HumRoot change Position
HumRoot change Orientation
HumRoot change Rotation
HumRoot change NetworkOwnerV3


Script with wait
(only Torso is not default )

Descendant added to char: UpperTorso
Descendant added to char: WaistRigAttachment
Descendant added to char: NeckRigAttachment
Descendant added to char: LeftShoulderRigAttachment
… etc (other parts added)
HumRoot Ancestry changed Astr0Derp Workspace
Descendant added to char: OriginalSize (x2)
Descendant added to char: OriginalPosition (x9)
Descendant added to char: OriginalSize
Descendant added to char: OriginalPosition (x7)
Descendant added to char: Status
Descendant added to char: ForceField
HumRoot change CFrame
HumRoot change Position
HumRoot change Orientation
HumRoot change Rotation
HumRoot change NetworkOwnerV3
TestRun called
GetMass called
Torso Size 1.83907783, 1.90123844, 1.07331204
mass: 14.916972503066
VectorForce changed Force
Descendant added to char: VectorForce
VectorForce changed Parent

1 Like