Hybrid 2d joints weirdness

I have an Entities.ForEach().WithStructuralChanges() in which I instantiate two objects (square and circle) and join them together using a SliderJoint2D on the circle. The objects are both hybrid entities.

protected override void OnUpdate() {
    Entities
    .WithStructuralChanges()
    .ForEach( (ref ShipPrefab sp) => {
        // Instantiate and join parts together
        Entity squareEntity = ShipConstructor.buildShip(ref sp, EntityManager);

        // Add a component to the square. This breaks it for some reason.
        // EntityManager.AddComponentData<TestComponent>(squareEntity, new TestComponent());
    }).Run();
}

This works fine but if I then add the TestComponent to the square after the joint is created but within the same frame, the joint no longer works.
It’s still there and all properties seem to be the same, it just doesn’t do anything.
If I add TestComponent before the joint is created or on the next frame, then there’s no problem.
I’ve checked the joint connected body instance id’s and they still match.

The two pictures show what happens when TestComponent isn’t added (Works) and when it is added (Fails).
I7472255--918269--success.png 7472255--918272--failure.png

The connected anchor (the little solid blue circle) is set 2m left from bottom centre of square.
This anchor point is in correct position in both cases it’s just that in the failed one, the slider joint doesn’t apply any constraints. It just lets the objects move about wherever.
I just can’t work out what’s going on here.

Ok, so I thought I’d just update this myself with the most minimal reproducible example I could create.

I’ve attached the exported scene (10k) if anyone cares to take a look. You need to install packages:
com.unity.entities 0.17.0 p42
com.unity.rendering.hybrid 0.11.0 p44

It just instantiates a square and a circle from two hybrid Entity prefabs and then adds a SliderJoint2D between them.

This works fine, unless you uncomment this one line in ShipPrefabSystem.cs
// EntityManager.AddComponent(square);
Doing that causes the joint not to work though I can’t figure out why.
I don’t know if this is some subtle bug I should send to Unity or if I’m just missing a piece of the puzzle in my understanding of the conversion process.

What does adding a component to a hybrid entity do that could cause any changes at all to those hybrid components?
In my mind, adding a Component should simply copy all the IComponentData’s to another chunk but I wouldn’t imagine that it clones or does anything to the MonoBehaviour components. Am I wrong there? I don’t actually know how Unity deals with or stores the Object based components.
Also my understanding is that these changes are done instantly when WithStructuralChanges is used.

The relevant code is below though I don’t know if anything can be gleaned from it. My guess is the problem lies in some kind of issue with the order of processing.

public class ShipPrefabSystem : SystemBase
{
    EntityQuery _query = new EntityQuery();


    protected override void OnUpdate() {
        Entities
        .ForEach( (Entity entity, ref ShipPrefab sp) => {
            // Instantiate Square
            float3 pos = sp.basePosition;
            Entity square = instantiateAtPosition(EntityManager, sp.square, pos);
          
            // Instantiate Circle
            pos.x -= 1;
            pos.y -= 0.5f;
            Entity circle = instantiateAtPosition(EntityManager, sp.circle, pos);

            // Attach Circle to Square
            float2 squareAnchor = new float2(-1, -0.5f);
            float2 circleAnchor = new float2();
            attachSliderJoint(EntityManager, circle, circleAnchor, square, squareAnchor);

            // Uncomment below line and joint stops working
            // EntityManager.AddComponent<Dummy>(square);
        }).WithStoreEntityQueryInField(ref _query)
        .WithStructuralChanges()
        .WithoutBurst()
        .Run();

        EntityManager.DestroyEntity(_query);
    }


    public static Entity instantiateAtPosition(in EntityManager entityManager, Entity prefab, float3 pos) {
        Entity entity = entityManager.Instantiate(prefab);
        entityManager.GetComponentObject<Transform>(entity).position = pos;
        return entity;
    }


    public static void attachSliderJoint(in EntityManager entityManager, Entity a, float2 anchorA, Entity b, float2 anchorB)
    {
        Rigidbody2D rigidbodyA = entityManager.GetComponentObject<Rigidbody2D>(a);
        Rigidbody2D rigidbodyB = entityManager.GetComponentObject<Rigidbody2D>(b);

        SliderJoint2D joint = rigidbodyA.gameObject.AddComponent<SliderJoint2D>();
        entityManager.AddComponentObject(a, joint);
        joint.autoConfigureAngle = false;
        joint.autoConfigureConnectedAnchor = false;
        joint.enableCollision = false;

        joint.anchor = anchorA;
        joint.connectedAnchor = anchorB;
        joint.angle = 0;
        joint.connectedBody = rigidbodyB;

        joint.useLimits = true;
        joint.limits = new JointTranslationLimits2D{min = 0, max = 1};
    }
}

7506053–925229–SquareCircle.unitypackage (9.81 KB)