
物理ベースのキャラに実在感を与える、いくつかの手法を示します。
振り向かせる
顔の向きを利用者に追随させるのに、物理ベースのキャラでもLookAt()が使えます。
これはキネマティクスのアニメーションを、ダイナミクスに変換する要領と同じですーーまず次のように空のオブジェクトを配置し:
- ・
 - キャラの首の、子ノードにする
 - ・
 - キャラの頭と、同じ位置に置く
 
次いで空オブジェクトをLookAt()で利用者の方へ向ければ、首と頭(が向くべき方向)のローカルの角度差が得られますーーあとはそれをConfigurableJoint のターゲットに設定することで、物理演算による、キャラの頭の回転が実行されます:[※1]
public GameObject objhed, objtgt;
private GameObject objvir, objpar;
private ConfigurableJoint cfjhed;
private Quaternion rotini;
private void Start() {
  rotini=objhed.transform.localRotation;
  cfjhed=objhed.GetComponent<ConfigurableJoint>();
  objpar=cfjhed.connectedBody.gameObject;
  objvir=new GameObject();
  objvir.transform.parent=objpar.transform;
}
private void Update() {
  objvir.transform.position=objhed.transform.position;
  objvir.transform.LookAt(objtgt.transform);
  cfjhed.SetTargetRotationLocal(objvir.transform.localRotation,rotini);
}
- ※1
 - ここでも、ConfigurableJoint の機能を拡張する次のメソッドを使います:
 - ・
 - https://gist.github.com/mstevenson/7b85893e8caf5ca034e6
 
物理的な反応をほどこす(重みや抵抗を感じさせる)
XR上のキャラクタに、もっともらしい物理的な反応をほどこす(利用者に重みや抵抗を感じさせる)には、次のような物理特性を調整します:[※1][※2]
- ・
 - Rigidbody.mass
 - ・
 - Rigidbody.drag
 - ・
 - Rigidbody.angularDrag
 - ・
 - Collider.material (PhysicMaterial.dynamicFriction)
 - ・
 - Collider.material (PhysicMaterial.staticFriction)
 - ・
 - Collider.material (PhysicMaterial.bounciness)
 - ・
 - ConfigurableJoint.slerpDrive (JointDrive.positionSpring)
 - ・
 - ConfigurableJoint.slerpDrive (JointDrive.positionDamper)
 - ・
 - ConfigurableJoint.slerpDrive (JointDrive.maximumForce)
 
- ※1
 - とはいえ、この調整にも限界がありますーーひとつはコントローラに物理演算を適用できないためですねーーキャラクタはダイナミクス(優先:Rigidbody )で演算するのに対し、コントローラを利用者の腕や指の動きに追随させるには、キネマティクス(優先:Transform )で演算するしかありません。XRの利用者は、XRのキャラクタに対し無限大の力で対応することになるので、どうしてもムリは出ますーーこれを解決するには、ジャイロなどコントローラそのものの改良が必要になるでしょうか。
 
- ※2
 - もちろんそれなりに回避策はありますーーたとえば一部のアプリ(VaM, etc. )は、空間にキャラクタを<ピン留め>することで、重みや抵抗の感覚を実現していますーーただそういったやり方では、キャラクタが自律的に動くことができないので(強化学習による自律歩行など)、汎用性という点で限界がありますし……
 
