Whats the problem with bodies inside children?

I have a sprite with a body. and it have 4 children, each one with a body (trigger)
When the sprite moves, it moves with him the 4 children…
but there is a huge delay between the movement, the parent moves first, and a lot later, (probably more than one frame update) THEN the children updates their position…

the higher the speed, the bigger the offset.
Im using this to add the children and bodies:

if(requiresBodyInChild)
{
     auto child = cocos2d::Node::create();
     addChild(child);
     child->setPhysicsBody(body);
}
else
{
     setPhysicsBody(body);
}

And Im letting the physics world to update the body and positions…

How to get rid of this offset???
why is it happening?
I also have tried to explicitly update the children nodes, but doesnt work.

Try with manual physics step in update.
setAutoStep(false) for physics.
You will find code in cpp-test

its being used :frowning:
My update looks like this:

getPhysicsWorld()->step(dt);
actionLayer->update(dt);
getDefaultCamera()->update(dt);

actually changing it to the same update only made it less visible, but the problem still is there.

Instead of this, try like this…

for (int i = 0; i < 3; ++i)
{
       this->getScene()->getPhysicsWorld()->step((1.0f / 180.0f));
}

I tried it, and is not a real solution, since only works 3 times harder, and is not precision for movement or collision what its missing.
What I need, is just to update both at same time. but I cant achieve it anyhow.

However, the offset is smaller, as long as the body doesnt move too fast.
I guess I give up with this.

Can you give me the minimum code for this to reproduce?
I will check from my-side.

the code is distributed in many files, but ill try to put here the minimum necesary.
A lot of info is missing in this semi code, since im using a lot of helper classes and utils. But this is actually all you need ( the player , children, and physics settings)

The character class

class PhysicsCharacter : public virtual cocos2d::Node
{
public:

~PhysicsCharacter();

virtual void AttachBody(const std::string& bodyName, cocos2d::PhysicsBody * body);
cocos2d::PhysicsBody* CreateCircleBody(
	ColliderTags tag,
	float radius = 50.0f,
	const cocos2d::Vec2 offset = cocos2d::Vec2::ZERO,
	bool isDynamic = true,
	bool isSensor = false
);


protected:
cocos2d::Sprite* display;
//colliders
cocos2d::PhysicsBody* bodyMov;

// helper colliders
cocos2d::PhysicsBody* bodyHelperL;
cocos2d::PhysicsBody* bodyHelperR;
cocos2d::PhysicsBody* bodyHelperTL;
cocos2d::PhysicsBody* bodyHelperTR;
std::map<std::string, cocos2d::PhysicsBody*> bodiesByName;
};

The character init

bool PhysicsCharacter ::Init()
{
if(display = Sprite::CreateWithTexture("blabla.png"))  <------ pseudocode
{
	bodyMov = CreateCircleBody(_TAG::PLAYER, 50.0f, { 0,40 });
	AttachBody("player", bodyMov);

	bodyHelperTL	= CreateCircleBody(_TAG::PLAYER_HELPER, 35.0f, { -35,75 }, false, true); //  ~ dynamic , sensor
	bodyHelperTR	= CreateCircleBody(_TAG::PLAYER_HELPER, 35.0f, {  35,75 }, false, true); //  ~ dynamic , sensor
	bodyHelperL	= CreateCircleBody(_TAG::PLAYER_HELPER, 35.0f, { -35, 5 }, false, true); //  ~ dynamic , sensor
	bodyHelperR	= CreateCircleBody(_TAG::PLAYER_HELPER, 35.0f, {  35, 5 }, false, true); //  ~ dynamic , sensor
	
	AttachBody("helper", bodyHelperL);
	AttachBody("helper", bodyHelperR);
	AttachBody("helper", bodyHelperTL);
	AttachBody("helper", bodyHelperTR);

	return true;
    }
    return false;
}

character - CreateBody:

cocos2d::PhysicsBody * PhysicsCharacter::CreateCircleBody(ColliderTags tag, float radius, const cocos2d::Vec2 
offset, bool isDynamic, bool isSensor)
{
cocos2d::PhysicsBody* body = cocos2d::PhysicsBody::create();

auto shape = cocos2d::PhysicsShapeCircle::create(radius);
body->addShape(shape);
body->setPositionOffset(offset);
body->setDynamic(isDynamic);
shape->setSensor(isSensor);

body->setAngularDamping(0.0f);
body->setLinearDamping(0.0f);
body->setRotationEnable(false);
///  collision masks settings here
return body;
}

character - Attach body

void PhysicsCharacter::AttachBody(const std::string& bodyName, cocos2d::PhysicsBody * body)
{
	if(tag == _TAG::PLAYER_HELPER)
	{
	    auto child = cocos2d::Node::create();
            addChild(child);
	    child->setPhysicsBody(body);
	}
	else
	{
		setPhysicsBody(body);
	}
	body->retain();
	bodiesByName.insert({ bodyName ,body }); // keep a reference by name
}

The scene setup

   Scene::Initialize
{
    getPhysicsWorld()->setAutoStep(false);
    //getPhysicsWorld()->setSubsteps(4);             <<---- previous tests.  result:  FAIL
    //getPhysicsWorld()->setUpdateRate(120);        <<---- previous tests.  result:  FAIL
    getPhysicsWorld()->setSpeed(5.0f);
    getPhysicsWorld()->setGravity(Vec2(0, -98));
    getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);

    schedule(schedule_selector(GS_1::update), 1.0f / 60.0f);  // default Node::update
    schedule(schedule_selector(GS_1::Update), 1.0f / 90.0f);	// physics & logic

    CHARACTER = PhysicsCharacter::Create();
    if(CHARACTER )
    {
	CHARACTER ->setPosition(250, 180);
        actionLayer->addChild(CHARACTER );
	cameraTarget = CHARACTER ;
    }
}


void Scene::update(float dt)
{
    if(cameraTarget)
    {
	auto targetPos = cameraTarget->getPosition();
	UI->setPosition(targetPos);
	getDefaultCamera()->setPosition(targetPos);
    }
    getDefaultCamera()->update(dt);
    Node::update(dt);
}

void Scene::Update(float dt)
{
    for(int i = 0; i < 4; i++)
    {
	getPhysicsWorld()->step(dt);
    }

    actionLayer->update(dt);
}