建設とUnity

Unityを使って、建設業界向けのソフトを開発するノウハウを紹介します。

【親子関係】Unityでメッシュの中心位置とtransformの位置を一致させる方法

CADなどで作成した3DデータをUnityで読みこんでみると、 メッシュの中心位置とtransformの位置が一致していないことがあります。

たとえば以下の画像のように、transformの位置は(0, 0, 0)ですが、メッシュの中心位置は(2, 6, 4)にきています。

f:id:sayadoki:20211231105115p:plain

開発しているソフトが単純なビューワーソフトで、オブジェクトを移動・回転させる予定がなければ、特に問題はありません。

しかし、たとえばオブジェクトをメッシュの中心位置で回転させる場合は、 オブジェクトのメッシュの中心位置とtransformの位置が一致していないことで実装が煩雑になってしまいます。

今回は、オブジェクトのメッシュの中心位置とtransformの位置を一致させる方法を紹介します。

エディタで設定する方法

Unityではtransformの親子関係が非常に重要です。

以下の画像のように、空のゲームオブジェクト(親)を生成して、メッシュの中心位置である(2, 6, 4)に設定します。この状態でメッシュの中心位置にtransformがきているのがわかります。

f:id:sayadoki:20211231111832p:plain

次に、メッシュを読みこんでいたオブジェクト(子)を親にドラッグして、親子関係にしましょう。その結果、子の位置は(-2, -6, -4)になります。

f:id:sayadoki:20211231112221p:plain

一方、親を確認してみると、先ほどと同じように子のメッシュの中央位置にtransformがある状態のままになっています。

f:id:sayadoki:20211231112320p:plain

この状態で親を移動、回転させることで、子のメッシュ中心位置でオブジェクトを操作することができます。

スクリプトで設定する方法

以上の設定を、スクリプトで設定してみましょう。

以下のスクリプトで、メッシュを読みこんでいる箇所は以下の記事を参照してください。

【Blender→Unity】STLのランタイム読込とZ-up・右手系からY-up・左手系への変換方法 - 建設とUnity

var child  = new GameObject("Child");
var parent = new GameObject("Parent");
child.transform.parent = parent.transform;

var mf = child.AddComponent<MeshFilter>();
var mr = child.AddComponent<MeshRenderer>();

// StlToUnityMeshは別記事参照
mf.sharedMesh = StlToUnityMesh(FullPath);
mr.material.color = Color.white;

var center = mr.bounds.center;
parent.transform.localPosition =   center;
child .transform.localPosition = - center;

ちなみにbounds.centerは重心位置ではなく、メッシュのバウンディングボックスの中心位置です。 重心位置が必要になる場合、別途計算するか、計算結果を取得して利用するようにしましょう。