New physics controllers become unstable when changing a character's mass during run-time

When changing the AssemblyMass of a player character during run-time while using the new GroundController, AirController, etc. the character will become unstable. Increasing the mass will cause the character to ‘shake’ while standing in place and any slight movement could cause the character to trip and fall over. The heavier the character, the more unstable they become.

Below are two videos demonstrating what is happening at different masses. The character’s weight was changed by setting all BaseParts under the character instance to Massless = true, except for the HumanoidRootPart whose density was increased to change the AssemblyMass. My player character’s AssemblyMass is normally 13.77 units when no code is used to change the mass.

When increasing the AssemblyMass to 16 units, the character will start shaking as seen in the video below:

When I increase the AssemblyMass to a whopping 160 units, any unexpected change of movement will cause the character to fall over immediately:

For gameplay purposes I want the characters in my game to all have the same weight, but unfortunately this behavior prevents me from using the physics controllers if I do so.

Reproduction steps

  1. Add a Humanoid named StarterHumanoid to the StarterPlayer folder with a ControllerManager and any of the physics controller instances as children.
    image
  2. Insert the following code into a Script inside the ServerScriptService.
local PLAYER_MASS = 160 -- change this to see how the behavior changes at different weights

function fixMass(Obj: BasePart)
	if Obj.Name ~= "HumanoidRootPart" then
		Obj.Massless = true
	else
		local propertiesOld = PhysicalProperties.new(Obj.Material)
		local properties = PhysicalProperties.new(
			PLAYER_MASS / (Obj.Size.X * Obj.Size.Y * Obj.Size.Z),
			propertiesOld.Friction,
			propertiesOld.Elasticity,
			propertiesOld.FrictionWeight,
			propertiesOld.ElasticityWeight
		)
		Obj.CustomPhysicalProperties = properties
		Obj:GetPropertyChangedSignal("Size"):Connect( -- for some reason the HumanoidRootPart's Size changes after CharacterAdded is already called?
			function()
				properties = PhysicalProperties.new(
					PLAYER_MASS / (Obj.Size.X * Obj.Size.Y * Obj.Size.Z),
					propertiesOld.Friction,
					propertiesOld.Elasticity,
					propertiesOld.FrictionWeight,
					propertiesOld.ElasticityWeight
				)
				Obj.CustomPhysicalProperties = properties
			end
		)
	end
end

game.Players.PlayerAdded:Connect(
	function(Plr)
		Plr.CharacterAdded:Connect(
			function(Character)
				local P = Character:GetDescendants()
				for i = 1, #P do
					if P[i]:IsA("BasePart") then
						fixMass(P[i])
					end
				end
				Character.DescendantAdded:Connect(
					function(Obj)
						if Obj:IsA("BasePart") then
							fixMass(Obj)
						end
					end
				)
			end
		)
	end
)
  1. Run the game and observe how the character will trip when you rotate too much.
4 Likes

Hello, does enabling GroundController.RidgityEnabled work?

Feel free to give it a try! All instructions to reproduce this bug are included in the main post. If you find any additional information that may be valuable to this bug report feel free to share it.

you have to compensate it by increasing align torque of ground controller. Another issue with that is, if the entire mass is distributed to a center, the character may just flip over even worse.

HumanoidRootPart resized to 0.5x0.5x0.5 at max density with rest massless and low align torque enough to flip character

HumanoidRootPart being normal size at high mass and sufficent align torque to stop character and not flip over


I have to distribute mass and avoid making it extremely dense in the center.

1 Like

Thanks for reporting this. I filed a ticket to our internal database.

2 Likes

Bit of a late follow up here, but this issue should be mostly resolved. The character should be stable at any mass assuming the GroundController.BalanceMaxTorque is set high enough to keep the character upright. The jittery-ness is gone.

However, following the exact repro in this post (mass of 160) will still result in the character tipping when motion stops. The rapid deceleration adds significant angular acceleration to the character, which is more than the default BalanceMaxTorque can handle at that mass. This can be compensated for by either increasing the BalanceMaxTorque, or introducing a non-zero DecelerationTime (0.1s was sufficient for me). This allows the character to naturally slow down from their top speed, reducing the resulting angular acceleration. (This approach is more typical of us in real life - since if you were also able to stop running instantly you’d probably also fall on your face). And of course setting RigidityEnabled will prevent the character from tipping all together.

There is still instability that occurs when your ControllerManager.GroundSensor.HitPosition is far from the assembly’s CenterOfMass. For example, if you welded a very long Part to the character’s head. Increasing the BalanceMaxTorque in this situation won’t compensate. We are tracking this issue in a separate ticket, and will be closing this one.

1 Like