こんにちは、SAT-BOXのコアラです。
今回は↓の記事の続きです。
sat-box.hatenablog.jp
前回の記事では、UnityのCenter座標がどう求められているかを調べました。
Center座標とは↓の画像の通り、PivotではなくCenterになっているときの操作の起点ですね。
今回は、このCenter座標を求める処理を書いてきました。
早速載せます。
using UnityEngine; public class Sample { public static Vector3 GetCenterPosition(Transform target) { //非アクティブも含めて、targetとtargetの子全てのレンダラーとコライダーを取得 var cols = target.GetComponentsInChildren<Collider>(true); var rens = target.GetComponentsInChildren<Renderer>(true); //コライダーとレンダラーが1つもなければ、target.positionがcenterになる if (cols.Length == 0 && rens.Length == 0) return target.position; bool isInit = false; Vector3 minPos = Vector3.zero; Vector3 maxPos = Vector3.zero; for (int i = 0; i < cols.Length; i++) { var bounds = cols[i].bounds; var center = bounds.center; var size = bounds.size / 2; //最初の1度だけ通って、minPosとmaxPosを初期化する if (!isInit) { minPos.x = center.x - size.x; minPos.y = center.y - size.y; minPos.z = center.z - size.z; maxPos.x = center.x + size.x; maxPos.y = center.y + size.y; maxPos.z = center.z + size.z; isInit = true; continue; } if (minPos.x > center.x - size.x) minPos.x = center.x - size.x; if (minPos.y > center.y - size.y) minPos.y = center.y - size.y; if (minPos.z > center.z - size.z) minPos.z = center.z - size.z; if (maxPos.x < center.x + size.x) maxPos.x = center.x + size.x; if (maxPos.y < center.y + size.y) maxPos.y = center.y + size.y; if (maxPos.z < center.z + size.z) maxPos.z = center.z + size.z; } for (int i = 0; i < rens.Length; i++) { var bounds = rens[i].bounds; var center = bounds.center; var size = bounds.size / 2; //コライダーが1つもなければ1度だけ通って、minPosとmaxPosを初期化する if (!isInit) { minPos.x = center.x - size.x; minPos.y = center.y - size.y; minPos.z = center.z - size.z; maxPos.x = center.x + size.x; maxPos.y = center.y + size.y; maxPos.z = center.z + size.z; isInit = true; continue; } if (minPos.x > center.x - size.x) minPos.x = center.x - size.x; if (minPos.y > center.y - size.y) minPos.y = center.y - size.y; if (minPos.z > center.z - size.z) minPos.z = center.z - size.z; if (maxPos.x < center.x + size.x) maxPos.x = center.x + size.x; if (maxPos.y < center.y + size.y) maxPos.y = center.y + size.y; if (maxPos.z < center.z + size.z) maxPos.z = center.z + size.z; } return (minPos + maxPos) / 2; } }
ちょっと長いので詳しい説明は省きますが、この関数にtransformを入れればCenter座標を取得できます。
これでCenter座標求められたわけですが、次はそれを活用する例を紹介します。
ここに人間と額縁があります。
どう見ても人間と額縁ですね。
人間のPivotは足にあり、額縁は中央にあります。
まず単純に、人間を額縁に入れてみたいと思います。
using UnityEngine; public class Sample : MonoBehaviour { public Transform frame; public Transform human; void Start() { human.position = frame.position; } }
こうすると
はみ出しましたね。
これを、Center座標を求めてやれば収まることでしょう。
処理はコチラ↓
using UnityEngine; public class Sample : MonoBehaviour { public Transform frame; public Transform human; void Start() { //Center座標を求める Vector3 humanCenterPos = GetCenterPosition(human); //humanをどれだけ動かすと、Pivotの位置にCenterを持ってこられるか求める Vector3 centerDis = human.position - humanCenterPos; //frameの座標と、humanのPivotとCenterの位置の差を足せば完了 human.position = frame.position + centerDis; } public static Vector3 GetCenterPosition(Transform target)... //略しました }
結果は・・・
頭ぶつけてますが、中央に来ていることが分かります。
このように、Center座標を使って位置を合わせたり色々なことに使えそうです。
以上です。