Onoty3D

Unityに関するメモとか

IKを試してみよう! Leap Motion編

前記事で試してみたIK。
マウスでオブジェクトを動かすのってなかなか面倒です。
ならば、Leap Motionを使えばもう少し簡単に動かせるのでは!?なんて思いました。

やってみることにします。
まずは環境づくり…。
Leap Motionのアセットをダウンロードしてきます。
https://developer.leapmotion.com/downloads/unity
これもUnity 5では、Pro版が利用可能なので、Download Unity Pro Assetを選択。

これをUnity 5のプロジェクトにインポートすると、コードをアップグレードするか確認されるので、アップグレードします。
それでもエラーが2つ程残り、実行時にもdll周りでエラーがでます。
これに関しては、のびっこさんのブログにタイムリーに解決法が書いてありました。
nobikko-nobinobi.hatenablog.com
これで無事Unity 5でもLeapMotionが使えます。

IK用に作った6つのオブジェクトを手で触れる様にするため、各オブジェクトにRigidBodyを追加します。
そのままだと、IkActiveにチェックを入れた途端にオブジェクトが自由落下してしまうので、UseGravityのチェックを外します。
また、オブジェクトが勝手に回転してプロ生ちゃんの体が怖いことになるので、Rotationも固定します。
f:id:onoty3d:20150316184745p:plain

各Colliderも干渉するので、適当なLayerを切り、互いが干渉しないようにします。
自分の場合、6つのオブジェクトのLayerを"IK"、Leap Motionの手のモデルのLayerを"Hand"として、"IK"は"Hand"にだけ干渉されるようにしました。
f:id:onoty3d:20150316184845p:plain

上手く掴めるようにもう少し細工をします。
LeapMotionのAssetに入っているPinchingSandboxのサンプルを参考に、6つのオブジェクトにGrabbableObject、手のモデルにGrabbingHandのスクリプトを適用させます。
これでオブジェクトを掴んだ時に、こぼれ落ちたりせず、しっかり掴めるようになります。

しかし、外力が加わるのか、オブジェクトから手を離すと、オブジェクトがとんでいってしまいます。
パラメータで制御できるかなと思ったのですが、どうにもうまくいかないので、スクリプトに少し手を加えます。
対象は、GrabbableObject。

オブジェクトを離した瞬間にOnReleaseが呼ばれるのですが、その瞬間にオブジェクトのPositionを固定させます。
次にUpdateが呼ばれた際に、Positionの固定を解除します(解除しないと手で動かせなくなる)。
ソースはこんな感じ(必要箇所だけ抜粋)。
オブジェクトがとんでいかないようにする方法は、別法があるかもしれません。

  private Rigidbody _rigidbody;
  
  public void Awake()
  {
      this._rigidbody = this.GetComponent<Rigidbody>();
  }

  public void Update()
  {
      if ((this._rigidbody.constraints & RigidbodyConstraints.FreezePosition) == RigidbodyConstraints.FreezePosition)
          this._rigidbody.constraints = (this._rigidbody.constraints & ~RigidbodyConstraints.FreezePosition);
  }
  
  public virtual void OnRelease() {
    //既存処理の最後に以下を追加↓
    this._rigidbody.constraints = (this._rigidbody.constraints | RigidbodyConstraints.FreezePosition);
  }

とりあえず以上を施した上での現状。
youtu.be

うーん、なんかもう少しな感じw
微調整が効かないので、結局マウスのほうが早いか…。