Search Unity

  1. We are migrating the Unity Forums to Unity Discussions. On July 12, the Unity Forums will become read-only. On July 15, Unity Discussions will become read-only until July 18, when the new design and the migrated forum contents will go live. Read our full announcement for more information and let us know if you have any questions.

Question Are there any plans for DOTS Physics2D?

Discussion in 'Physics for ECS' started by Gekigengar, Oct 20, 2022.

  1. Gekigengar


    Jan 20, 2013
    Are there any plans for DOTS Physics2D? Or will it only be Tiny only feature? (Which is indefinitely paused right now)
    Aratow and Volshar like this.
  2. Volshar


    Mar 14, 2021
    Would like to know this too. I have found this github repo of someone doing 2D physics based on UnityPhysics for DOTS but it would be awesome to have official deterministic 2D physics alongside the 3D ones. :)
  3. Tigrian


    Mar 21, 2021
    From what little I know, there is no 2D physics package planned at the moment (apart from the Tiny project), it's not even on the roadmap, so it's very unlikely that a full package will arrive soon. But if you need 2D physics, you can use the limit DOF joint (limit degree of freedom, see this link.), which will limit your physic to two axes. This was recommended in this post by SteveeHavok, that links to his other responses (and is still the response I've seen from Unity staff to people asking for a 2D package). I've never tried to make a 2D game this way, so if you know about the limit DOF joints, and those are insufficient for your needs, forget my answer. However, it always seemed to me that the Unity developers claimed that this was sufficient for 2D physics. And so this physics will be as deterministic as 3D physics is already. If this does not answer your question on how to make 2D physic, and you just want a full dedicated package (not sure if this would make sense outside of Tiny though), again, forget my answer, I've never made a 2D game, even less in ECS.
    Last edited: Oct 27, 2022
    Aratow likes this.
  4. msfredb7


    Nov 1, 2012
    I'm the author of Fix2D and I don't recommend you use it at the moment. Locking regular Unity-Physics in 2D space OR using regular GameObjects is safer. Fix2D is quite experimental, and it's not deterministic yet. Most of the internal implementation still has floats. Also: making your game use "fix" (software floats, 64 bit) instead of "float" is quite a pain. We've already done it for our project so the cost has been paid, but I'm not sure I'd recommend it unless determinism is serious requirement for you.

    Disclaimer: Just an opinion
    Regarding 2D physics in ECS from Unity, I don't think this will happen anytime soon. Mainly because regular GameObject Unity is ok for most 2D games.

    EDIT: I've made the Fix2D repository private. I don't consider it mature enough to be shared.
    Last edited: Nov 17, 2022
    BAIZOR likes this.
  5. Kmsxkuse


    Feb 15, 2019
    I've been zeroing out the 3D component values in the velocities and positional data found in physics world during it's construction:
    Code (CSharp):
    1. [BurstCompile]
    2. private unsafe struct ConstrainJob : IJob
    3. {
    4.     public int Linear, Angular, World, Body, Pos;
    6.     public NativeArray<MotionVelocity> Velocity;
    7.     public NativeArray<MotionData>     Data;
    9.     public void Execute()
    10.     {
    11.         var vel = (MotionVelocity*)Velocity.GetUnsafePtr();
    13.         // * Fixed zero value.
    14.         var zC = 0;
    16.         // * Shift pointer to access Z variable of linear velocity and zero it out.
    17.         void* destination = (float*)((byte*)vel + Linear) + 2;
    18.         UnsafeUtility.MemCpyStride(destination, sizeof(MotionVelocity), &zC,
    19.             0, sizeof(int), Velocity.Length);
    21.         // * Fixed float2 zero value.
    22.         float2 xyC =;
    24.         // * Shift pointer to access XY fields of angular velocity and zero them out.
    25.         destination = (byte*)vel + Angular;
    26.         UnsafeUtility.MemCpyStride(destination, sizeof(MotionVelocity), &xyC,
    27.             0, sizeof(float2), Velocity.Length);
    29.         var dat = (MotionData*)Data.GetUnsafePtr();
    31.         // * Shift pointer to access WorldFromMotion (RigidTransform) and then the Z variable of its position.
    32.         destination = (float*)((byte*)dat + World + Pos) + 2;
    33.         UnsafeUtility.MemCpyStride(destination, sizeof(MotionData), &zC,
    34.             0, sizeof(int), Data.Length);
    35.     }
    36. }
    I did not zero out rotational quaterion due to the computational difficulties of converting to euler then converting back to quat. However, I have not noticed any XY rotations emerging following collisions between rigidbodies following the constraints enforced in the job above.
  6. Gekigengar


    Jan 20, 2013
    Planning to use Unity's DOTS Physics to resolve collision in an RTS. It will require both Determinism and a large amount of simulation. I believe DOTS is more suitable for my case.

    I actually end up using both KD-Tree and AABBTree for shape and distance queries.
    Meaning I do not have to resort in waiting for Unity's 2D Physics solution, nor tanking some additional physics overhead that cannot be decoupled.
  7. abramsmatthew99


    Mar 16, 2021
    I know I’m a bit late here, but when you say you run this job on construction, could you be a bit more specific? I’m just learning the ECS design and I’m looking into as much as I can to build this 2d game.
  8. Kmsxkuse


    Feb 15, 2019
    This is the entire system, slightly touched up from the previous code sample as to not require finding the individual field offsets and instead just uses a pointer.

    Code (CSharp):
    1. using Unity.Burst;
    2. using Unity.Collections;
    3. using Unity.Collections.LowLevel.Unsafe;
    4. using Unity.Entities;
    5. using Unity.Jobs;
    6. using Unity.Mathematics;
    7. using Unity.Physics;
    8. using Unity.Physics.Systems;
    10. namespace Multiplayer.Shared.Systems
    11. {
    12.     [UpdateInGroup(typeof(PhysicsSystemGroup))]
    13.     [UpdateAfter(typeof(PhysicsSimulationGroup))]
    14.     [UpdateBefore(typeof(ExportPhysicsWorld))]
    15.     [RequireMatchingQueriesForUpdate]
    16.     public partial struct ConstrainPhysicsTo2D : ISystem
    17.     {
    18.         [BurstCompile]
    19.         public void OnCreate(ref SystemState state)
    20.         {
    21.             state.RequireForUpdate<PhysicsWorldSingleton>();
    22.         }
    24.         [BurstCompile]
    25.         public void OnUpdate(ref SystemState state)
    26.         {
    27.             ref PhysicsWorldSingleton physics = ref SystemAPI.GetSingletonRW<PhysicsWorldSingleton>().ValueRW;
    29.             state.Dependency = new ConstrainJob
    30.             {
    31.                 Velocity = physics.MotionVelocities,
    32.                 Data     = physics.MotionDatas
    33.             }.Schedule(state.Dependency);
    34.         }
    36.         [BurstCompile]
    37.         private unsafe struct ConstrainJob : IJob
    38.         {
    39.             public NativeArray<MotionVelocity> Velocity;
    40.             public NativeArray<MotionData>     Data;
    42.             public void Execute()
    43.             {
    44.                 // * Fixed zero value.
    45.                 var zC = 0;
    47.                 // * Fixed float2 zero value.
    48.                 float2 xyC =;
    50.                 var vel = (MotionVelocity*)Velocity.GetUnsafePtr();
    52.                 // * Shift pointer to access Z variable of linear velocity and zero it out.
    53.                 UnsafeUtility.MemCpyStride(&vel->LinearVelocity.z, sizeof(MotionVelocity),
    54.                     &zC, 0, sizeof(int), Velocity.Length);
    56.                 // * Shift pointer to access XY fields of angular velocity and zero them out.
    57.                 UnsafeUtility.MemCpyStride(&vel->AngularVelocity, sizeof(MotionVelocity),
    58.                     &xyC, 0, sizeof(float2), Velocity.Length);
    60.                 var dat = (MotionData*)Data.GetUnsafePtr();
    62.                 // * Shift pointer to access WorldFromMotion (RigidTransform) and then the Z variable of its position.
    63.                 UnsafeUtility.MemCpyStride(&dat->WorldFromMotion.pos.z, sizeof(MotionData),
    64.                     &zC, 0, sizeof(int), Data.Length);
    66.                 UnsafeUtility.MemCpyStride(&dat->BodyFromMotion.pos.z, sizeof(MotionData),
    67.                     &zC, 0, sizeof(int), Data.Length);
    68.             }
    69.         }
    70.     }
    71. }
    The key part of this is "[UpdateBefore(typeof(ExportPhysicsWorld))]" in the header and schedules this system to run before physics gets applied to various entities. This is the construction element I was mentioning, where just before the physics data gets exported to the regular transform component, non-2D values need to be clamped to 0.

    Again, this section of code does not prevent rotation along XY euler angles as solving from quaternion -> euler was a bit too expensive.
  9. Okari-Draconis


    Sep 2, 2013

    Would you be willing to go into more detail, or give me a reference to something? I'm trying to prevent the ration of sprites during collision