Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Temp Run セミナーの原稿

Temp Run

使用するアセット https://www.assetstore.unity3d.com/#/content/9896

完成ゲーム「てんぷらん」 http://unity3d-jp.github.io/TEMPRUN/web%20player/

ドキュメントはこちら http://docs-jp.unity3d.com/

とりあえず出来上がりのゲームを見てみましょう。 まあ某寺院の中を走るゲームを作ります。

環境を揃えましょう

  • 右端の項目を「2 by 3」に
  • Pivot、Globalに

エディタの説明をします

シーンビューの説明

GameObject → Create Other → Cube

オブジェクトを動かす説明

地面

まず地面を作ります。

GameObject → 3D Object → Cube

名前を「Ground」としましょう。

Scale を (5, 1, 100) Position (0, -0.5, 46)

ライト

ハードシャドウも入れましょうか。

Mecanim入門

Assets/Mecanim_GDC2013/Character/TeddyBear

を使います。 これをD&Dするとクマができます。

原点位置に移動するためにリセット

プレイ→何も起きません。

Assets/Mecanim_GDC2013/Character/TeddyBear

に戻って。選択すると、Inspectorに表示が出ます。

このクマは単なる3Dモデルです。アニメーションは入っていません。 大事なのは、「Rig」の項目で Animation Typeが「Humanoid」になっていることと、 Avatar Definitionが「Create From This Model」になっていることです。

これで「Avatar」と呼ばれるものを作ります。

Avatar

Avatarというのは、違うモデルでもAvatarを同じであれば、同じアニメーションを再生してくれるのです 例えばおじさんのアニメーションとクマで再生できないのが普通ですが、Avatarを作って揃えることで、うまく行くということです。

ここで、「Configure」を押すと、別のAvatarシーンに移行しようとします。

ちょうど良い頃合いなので、シーンをセーブしましょう。シーン名「Game」でいいでしょうかね。

ここではAvatarがどの骨とどの部位なのか、ということを割り当てることと、 骨の稼働範囲を設定することができます。

Mappingがどの骨とどの部位なのか、ということを割り当てているのですが、デフォルトでほぼOKです。赤くなっている箇所を修正すればいい。

割り当てなくてもいい部位もあります。例えばChestとかですね。

Musclesで可動範囲とかを調整します。まーぶっちゃけやんなくてもOKです

で、既にできているかと思いますが、TeadyBearのPrefabの下に TeadyBearAvatar というのがありますね。これがAvatarです。

アニメーション

では次にアニメーション、モーション、つまり手とか足とかの動きのデータですね。そちらを見て行きましょう。

それで、どこにデータがあるかというと

Assets/Mecanim_GDC2013/Animation/Clips/

の中ですね。

この例えばRunというDefaultAvatar@RunForward_NtrlFaceFwdというファイルを見てみましょう。

このRigを見て行くと、こちらはAvatar Definitionが「Copy From Other Avatar」となっていますね。つまりこっちはモデルは使わないんですよ、アニメーションだけですよ、ということです。

あとソースは変えた方がいいのでしょうが、どうやらそのまま行けるようです。

で、Animationsを見て行きましょう。

こちらも実は既に設定されているので、それを使いますが、本来であれば必要な箇所だけを切り取るわけです。 例えばRunはここからここまでとなっていますが、 これをかえることでいろいろ調整するわけです。 Revertしておきましょうか。

で、切り出されたアニメーションが、ここでいう「Run」となります。

Animator

ではいよいよ、Animation遷移に取りかかりましょう。遷移というのは移り変わりということですね。

アニメーションというのは単体だけでは意味なくて、他のアニメーションとつなげなくてはそれっぽく見えません。

で、mecanimの凄いところはこのつなぎ目が自動的に滑らかにしてくれるところです。

では AssetsでCreate→Animator Controllerを作って、名前はBearAnimatorControllerとかしておきましょうか。

作ると、「Animator」ウインドウが出ますので、そちらでアニメーション遷移を追加していきます。

追加の方法は簡単で、先ほど作ったアニメーションクリップをD&D

そして先ほどのTeadyBearのAnimatorのControllerにD&D

そして、プレイ

走りましたか?

カメラの同期(親子関係)

クマが向こうに言ってしまうので、CameraをTeadyBearの親子関係にしましょう。

親子関係にするのには簡単で、子供になるカメラを、親になるTeadyBearD&Dするだけ

カメラを適当な場所に移動します。(e.g. Pos(0.0, 2.8 , -2.5), Rot(30, 0, 0))

こでプレイしてみると、一緒に動くかと思います。

つまり、親子関係があれば、親が動けば子が動くということです。

状態 の追加

ではあとはvault(飛び乗る)アクションを追加しましょう。

そして遷移条件をつけましょう。遷移条件はですね、Animatorウィンドウの左上の「Parameters」タブをクリックして、出てきたタブの「+」ボタンを押して「Bool」で、名前を jump で。

矢印を作って、矢印を選択して、

Conditionを、jump=true に、Has Exit Time をオフに

帰りの矢印を作って、同様にビボットグラフを合わせます

プレイしてみましょう。

そしてすかさず Animator の Parametersの jump のチェックをオン!

でジャンプしますか?

しない場合は、おそらくUnity Editorのバグです。

一旦、Conditionを、jump=false にしてみて、強制的にジャンプするようにしましょう。

これでジャンプしましたか?そしたらjump=true に戻して、試してみてください。

Animation Clipの調整

ジャンプばかりしていると、わかるのですが、右にずれて行ってしまいます。

どうやらデフォルトのVautアニメーションの切り出しが、位置が悪いようです。

DefaultAvatar@Vaultを選択して、Endの位置を273

Root Transform Rotation の Based Upon を BodyOrientation 、offsetを 6.3 に

まっすぐ進みました?

これは後ほど、修正しますので、お待ちください。

さらに状態の追加

同様にスライディングも作って行きましょう。

Slideを検索欄に入れて、D&Dで追加

ParametersにBoolで「slide」を追加、Has Exit Time をオフに

Make transitionで遷移を追加して、つなげる。逆も

Run→Slideの遷移を選択して、Conditionをslideに

Root Transform Rotation の Based Upon を BodyOrientation 、offset を 3 に

死ぬ状態への遷移

では、死ぬ状態を作りましょう

Dying を追加

Transition を全ての状態からつなげましょう

Any State からDyingにつなげましょう。

Parameter を Bool で Dead に

矢印を選択して Settings で Can Transition To Self のチェックをはずす

Dying の グラフを手前に

Dying をともに Root Transform Rotation を Original に Root Transform Position(Y) を Original に Root Transform Position(XZ) を Original に

障害物の配置

GameObject → Create Other → Cube

名前をBoxLower

Reset

Scale x を 5 に Z を 0.2 に

Transform を z を適当。例えば 7、 Yも少し下げて、 -0.1

マテリアル

Lower

赤色に

Prefab

D&Dで

二つ目のマテリアルを

BoxHigherにコピーして、

Higherマテリアル

Scale ( 5, 0.7, 0.2 ) Transform Y を 0.9 に

適当に横移動

そして初めてのプログラミング

Projectビューで右クリックからのメニュー

Create → Javascript で (今回は Javascript で統一します)

TeddyBear に D&D

名前は PlayerController で 「Open...」で開く

Start部を削除

var tmpValue : float = 1.0f;

Inspector に 「Tmp Value」 が追加されています。こうやって変数オブジェクトを追加できるんですね。

var anim : Animator;

Inspector のそこの所に TeadyBear 自体をD&D

function Update () {
	anim.SetBool ("jump", Input.GetKeyDown (KeyCode.UpArrow));
	anim.SetBool ("slide", Input.GetKeyDown (KeyCode.DownArrow));
}

動きました?

死ぬ判定

当たったときの死ぬトリガーをつけます。

function OnTriggerEnter ( col : Collider )
{
	anim.SetBool ("dead", true);
}

当たり判定のために Capsule Collider を

Component → Physics → Capsule Collider

Center を 0.57

Radius を 0.26

プレイすると? 当たりません。

これは Rigidbody がないからです。これもつけましょう。

プレイすると?落ちますね?

重力があるからです。Gravityをオフに。

Is Trigger をオンに

これでどうでしょう? すぐ死ぬ場合は地面に当たっているからです。 その場合は当たり判定のカプセルを少しあげましょう。

真の当たりチェックへ

うまくいってそうですけど、これ実は何しても死にます。

なので、まずは走っているときだけはNGにしましょう。

function OnTriggerEnter ( col : Collider )
{
	var state : AnimatorStateInfo = anim.GetCurrentAnimatorStateInfo (0);
	if (state.IsName("Base Layer.Run")) {
		anim.SetBool ("dead", true);
	}
}

で、うまくいってそうですけど、これだと障害物の判定をしていません。

Vaut(ジャンプ) の時は Higher を 死ぬようにして Slide(スライド) の時は Lower を 死ぬようにしなくちゃいけません

function OnTriggerEnter ( col : Collider )
{
	var state : AnimatorStateInfo = anim.GetCurrentAnimatorStateInfo (0);
	if (state.IsName("Base Layer.Run") ||
		(state.IsName("Base Layer.Vaut") && col.CompareTag("Higher")) ||
		(state.IsName("Base Layer.Slide") && col.CompareTag("Lower"))) {
		anim.SetBool ("dead", true);
	}
}

タグの設定

あ、でもこれだけでは不十分です。

タグを設定しましょう。Edit → Project Settings → Tags (または何かのプレファブを選択して、「Add Tag...」で)

一番上の▶をクリック

そこの一番目に「Lower」というのを作りましょう。ついでに2番目に「Higher」というのを作りましょう。大文字小文字間違えないでくださいね

そしてPrefabにタグづけしていきましょう。

BoxLower のプレファブの方を選択して、InspectorのTag をLowerに

同様に BoxHigher のプレファブの方を選択して、Higherに

こうすると、シーン内のオブエジェクトが全て反映されます。

まっすぐ走らせる為にスクリプトの編集

まっすぐ走らせるために以下のスクリプトを一番したに追加しましょう。

function LateUpdate() {
	this.GetComponent(Rigidbody).velocity.x = 0.0f;
}

LateUpdateにしているのは、アニメーションが反映された後に位置をコントローするする場合に位置を反映できる唯一の場所だからです。


チャレンジコーナー

リスタート

function OnGUI()
{
	var state : AnimatorStateInfo = anim.GetCurrentAnimatorStateInfo (0);
	if (state.IsName("Base Layer.Death")) {
		if ( GUI.Button(Rect(30,30,200,80), "Again?") ) {
			Application.LoadLevel(0);
		}
	}
}

ゴール

レーン切り替えとか?

方向転換とか?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment