かつて代官山らへんで働いてたengineerのUnityブログ

サーバサイドやってきたエンジニアがUnityとか触って遊ぶだけのブログ

【Unity】アニメーションしてる3Dモデルをラグドール化してふっ飛ばしてみる【AdventCalendar】

Unity #2 Advent Calender 2018 22日目を書かせていただきます。

前回はGREAT__SHARKさんのEntity Component System を作って学ぶでした。
ECSそろそろ触っておかなきゃなーと思ってる最中、概念や導入部分から公式サンプルの解説までかなり丁寧に説明してくださっているのでめちゃめちゃありがたかったです!必見!


どうも、くそすけです。
Unity関連でアドベントカレンダーを書くのは2回目になります。
2015年にこんな記事を書いてました。どんなテンションで書いてたのかもう思い出せない...
chroske.hatenablog.com

最近作ってるもの

友人のデザイナーさん達とこんなゲームを作っております。


ゴリラと人間が鬼ごっこする最高にHappy&Wildなゲームです。
誰かを巻き込んで個人開発をするのは初めてだったりするので、ちゃんと完成までもっていかないとなあと思っております。
僕が担当しているのはUnityとリアルタイムサーバの部分です。そうなんですマルチプレイなんです。
めっちゃアクセス来て捌けなかったらどうしようとか皮算用しておりますがまあ大丈夫でしょう。
そんな来ないって
どこかで見かけたら遊んでやってください!
今回はこのゲームでも使っているアニメーションしてるモデルをラグドール化する方法についてです。

ラグドール

TimeLineとかECSとかShaderGraphとか比較的今どきの機能関連でガンガン記事が投稿される中
ラグドール?!って感じかと思いますがラグドールです。僕も思います。ネタがなかった...
洋ゲーなどではお馴染みラグドール。関節がぐにゃぐにゃのあれですね。
和製商業ゲームだとあんまり見かないような気がしますが僕はこの表現が結構好きです。
ではさっそくメニューの[GameObject/3D Object/Ragdoll]からこちらのイケメンゴリラをラグドール化していきます。

ゴリラってかっこいいよね!

ラグドールにアニメーションをつける

Unityのメカニムアニメーションはラグドールを動かすことを多分想定していないので、ラグドールをそのままアニメーションさせようとすると生まれたての子鹿みたいになります。

イケメンが台無しですね

なので各パーツに付与されたRigidbodyのisKinematicをtrueにして物理を無効化してやる必要があります。

void SetKinematic(bool newValue)
{
	Component[] components=GetComponentsInChildren(typeof(Rigidbody));

	foreach (Component c in components)
	{
		(c as Rigidbody).isKinematic=newValue;
	}
}

こんな感じの処理でいいでしょう。GetComponentsInChildrenしてるのでパーツ数が多いと重くなるかもしれませんが。

アニメーションしてるモデルをラグドール化する

さっきtrueにしたisKinematicを今度はfalseにしてアニメーションを止めてやるだけです。
isKinematicを切り替えてからアニメーションを止めてやったほうが綺麗にラグドール化する気がします。誤差の範囲だとは思いますが。

public void ChangeRagdoll()
{
	SetKinematic(false);
	anim.enabled = false;
}


ラグドールをふっ飛ばす

AddForceしてやりましょう。説明は不要ですね。

void Update () {
	if (Input.GetMouseButtonDown(0))
	{
		Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
		RaycastHit hit;
		if (Physics.Raycast(ray,out hit))
		{
			if (hit.rigidbody!=null)
			{
				ChangeRagdoll();

				impactTarget = hit.rigidbody;
				impact = ray.direction * impactPower;
				impactTarget.AddForce(impact,ForceMode.VelocityChange);
			}
		}
	}
}

クリックしたところにrayを飛ばしてそこにAddForceしてやるようにしました。

まとめ

まあ実装するとしたらこんな感じだよねーって内容だったと思います。
特に意外性もないっていう。
物理でなにかしらが動いてるだけでもゲームっぽい雰囲気は出ますし、実装も簡単なのでカジュアルなゲームで使ってみたら面白い演出が出来たりするんじゃないかなーと。

明日はUnity #2 Advent Calender 2018 23日目、投稿者はherieruさんです!Shader関連ですかな?
それでは~~~~