Are there any plans for DOTS Physics2D? Or will it only be Tiny only feature? (Which is indefinitely paused right now)
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.
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]( Unity Physics Discussion page-7#post-4460308) 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.
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.
I’ve been zeroing out the 3D component values in the velocities and positional data found in physics world during it’s construction:
[BurstCompile]
private unsafe struct ConstrainJob : IJob
{
public int Linear, Angular, World, Body, Pos;
public NativeArray<MotionVelocity> Velocity;
public NativeArray<MotionData> Data;
public void Execute()
{
var vel = (MotionVelocity*)Velocity.GetUnsafePtr();
// * Fixed zero value.
var zC = 0;
// * Shift pointer to access Z variable of linear velocity and zero it out.
void* destination = (float*)((byte*)vel + Linear) + 2;
UnsafeUtility.MemCpyStride(destination, sizeof(MotionVelocity), &zC,
0, sizeof(int), Velocity.Length);
// * Fixed float2 zero value.
float2 xyC = float2.zero;
// * Shift pointer to access XY fields of angular velocity and zero them out.
destination = (byte*)vel + Angular;
UnsafeUtility.MemCpyStride(destination, sizeof(MotionVelocity), &xyC,
0, sizeof(float2), Velocity.Length);
var dat = (MotionData*)Data.GetUnsafePtr();
// * Shift pointer to access WorldFromMotion (RigidTransform) and then the Z variable of its position.
destination = (float*)((byte*)dat + World + Pos) + 2;
UnsafeUtility.MemCpyStride(destination, sizeof(MotionData), &zC,
0, sizeof(int), Data.Length);
}
}
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.
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.
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.
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.
using Unity.Burst;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using Unity.Entities;
using Unity.Jobs;
using Unity.Mathematics;
using Unity.Physics;
using Unity.Physics.Systems;
namespace Multiplayer.Shared.Systems
{
[UpdateInGroup(typeof(PhysicsSystemGroup))]
[UpdateAfter(typeof(PhysicsSimulationGroup))]
[UpdateBefore(typeof(ExportPhysicsWorld))]
[RequireMatchingQueriesForUpdate]
public partial struct ConstrainPhysicsTo2D : ISystem
{
[BurstCompile]
public void OnCreate(ref SystemState state)
{
state.RequireForUpdate<PhysicsWorldSingleton>();
}
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
ref PhysicsWorldSingleton physics = ref SystemAPI.GetSingletonRW<PhysicsWorldSingleton>().ValueRW;
state.Dependency = new ConstrainJob
{
Velocity = physics.MotionVelocities,
Data = physics.MotionDatas
}.Schedule(state.Dependency);
}
[BurstCompile]
private unsafe struct ConstrainJob : IJob
{
public NativeArray<MotionVelocity> Velocity;
public NativeArray<MotionData> Data;
public void Execute()
{
// * Fixed zero value.
var zC = 0;
// * Fixed float2 zero value.
float2 xyC = float2.zero;
var vel = (MotionVelocity*)Velocity.GetUnsafePtr();
// * Shift pointer to access Z variable of linear velocity and zero it out.
UnsafeUtility.MemCpyStride(&vel->LinearVelocity.z, sizeof(MotionVelocity),
&zC, 0, sizeof(int), Velocity.Length);
// * Shift pointer to access XY fields of angular velocity and zero them out.
UnsafeUtility.MemCpyStride(&vel->AngularVelocity, sizeof(MotionVelocity),
&xyC, 0, sizeof(float2), Velocity.Length);
var dat = (MotionData*)Data.GetUnsafePtr();
// * Shift pointer to access WorldFromMotion (RigidTransform) and then the Z variable of its position.
UnsafeUtility.MemCpyStride(&dat->WorldFromMotion.pos.z, sizeof(MotionData),
&zC, 0, sizeof(int), Data.Length);
UnsafeUtility.MemCpyStride(&dat->BodyFromMotion.pos.z, sizeof(MotionData),
&zC, 0, sizeof(int), Data.Length);
}
}
}
}
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.
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