ゲーム開発を受注しようぜ＜その４＞　キャラクターのモーション遷移を作ろうぜ

ステージ・シーンでの　遷移を次のように書いたが、

![20170413a6b3.png](https://qiita-image-store.s3.amazonaws.com/0/159417/d68ed75a-707f-7356-5b13-6b00092c67f1.png)

この図は　なんで　出口を●で束ねているかというと、

![20170608p1.png](https://qiita-image-store.s3.amazonaws.com/0/159417/95b5c5ad-4727-3ce9-1e7f-c244d30e0207.png)

ある程度　束ねないと　PlantUMLが使っている描画ライブラリが　ぐちゃぐちゃにしてくれるんで、束ねているという理由がある。

そんな工夫を入れていることから、自動で描かれたUML図というのは　そのまま実装すれば　プログラムになる、というほどのものになっていない。

# Qiita に SVG はアップロードできないのか？

```
![undefined]()
```

じゃあ PNG で。５倍ぐらい容量が膨らむし、テキスト・データも絵になってしまうが。

![20170608r1.png](https://qiita-image-store.s3.amazonaws.com/0/159417/7babd9be-1a26-1283-f0ab-ac95068bbd25.png)

UML図の書き方もアレンジしていかないと　実用時に手間を減らしてくれない。

## 図の中で使っているフラグは

- 落下時（下方向に地面がなく、画面下外に出たとき）
- 体力<1
- 非接地時
- 接地時
- 無敵時除く、障害物衝突時
- タックルボタンタップ
- ジャンプボタンタップ
- 一定時間
- 放物線下降時
- 即時
- 〇〇から来たとき　（ダッシュ、ジャンプ、空中、二段空中）

などか。例外的なものもあるので、もう少し調整する。

とりあえず　これらを判定できる　センサー　のようなものを作ればよさそうだ。

### 落下時
(1) カメラの視界から　キャラクターが見えなくなった

「カメラに写っている間のみ処理を行う」テラシュールブログ
http://tsubakit1.hateblo.jp/entry/20131007/1381156232

「イベント関数の実行順」Unity
https://docs.unity3d.com/ja/540/Manual/ExecutionOrder.html

(2) レイキャストを下方向に伸ばし、何も当たらない

### 体力<1
(1) Playerの hp が 1 未満なら

### 非接地時、接地時
(1) isGrounded フラグを見て、真なら接地時

### 無敵時除く、障害物衝突時
(1) Player の isInvincible フラグが偽
(2) 敵オブジェクトに衝突したとき

### タックルボタンタップ　（ジャンプボタン、メニューボタンも同様）
(1) タックルボタン　タップ時

### 一定時間
(1) アニメーターに設定。コンフィグを元に設定できるか？

### 放物線下降時
(1) VelocityY がマイナスのとき

### 即時
(1) 無条件でモーション遷移

### 〇〇から来たとき　（ダッシュ、ジャンプ、空中、二段空中）
(1) 文字列を覚えておくか。dash, jump, sky, doublesky など。


# サブステートマシンの中の　どのステートへ飛ぶかまでは　直接指定できないのか？

入口までは行けるが、その中のどのステートへ行くかまでは　指定できないようだ。

![20170609s1.png](https://qiita-image-store.s3.amazonaws.com/0/159417/c00e1f63-033e-2bff-3e9f-44721a2ecddf.png)

どこから来たのかを from、宛先の中で、どの部署こへ行くのかを to で書き足してみた。

アニメーターのパラメーターにも

- from : string
- to : string

を追加することにする。
"from" や "to" といった文字列は Visual Studio で検索しやすいように const で定数にしておこう。

**と思ったら string 型は使えなかった。int 型で代用するか。**

**それよりもトリガーの方がいいのか。**

![20170609s3.png](https://qiita-image-store.s3.amazonaws.com/0/159417/fa6baffb-6518-39fd-312b-4df4044ce65c.png)

じゃあ、青色字は　トリガーということにする。


# 何フレーム

このモーションのアニメは　何フレーム　だとか、書いていない。
アニメ用の設計書は　別に要るか、
Unityで実装したものが　設計なのか、というところだ。

手元に　提出版の図がある。それによると。

- 待機
- ダッシュ
- タックル
- 地上ダメージ
- ジャンプ上昇
- ジャンプ下降
- 回転上昇
- 回転下降
- 空中ダメージ
- 二段空中ダメージ
- しゃがみ
- ダウン
- 落下

の１３種類のモーションを見た目で区別できれば、動作テストとしては　よさそうだ。

![20170607i1.png](https://qiita-image-store.s3.amazonaws.com/0/159417/ac2491aa-67d9-5348-cdda-bd5fafa1e620.png)

この画像で　１３種類のモーションを用意できるだろうか？
待機がない気がする。

![20170607i2.png](https://qiita-image-store.s3.amazonaws.com/0/159417/d7b193da-05e2-7db2-cf72-6d046b9e8d0e.png)

じゃあ　２枚　描き足そう。


モーションのアニメの登録の仕方は、前の記事で説明した：http://qiita.com/muzudho1/items/4ee198296d620da0b8fa

![20170607j1b1.png](https://qiita-image-store.s3.amazonaws.com/0/159417/3788a295-d155-d56c-4d1e-78cfe4b1e2be.png)

とりあえず、これから作る予定のアニメーション・クリップの　空っぽの新規ファイルを先に作っておく。

- ドープシートに　スプライトを置いていく
- ループするアニメなら、プレイヤー・ゲームオブジェクトと アニメーション・クリップ選択状態で
 Inspectorビューの[Loop Pose]チェックボックスをチェックする

スプライトと　アニメーション・クリップの紐づきは、次に説明する　アニメーター　で行う。

Windowsのファイル・エクスプローラーで .animファイルをリネームすると、プレイヤー・ゲームオブジェクトと　アニメーション・クリップの紐づきが解除されてしまうようだ？

# アニメーター

![20170607k1b.png](https://qiita-image-store.s3.amazonaws.com/0/159417/42a02c53-f07f-7e25-c4b0-07cb67c03d82.png)

アニメーション・クリップの中に１つ混ざっている　アニメーター　というファイルが、このモーション遷移　のデータだ。

![20170607l1b.png](https://qiita-image-store.s3.amazonaws.com/0/159417/8b234169-54bc-5a58-cfce-9a353dd65fff.png)

設計図通りには作れない。「●」とか使って　似たような記述を１くくりにして省略しているところも、省略せずに　線を引く必要がある。

# 着地しているかどうかの判定

参考記事：

「【Unity1】クリックでジャンプ！AddForce, GetButtonDown【ユニティちゃん縦スクロール3】」ひよこのたまご
http://hiyotama.hatenablog.com/entry/2015/04/24/210000

接地しているとき `isGrounded` は真で、空中のとき偽にするわけだ。

いつ真偽を設定するかというと プレイヤーに紐づく Update()メソッドで、その式がこう。

```C#
isGrounded = Physics2D.Linecast ( スタート, エンド, レイヤー);
```

線を放射してみて、コライダーにぶつかったら真なのだろう。
スタートが　キャラクターの中心、
エンドが　足元になるように設定すればいいらしい。

「Physics2D.Linecast」
https://docs.unity3d.com/ScriptReference/Physics2D.Linecast.html

「Transform.up」
https://docs.unity3d.com/ScriptReference/Transform-up.html

ここで、どこをキャラクターの中心と呼ぶかについて、

- **center** 画像の中心なのか
- **bottom** 足元なのか

など別途　設定しているかと思う。Unityでは **画像の中心** とは呼ばず、 **ピボット**（関節の回転軸ぐらいの意味） と呼ぶ。

ひよこのたまご　で解説されている式はこうだ。

```C#
transform.position
```

が、そのピボットのゲーム空間中の３Ｄ位置を覚えている。ここに

```C#
transform.up
```

を足せば、１ゲームオブジェクト分上、という意味になる。

これで足元から１グリッド分上をスタートとして、
足元より１０分の１グリッド分下をエンドとして、線を引いている。

Physics2D.Linecast が　線を引っ張って何かとぶつかっているかを判定してくれるので、
**下半身に線をひっぱって　何かとぶつかっていれば　接地　だ**、という理屈を押さえればＯＫだろう。

レイヤーをスクリプトで設定する例

```C#
// GameObject go;
go.layer = LayerMask.NameToLayer("Ground");
```