Я не видел отношений с родителями в Box2d, кроме отношений body/fixture.
Мне кажется, что у вас есть obj1 и obj2, ссылающиеся на тот же объект с выделенной памятью Box2d (тело). Например, если вы удаляете obj1, вы, вероятно, удаляете прикрепленное к нему тело (делая что-то вроде world-> DestroyBody (...)). В следующем обновлении box2d вы ссылаетесь на объект, который вы не выделили, и сказали, что он уничтожен (в систему Box2d). Возможно, это проблема?
Я также вижу, что вы делитесь креплением между объектами obj2 и obj1. Что произойдет, когда obj1 будет восстановлен системой box2d (т. Е. Вы уничтожили тело obj1)? Это не кажется правильным ... система не знает о ваших родительских отношениях, а C++ не имеет встроенной в нее системы подсчета ссылок. Это также может быть проблемой.
Если ваша цель состоит в том, чтобы один объект GameObject управлял несколькими телами (т. Е. Рой чего-то), то пусть единственный GameObject поддерживает список нескольких тел и управляет ими всеми.
Однако, я считаю, вы хотите, чтобы все они двигались так, как если бы они были прикреплены. Насколько я знаю, существует всего два способа заставить два тела вести себя как «один».
Вариант № 1: Первый - использовать соединение между ними. Я сделал это в игре, в которой у меня был космический корабль, который врезался в оружие, чтобы забрать его. Когда корабль сделал это, я создал призматический сустав, чтобы ружье показалось «встать» перед кораблем. Это код, который я использовал для его подключения:
void BulletLauncherEntity::CreateJointConnection()
{
Entity* owner = GetOwner();
Body& ownerBody = owner->GetBody();
// We put the position of this at the tip of the
// owner.
float32 launcherDist = 0.5*(owner->GetScale())*Constants::SCALE_TO_METERS_RATIO();
float32 launcherSize = 0.5*GetScale()*Constants::SCALE_TO_METERS_RATIO();
// Joint along axis of entity
b2PrismaticJointDef jointDef;
// Note that the "Initialize" function in the
// jointDef did not really give us what we wanted.
jointDef.bodyA = &ownerBody;
jointDef.bodyB = &GetBody();
jointDef.localAnchorA = Vec2(launcherDist-launcherSize,0);
jointDef.localAnchorB = Vec2::Zero();
jointDef.localAxisA = Vec2(1,0);
jointDef.referenceAngle = 0;
jointDef.lowerTranslation = -launcherDist;
jointDef.upperTranslation = 0.5*GetScale()*Constants::SCALE_TO_METERS_RATIO();
jointDef.enableLimit = true;
jointDef.maxMotorForce = 2.0;
jointDef.motorSpeed = 0.25;
jointDef.enableMotor = true;
jointDef.collideConnected = false;
ownerBody.GetWorld()->CreateJoint(&jointDef);
}
Вы также можете использовать сварное соединение.
HOWEVER, согласно руководству, используя сварные швы, не создает «жесткое» соединение. Он имеет некоторую мягкость, потому что при столкновении необходимо соблюдать ограничения.
из руководства:
сварного соединения попытки ограничить все относительное движение между двумя телами. См. Cantilever.h в испытательном стенде, чтобы увидеть, как ведет себя сварной шов . Заманчиво использовать сварное соединение для определения разрушаемых конструкций . Тем не менее, решатель Box2D является итеративным, поэтому суставы представляют собой бит . Поэтому цепи тел, соединенные сварными швами, будут изгибаться. Вместо этого лучше создать обрывающие тела, начиная с одного тела с несколькими светильниками. Когда тело ломается, вы можете уничтожить светильник и воссоздать его на новом корпусе. См. Пример Breakable в тестовом стенде .
Я не пробовал проверить это или посмотреть, как «жесткие» другие типы соединений. Когда я использовал призматический сустав, мне показалось, что он довольно твердый. Но во время столкновений он иногда «толкается».
Вариант № 2: Прикрепите его как приспособление непосредственно к корпусу. Я думаю, вам нужно будет уничтожить старое тело и создать для него новый набор светильников.
Было ли это полезно?