おはよう。現在Unityを使ってゲームを作っている。
ゲームにて一番大変な作業がスクリプトだと確信している。
始めてC+を触れる人はもちろん、すでに触れている人でも大変だ。
スクリプトを使いこなすと、細かい指定もできるし、
スクリプトなしでできる作業を「あり」で行える。
最小限のスクリプトで済む作業として、アニメーションの移動がある。
例えば歩いたら「止→歩」に切り替えるなどだ。
二通りのやり方を通し、やりやすいほうを選んでほしい。
アニメーションの基本

はじめにアニメーションを動かすための最低条件として、
橙色の矢印を引いてもらわなければならない。
橙色の矢印は一つのアニメーションを登録すると、勝手に設置してくれる。
ここから二通りのやり方でアニメーション設置できる。
一つは遷移を使う(矢印を引く:make transition)方法。
もう一つはスクリプトで直接指定していく方法だ。
遷移を引くやり方は私より下記動画を見たほうが早い。
遷移を使う方法は「遷移を使う」作業が面倒でないうえ、
かなり複雑なアニメーション設定を行うなら使う。
直接スクリプトを使う場合、アニメーション設定がシンプルな場合に使う。
スクリプト指定はこちらの本で詳しく述べている。

現在、私は上記本に沿ってスクリプトを使い、直接指定している。
遷移を使う方法も結局スクリプトを使う方法に変わりないからだ。
スクリプト直接指定法

もう一つのスクリプト直接指定法について、
- stringでアニメのタイトルをとる(アニメ編集項目と一致させる)
- アニメーションの定義とstartでgetComponent<Animater>();を設置
- Startにて初期アニメを設置しておく(僕はnowAnimeと置いた)
- FixedUpdateにて動きやボタン(bool)発動によって細かく分岐
- 最後に定義.Play()で再生させる
アニメーション分岐は一つの箇所で行い、定義.Play()は一度きりの発動でよい。
アニメーションの難しさ

アニメーションの難しさは条件分岐の細かさにある。
遷移を使う方法はそれほど分岐を細かく指定しなくていいが、
初めからスクリプトを使う場合は違う。
くわえて真偽値boolを使って条件分岐をしなければならない。
boolによってどんどん細かい分岐ができるようになる。
上記画像を振り返る前にまず、初期値を書いておく。

始めは「静止状態(ここではfrontAnime)」におく。
きちんと設定しておかないと、いきなり歩いたり武器をふったりと別のアニメになってしまう。
はじめをみたうえで上記画像を一つずつ見ていくと、
grounded:大地に接しているかどうかの判定を行い、
接しているなら真、接していない場合は偽(!をつける)。
※groundedのやり方は上記動画か上記Unity2D本を参照すべし。
ここでは「大地に接している」ならstopAnimeからwalkAnimeに切り替える
else(= !grounded:大地に接していない)時、
空中にいるからジャンプアニメに切り替える。
velX,velY,!attaking:velはRigidBody2dのverocityを示す。
attakingはboolであり、初期値は偽にしている。
攻撃ボタンを押したとき、偽→真に変更する。
三つをまとめると「速度が0(不動)かつ攻撃ボタンを押していない」とき、
静止状態(初期値)アニメに変わる。
条件を別の形に置き換える

トリガーはボタンを押したときのみ発動してすぐ戻る状態で、主に攻撃アニメで使う。
はじめ「スクリプトでどうトリガーを設置すればいいか」がわからなかった。
条件分岐の難しさこそ、スクリプトにおいて最も頭を抱えるところだ。
ちなみに上記画像は遷移を引いており、この時のプログラミング(一部)はこちら。

スクリプトでTriggerをどう表現したらいいか?
定義に戻ってみよう。
トリガー:ボタンをおすたびに発動し、すぐもとに戻る
=ボタンを押した瞬間だけ真→偽になり、目的の時間がたったら偽→真に変わる
定義を言い換えたのち、トリガーの役割をプログラミングの形で表現すると、
- bool値を定義(例:attacking、最初は偽に設置)
- floatあるいはintを使って二つの時間を定義。一つ目は計測用、二つ目は基準用
- Updateにてボタンを押すとattackingが真になる
- if(条件式)でattackingが真なら攻撃アニメに切り替え、計測用を動かす(Time.deltaTime)
- 計測用が基準値を越えたらattackingを偽に変える
基準用の時間が少ないほど、トリガーに近い状態へと変わる。
具体的な作業に戻っていこう。

attakingが真=攻撃ボタンを押したとき、
攻撃アニメに切り替えているが、同時にすぐ別のアニメに変えねばならぬ。
ここでattakTime及びattakTimeRe(ともにfloat)を設定している。
attakTimeは数値を入れず(Start時に数字を入れてもいい)、
attakTimeRe(私は0.3f)には数値を入れる。
攻撃ボタンを押したとき、アニメを変えつつ
-Time.deltaTimeと置いて時間を数えている。
Time.deltaTimeについては参照サイトを置いておく。
時間をカウントダウン/アップできるための道具だ。
attakingを押したらattakTimeの数値がどんどん減り、
attakTimeが0未満(3,2,1,0秒)になったら、
attakingを偽に設置しつつ、attakTimeに数値(attakTimeReで設置した数)を代入する。
やっている内容はTriggerだ。
アニメーションプレイは一度のみでOK

トリガーを別の形で置き換える話を終えたので、元に戻ろう。
私は上記Unity2Dの作り方及び2D作成本を参考に独自で作り上げた。
現時点でも少しバグはあるし、簡略化されている部分もある。
全てのアニメ条件を載せた後、最後にアニメーションをプレイしておく。
anim.Playと書いているが、animはもちろんgetComponent<Animation>済みだ。
変更はnowAnimeのみで、nowAnimeはstringタイプだ。
まだ現時点ではアイテムを得たり、ゴールした時のアニメを書いていない。

再掲として、最初に作ったゲームは遷移を使いまくっている。
数個の矢印を引くなら問題ないが、アニメーション数が多いほど面倒になる。

こちらは遷移を使わず、スクリプトと条件分岐からアニメを切り替えられた。
スクリプトに慣れないうちは遷移を引っ張ったほうがいいと思うが、
慣れたら、遷移を使わない方がやりやすい。
遷移を使う/使わないにしろ一番のポイントは条件分岐だ。
条件分岐しても思うようにいかないとき、
定義を分解して言い換える能力こそプログラミングにて重要と確信している。
言い換え能力は自分の母語(私は日本語)で定義をしたのち、
定義をプログラミングに置き換えると、何を示すかを紙に書いたうえで、
実際にプログラミング(作業)し、テストしていったほうが早い。
お互い目的のゲーム作りに向けて、頑張ろう。
