Grabbing individual PhysicalProperties of a part?

Is there any way to get a single, individual property (Friction, Elasticity, etc.) of the PhysicalProperties of a part? If so, is there any way to individually change them without replacing the entirety of its PhysicalProperties?

(Ex: changing only the Friction of a part and maintaining all other PhysicalProperties)

Haven’t seen any solution to this yet, I don’t even know if it is possible. Thanks :grinning:

Well, no. But you could get the properties it should be based on the part’s material, change the friction, and use that new object.

Something like:

local function setFriction(part, friction)
  local props = PhysicalProperties.new(part.Material)
  props.Friction = friction
  part.CustomPhysicalProperties = props
end

setFriction(workspace.Part, 0.5)

If the part is going to be changing materials throughout the game, you’ll need a more complicated solution that redoes this every time it changes.

Sorry, you actually can’t assign directly to Friction, so it would actually be:

local function setFriction(part, friction)
	local props = PhysicalProperties.new(part.Material)
	part.CustomPhysicalProperties = PhysicalProperties.new(
		props.Density, 
		friction, 
		props.Elasticity,
		props.Friction, 
		props.ElasticityWeight
	)
end

setFriction(workspace.Part, 0.5)

That’s pretty annoying.

You can read PhysicalProperties by indexing the name of the property, like so:

local density = Part.CustomPhysicalProperties.Density

However, they decided (for some reason) to not let PhysicalProperties objects to be modified after creation. To change only 1 property, you’d have to save all the current properties, like so:

function GetProperties(Properties)
	return Properties and {
		Density = Properties.Density;
		Elasticity = Properties.Elasticity;
		ElasticityWeight = Properties.ElasticityWeight;
		Friction = Properties.Friction;
		FrictionWeight = Properties.FrictionWeight
	} or nil
end

The function above returns a dictionary containing all the current properties. A way to implement that could be:

function ChangePhysicalProperty(Part: BasePart,Type: string, Value: number)
	local PartProperties = GetProperties(
		Part:IsA("BasePart") and Part.CustomPhysicalProperties or nil
	)
	if PartProperties then
		PartProperties[Type] = Value
		local FormattedTable do
			local t = {}
			for i,v in pairs(PartProperties) do
				table.insert(t,v)
			end
			FormattedTable = t
		end
		Part.CustomPhysicalProperties = PhysicalProperties.new(table.unpack(FormattedTable))
	end
end

Using this, I created a function that handles this. To use it, you pass the part, the property name, and the value. I tested it with this:

function GetProperties(Properties)
	return Properties and {
		Density = Properties.Density;
		Elasticity = Properties.Elasticity;
		ElasticityWeight = Properties.ElasticityWeight;
		Friction = Properties.Friction;
		FrictionWeight = Properties.FrictionWeight
	} or nil
end

function ChangePhysicalProperty(Part: BasePart,Type: string, Value: number)
	local PartProperties = GetProperties(
		Part:IsA("BasePart") and Part.CustomPhysicalProperties or nil
	)
	if PartProperties then
		PartProperties[Type] = Value
		local FormattedTable do
			local t = {}
			for i,v in pairs(PartProperties) do
				table.insert(t,v)
			end
			FormattedTable = t
		end
		Part.CustomPhysicalProperties = PhysicalProperties.new(table.unpack(FormattedTable))
	end
end

print(workspace.Baseplate.CustomPhysicalProperties)
ChangePhysicalProperty(workspace.Baseplate,"Density",100)
print(workspace.Baseplate.CustomPhysicalProperties)

This printed:

1 Like