位置や方向の計算
自分から見た相手の向きと距離を求める
//自分=A、相手=Bとする。(AとBはGameObject) Vector3 v = B.transform.position - A.transform.position;
↑を解説すると
Unityのワールド座標の原点の位置が(0,0,0)なのでtransform.positionが原点からみた位置ベクトルになる。青矢印はAの位置ベクトル、緑矢印がBの位置ベクトルになる。Aから見たBの方向と距離はオレンジのベクトルになる。
ベクトルBからベクトルAを引いてみると赤線になる
赤線とオレンジの線は同等なので
ベクトルB ー ベクトルA = オレンジの線 = Aから見たBの方向と距離
自分から見た相手との距離を求める
//相手=targetとする。3D空間でのベクトルの大きさ=距離 float norm = (target.transform.position - gameobject.transform.position).magnitude;
magnitudeの中身は
で、ベクトルの長さを求めている
自分から見た相手の方向を求める
//相手=target(GameObject)とする //相手から自分の位置を引いている解説は↑ //自分から見た相手の方向と距離を正規化すると方向になる Vector3 v = (target.transform.position - gameobject.transform.position).normalized;
Vector3.normalizedの中身はベクトルを
で割っている
自身がカメラの前にいるか、後ろにいるか
対象のワールド座標をカメラのローカル座標に変換することでカメラから見てどの位置にいるのかがわかります。
Vector3 v = Camera.main.transform.InverseTransformPoint(transform.position); if (v.z > 0) { Debug.Log("カメラの前にいる"); } else if (v.z < 0) { Debug.Log("カメラの後ろにいる"); }
物理的な計算
物体の現在の速さを求める
Rigidbody rb = GetComponent<Rigidbody>(); float speed = rb.velocity.magnitude;
角加速度を求める
//waを角加速度とする。角加速度=dw/dt(wは角速度、tは時間)
Vector3 oldAngularVelocity = new Vector3(); private void Start() { Rigidbody rb = GetComponent<Rigidbody>(); } private void Update() { Vector3 wa = (rb.angularVelocity - oldAngularVelocity) / Time.deltaTime; oldAngularVelocity = rb.angularVelocity; }
現在のトルクを求める
//角加速度は↑のwa
//慣性モーメントテンソルを対角化したものがinrtiaTensorで、その際に用いた3次元回転行列がinertiaTensorRotationなので(3次元回転行列×対角行列×逆3次元回転行列)で元に戻せる //そのため慣性モーメントテンソル=Ir * Id * IrIとなる //トルク=慣性モーメントテンソル×角加速度 Vector3 oldAngularVelocity = new Vector3(); private void Start() { Rigidbody rb = GetComponent<Rigidbody>(); } private void Update() { Vector3 wa = (rb.angularVelocity - oldAngularVelocity) / Time.deltaTime; oldAngularVelocity = rb.angularVelocity; Vector3 Id = rb.inertiaTensor; Quaternion Ir = rb.inertiaTensorRotation; Quaternion IrI = Quaternion.Inverse(Ir); Vector3 torque = Ir * Vector3.Scale(Id , IrI * wa); }