さて、約2時間のいじくりの後で、なんとかこれを行うことができました。あなたはおそらくこれをメソッド/クラスに抽出したいと思うでしょうが、基本的な考え方はこれです:
オブジェクトの「ホルダー」ボディと呼ぶものを作成します。これらのボディは「オブジェクト」のサイズと位置を共有しますが、衝突には関与しません。基本的に、それらはクローンです。
//Create "Main" (center) body
_bodyMain = BodyFactory.CreateRectangle(World, 5f, 5f, 1f);
_bodyMain.BodyType = BodyType.Dynamic;
_bodyMain.Position = new Vector2(2, 2);
//Create "MainHolder"
_bodyMainHolder = BodyFactory.CreateRectangle(World, 5f, 5f, 1f);
_bodyMainHolder.BodyType = BodyType.Dynamic;
_bodyMainHolder.CollisionCategories = Category.None; //Prevents collisions
_bodyMainHolder.Position = new Vector2(2, 2);
_bodyMainHolder.IsSensor = true;
//See http://farseerphysics.codeplex.com/discussions/222524 for why they're sensors
_bodyMainHolder.FixedRotation = true;
//Note: Only add FixedRotation for the main one, leave it off of the other
// holders. I'll explain later.
を使用して各ホルダーを「mainHolder」に取り付けますWeldJoint
。これは、彼らが互いに離れることを防ぎます。FixedRotation
mainHolderの回転を防ぎます。farseerにバグがあるかどうかはわかりませんが、aを追加し
WeldJoint
て両方のボディにがあるFixedRotation == true
と、ジョイントが正しく機能しません。これが、メインホルダーだけが持っている理由.FixedRotation = true
です。
//Weld the holders together so they don't move. Assumes another holder is defined
// for the object on the right side (bodyRightHolder).
JointFactory.CreateWeldJoint(World, _bodyMainHolder, _bodyRightHolder,
_bodyRightHolder.Position - _bodyMainHolder.Position, Vector2.Zero);
「オブジェクト」本体を、RevoluteJoint
s を使用してそれぞれのホルダーに接続します。これにより、オブジェクトがホルダーにロックされますが、ホルダーは自由に回転できます。
//Lock the actual bodies to the holders
JointFactory.CreateRevoluteJoint(World, _bodyMainHolder, _bodyMain, Vector2.Zero);
JointFactory.CreateRevoluteJoint(World, _bodyRightHolder, _bodyRight, Vector2.Zero);
アングルジョイントを取り付けて、実際のオブジェクトの回転を互いに一致させます。注:オブジェクトのすべてのペアにアングルジョイントをアタッチする必要はありません。角度ジョイントをメインボディと他のボディに追加するだけで、回転がすべてのオブジェクトにわたって移動します。
//Make them rotate the same as each other
JointFactory.CreateAngleJoint(World, _bodyMain, _bodyRight);
それでおしまい!必要な他のオブジェクト/オブジェクトホルダーごとに追加のコードを追加するだけで、残りのコードが処理されます。これが私のテストを説明するための画像です:
ここで、緑色のボディがホルダーです。それらは回転したり衝突したりせず、一緒に溶接されます。黄色と赤のボディが「オブジェクト」です(黄色がメインです)。同じ量だけ回転し、それぞれのホルダーを中心に回転していることがわかります。また、赤と黄色のボディだけが衝突に参加します。これは上記の3つの条件をすべて満たしていると思います。
Farseerの "Samples XNA"ソリューションをロードしてSimpleDemo1.cs( "Samples XNA"プロジェクト> "Samples"フォルダー)を見つけたら、テストするために書き直しました(コードはこちら)。