Introduction
The Unity Physics package, part of Unity’s Data-Oriented Technology Stack (DOTS), has been available since Unity 2019. It promises a physics system that uses the Entity Component System (ECS) paradigm, which can significantly improve performance in CPU bound scenarios. With Unity 2022.3, the package reached its 1.0 release and is, in theory, ready for production.
I say “in theory” because, as with many things in Unity, package versioning follows what I like to call the “Unity convention”. This convention differs from the industry’s typical understanding of alpha, beta, and release stages. For most software, an alpha version is functional but incomplete, with missing features and known bugs. In Unity, alpha often feels more like the “wishful thinking” stage, take, for example, the ongoing .NET modernization. Conversely, when most software reaches an official release, it is considered stable, feature complete, and free of critical bugs. In the Unity ecosystem, a “release” is often closer to a public beta: functional but with potential breaking issues, as is the case with the ECS Physics package at the time of writing.
In this post, I will describe why you don’t want to use the ECS physics system in production yet, as there is the danger of having your whole project breaking, but before diving into the problem, we need to review some basic physics concepts, specifically how friction works in combination with Newton’s Third Law of Motion.
Friction And Newton’s Third Law Of Motion
In physics, Newton’s laws of motion describe the fundamental behavior of forces. Newton’s Third Law, the law of action and reaction, states:
“For every action, there is an equal and opposite reaction.”
In simpler terms, whenever two bodies interact, they exert forces on each other that are equal in magnitude and opposite in direction.
Any physics engine must respect these laws, regardless of the programming paradigm. If it doesn’t, the simulation no longer reflects the real world. Friction is a force, and therefore, when two objects experience friction, the forces they exert on each other must also be equal and opposite.
Each physics engine calculates friction in its own way. In Unity, physics materials define a friction value and specify how two materials combine their friction when interacting. Different materials can use different combination methods, but here’s the catch: when two materials with different friction combination rules interact, the calculation must still obey Newton’s Third Law.
To ensure this, Unity needs a system that determines which combination method takes precedence, enforcing a single calculation for both materials. This is the only way to maintain equal and opposite forces when friction values differ.
Friction In ECS And PhysX Physics
In Unity, this precedence is determined using the enum values that define the friction-combination policy.
When using PhysX (the classic GameObject-based physics engine), there are four friction combination options:
1) Average – Use the average of the two friction values.
2) Multiply – Multiply the two values.
3) Minimum – Use the smaller of the two values.
4) Maximum – Use the larger of the two values.
This also defines the order of precedence: Maximum > Minimum > Multiply > Average (highest to lowest).
For example, suppose one material uses Average with a friction value of 0.5, and another uses Minimum with a value of 0.1. Unity will choose Minimum for both materials, resulting in a friction force of 0.1 for both objects.
Here is how the enum is defined for GameObject physics:
public enum PhysicsMaterialCombine
{
Average = 0,
Multiply,
Minimum,
Maximum
}
The ECS physics though, uses a different enumeration:
public enum CombinePolicy : byte
{
/// <summary> sqrt(a * b) </summary>
GeometricMean,
/// <summary> min(a, b) </summary>
Minimum,
/// <summary> max(a, b) </summary>
Maximum,
/// <summary> (a + b) / 2. </summary>
ArithmeticMean
}
There are two key differences between the two physics systems:
1) Three out of four operations are identical. Both systems support Minimum, Maximum, and Arithmetic Mean (or Average, which is effectively the same when applied to two numbers).
2) The enum ordering differs, which affects the priority when determining which combination method is used.
If we revisit the earlier example using ECS Physics, the Arithmetic Mean has a higher priority than Minimum, which means the result would be:
( 0.5 + 0.1) / 2 = 0.3
instead of 0.1, which we would get under GameObject physics.
Initially, I assumed that since these are two independent systems, their differences didn’t really matter. For example, even if the combination order produced different results, each system could be used according to its own logic as long as the behavior was documented.
Unfortunately, that assumption was wrong.
In a recent Unity forum discussion, a Unity staff member confirmed that the difference in operation ordering between GameObject physics and ECS Physics is, in fact, a bug that should be fixed. Specifically, they said:
“Built-in physics authoring uses a certain convention here. It’s just like the built-in Collider layers. Baking these into Unity Physics should follow the same convention. If that’s not the case, it can be considered as a bug.” daniel-holz, in Unity discussions
The Problem With The Current Bug
This bug introduces a serious problem: fixing it will break existing projects that rely on the current (incorrect) ordering. Any project using friction in ECS Physics will see its behavior change once the bug is corrected.
For example, suppose a developer creates a project today where two bodies interact with the following materials:
Material A: Friction = 0.5, Combination = Average
Material B: Friction = 0.1, Combination = Minimum
Under the current ECS Physics behavior, the result is 0.3. Once the bug is fixed, the correct combination rule (Minimum) will apply, and the result will change to 0.1, significantly altering how quickly objects slow down.
Another example is even more critical. Imagine:
Material A: Friction = 0 (frictionless), Combination = Minimum
Material B: Friction = 0.8, Combination = Average
With the current bug, the objects will eventually stop moving. After the fix, the Minimum operation will take precedence, producing a result of 0, meaning the objects will never stop moving.
This demonstrates how a “fix” could completely change the physical behavior of a game, potentially breaking gameplay or requiring a full rebalance of physics interactions.
Multiplication VS Square Root Of The Product
The second difference raises another question:
If not following the GameObject physics conventions is considered a bug, is the difference in the multiplication method also a bug?
GameObject physics uses Multiplication (friction = a * b).
ECS Physics uses the Geometric Mean (friction = sqrt(a * b)).
Unity even issues a warning that the Multiplication mode is not directly convertible between the two systems. This difference can produce noticeably different results.
I asked this question in the Unity forums as well, but at the time of writing, I have not received an answer:
“So is then the difference in operations a bug too? Because only three of the four are same: The Game Object physics uses a multiplication of the two friction values as the fourth operation, but the ECS system uses the geometric mean, which is the square root of the product of the two values. In fact Unity issues a warning that the multiplication mode is not convertible between the two. This obviously will have different results.
Should we also expect a change here? Will ECS physics eventually adopt multiplication, or is the square root of the product of the values going to change for the ECS physics to multiplication so that both systems follow the same convention?
Changes like this are important to know for anyone starting a project with ECS physics, as switching to the GameObject multiplication convention would be a breaking change.”
Conclusion
ECS Physics currently suffers from at least one confirmed bug in its friction system. Fixing it will introduce breaking changes for any project that relies on the current combination ordering.
Until this is resolved, my recommendation is:
Avoid using ECS Physics in production projects.
Use classic GameObject physics instead if you need stability today.
Or wait for Unity to clarify how these changes will be implemented before committing a large project to ECS Physics.
We still have no official answer on whether the Multiplication vs. Geometric Mean difference is a bug. If Unity decides to align ECS Physics with GameObject physics here as well, it would introduce yet another breaking change.
Initially, I assumed the enum’s ordering was intentional, which is why I didn’t consider it a bug at first. A mistake like this is serious, especially in such a simple and fundamental piece of code. Creating an ordered enum and carefully choosing its value sequence is programming 101. Enums are rigid structures—any change to their order or values in a library causes breaking changes.
When exposing an enum in a public API, its values and their ordering should never change. Otherwise, a different form of enumeration should be used, as described in the Framework Design Guidelines. I’ve previously illustrated some safer alternatives in these posts:
- Alternatives to Enums - Part 1: Strongly Typed Strings
- Alternatives to Enums – Part 2: Advanced Enums Implementing Polymorphic Behavior with Custom Types
In this particular case, implementing those alternatives wouldn’t be trivial because the underlying type needs to be byte for performance reasons in ECS. Still, a custom type could have been used as an adapter between the UI and the internal enum to avoid these issues.
We may never know the reasoning behind some of Unity’s design decisions. But even in simple, critical areas of the engine, Unity seems to have a habit of shooting itself in the foot.
I will update this post when Unity provides more information whether it’s about the confirmed friction combination order fix or the Multiplication vs. Geometric Mean discrepancy.
Until then, thank you for reading and as always, if you have any questions or comments you can use the comments section, or contact me directly via the contact form or by email. Also, if you don’t want to miss any of the new blog posts, you can subscribe to my newsletter or the RSS feed.