AIプログラムとかUnityゲーム開発について

探索や学習などを活用したAI系ゲームを作りたいと思います。

IKを使って銃口を動かす

 mecanimのhumanoidのキャラの手の動きなどはanimatorの動きで制御されていますが、銃を打つ場合など、銃口をターゲットに向けて打てるとよりリアルになります。
 そこでIKを使って、スクリプトで銃口(というか右手)を動かす仕組みをやってみました。

 こちらのサイトを参考にさせて頂きました(普通の解説サイトがやってないようなマニアックな技術を公開されていて、非常に勉強になります)
gametukurikata.com

 まずIKを作用させたいmecanimキャラのAnimatorについて、遷移図の左横のLayersタブを選択して、Base Layerの設定から「IK pass」にチェックを入れておく必要があります。


 SetIkPositionは、対象の部分を、どこに動かしたいかを座標で指示します。
 そして、SetIKPositionWeight関数は、元の位置から指示した座標まで0から1で移動を反映させます(1でゴールに移動。0でスタート位置。0.5で中間位置)
 具体的には以下のように反映量を変数で指定しておきます(初期値0にしておく)
 (0,3,2)は相対的な移動させたい位置です。

Animator anim;
float reach=0;
void Start () {
    anim= GetComponent<Animator>();
}
void OnAnimatorIK() {
    anim.SetIKPositionWeight(AvatarIKGoal.RightHand, reach);
    anim.SetIKPosition(AvatarIKGoal.RightHand, transform.position+new Vector3(0,3,2) );
}

 次に例えば以下のようなコードを書いておけば、上カーソルで右手が上がっていき、下カーソルで右手が下がって行きます。Y座標だけ動かすと体にめり込んだのでZ座標も動かしています。

void Update () {
	if(  Input.GetKeyUp( KeyCode.UpArrow ) )
		reach+=0.02f;
	if(  Input.GetKeyUp( KeyCode.DownArrow ) )
		reach-=0.02f;
}

 実際にカーソルキーで右腕を上下させた画像です。

reach=0(スタート位置)
f:id:yasu9780:20160919205623p:plain
reach=0.08
f:id:yasu9780:20160919205629p:plain
reach=0.24
f:id:yasu9780:20160919205643p:plain
reach=0.58
f:id:yasu9780:20160919205650p:plain

 実際はreach=1.0の座標に動かすには腕が外れないといけなかったらしく、0.58より大きくしてもほとんど動かなかった(^o^)
 IKのIはInverseですが、右手を動かすと逆伝播して右肘、右肩が動くという仕組みです。
 アニメーションを自分で作るのは大変なのでコードで動かせる方が有りがたい。