Unityの寺子屋 4日目

学習内容

アニメとSEの設定

◇アニメとSEの設定

復習
アニメはctrl+6で開くことが出来るアニメーションウィンドウから設定できる。
アニメーションウィンドウ中央のCreatから新しいアニメを作る。
2Dではアニメに使う画像などをプロパティにドラッグ&ドロップすることで、簡単に作成可能。

複数のアニメを状況に応じて切り替えたい場合はアニメーターコントローラーから設定できる。
ある条件下でのみ再生したいアニメがある場合、遷移条件を設定する必要がる。
遷移条件の設定はトランジション(アニメ間にある矢印)に対して行うが、こういった特定条件下でのみ再生したいアニメの場合にはどこから遷移させて良いのかわからない場合がある。その場合は、AnyStateからトランジションを引けばよい。
AnyStateは現在のステートは指定せず、切り替え用のトランジションが必要な場合に使用する。

DOTweenを使ったアニメ

Sequenceクラス:アニメーションの統合を行えるクラス。
Append():直前の動作に続けて設定したアニメを再生するメソッド
シーケンスクラスのインスタンスを作って、そこからAppend()を呼び出しますが、引数に追加したいアニメ(Tweenなど)を書き込むと直前の動作に続けて書き込んだアニメが再生されます。
具体的なコードなどは以下のサイトを参考にしてください。

Qiita – DOTweenをふわっとまとめてみた
https://qiita.com/kagigi/items/bdf4d42835add07b0077

ToAlpha(getter,setter,終了値、期間):DOTweenクラスの関数。第一第二引数にはラムダ式というものを使って、不透明度を取得・設定するための匿名関数を指定するとのこと。正直何言ってるのかわからなかったです….
ラムダ式というものは関数を設定するためのC#の文法とのこと。ようは関数を定義しているらしいです。
どうやって定義しているかというと、

引数 => 関数内の処理

という形で記述されていました。
一応ざっくり説明をしてくれてはいるものの、しっかりとどういうものか知っておいたほうがよさそうですね。

後はSEを追加しました。
また、本当は追加ステージの作成と、タイトル、ステージ選択画面まで作って一応完成ですが、そちらについては「UnityではじめるC#」(リンクはアマゾン)で一度学習した内容なので今回は割愛しました。
そんな感じで完成したゲームがこちら。



ついにUnityの寺子屋終了です!


内容的にかぶっているところなど、割愛した部分もありますが、 一応1カ月で3冊の入門書を終わらせることが出来ました。
ここからすぐ自作ゲームを作ることは難しいかもしれませんが、スタートラインにはたてたのではないでしょうか。
とりあえず、作りたいものにチャレンジしてみて、その過程でいろいろなスキルを身についけていきたいと思います。

そういえば、今まで、この本を含めて3冊のUnity入門書でC#も少しは勉強できてはいるものの、その内容はC#の超基本的な部分のみですので、C#のいわゆる常識的なところ(基本的な文法や使い方、用語など)はちゃんとしたC#専用の入門書、学習書を使って勉強したほうがよさそうです。
有名どころだと独習C#などがあるようだったので、本屋で内容を見てみたところ、結構難しそう+つまらなそう(モチベが上がらなさそう)でした。
おそらく、今はゲームを作りたい欲が強く、そういった部分に気持ちが向かないのだと思います。
ゲームを作っていくうちに、C#の文法などがわからなくて困る場面が出てくると思うので、その時にそういった本で勉強するのがモチベーションを維持しやすいのかなと思いました。
せっかく一カ月あった休みを使って勉強したので、このまま何も残せず終わりたくないですし、自分のこれからの人生のためにも続けていきたいと思うので、モチベーション管理はしっかりしたいと思います。

次回以降はゲーム作成中に勉強した技術や、作成中のゲームなどの制作過程を書いたり、作成するにあたり取り組んでいる本などを今までのような形式で書いていこうと思います。

それでは、今日はこの辺で。


Unityの寺子屋 3日目

学習内容

  1. chap4:放置ゲームをクッキークリッカー系に変える
  2. chap5:横スクロールアクションゲームの作成
    • Rigidbody2Dのプロパティ
    • PhysicsMaterial2D
    • ゲームクリアの処理

1.chap4:放置ゲームをクッキークリッカー系に変える

OnApplicationPause関数:UnityEngineクラスの関数で、引数はbool型。アプリがバックグラウンド以降or復帰した時に呼び出される。
OnApplicationQuitというアプリが完全終了した際に呼び出される関数もあると野のこと(下記参考サイト参照)

以下参考サイト

chap4の内容はクッキークリッカー系に直すだけでした。
基本的なシステムは放置ゲームのものを流用すればできるようになっていたので、初めて出てきた関数だけメモがてら残しています。

2.chap5:横スクロールアクションの作成

chap5からは横スクロールアクションを作成していきます。
正直この章目当てで買ったくらい横スクロールアクションのゲームが作りたいと思っています。メトロイドが好きなので、メトロイドヴァニアなんかをそのうち作れたらいいなぁと思っております。

◇Rigidbody2Dのプロパティ

プロパティ説明
Body Typeその物体のタイプを、Dynamic、Kinematic、Staticから選択する。
Materialマテリアルを設定する。
Simulated物理演算と衝突判定のon/offを切り替える
Use Auto Massonにするとコライダーの形状から質量を自動的に検出する。
Mass質量のこと。(Use Auto Mass)をオフにしているときはここに密度を指定する。重い物体は動かす際にも止める際にも大きな力が必要になる。
Linear Drag移動の減衰値
Angular Drag回転動作の減衰値
Gravity Scale重力の影響度合。0にすると無重力状態を表現できる。
Collision Detectionほかのオブジェクトとの衝突検知の方法
Sleeping Modeプロセッサー負荷を抑えるためのオブジェクトのスリープ方法。
①Never Sleep、②Start Awake、③Start Asleepの三つがある。
①は常時動ける状態なので、負荷がたまりやすい。衝突すればスリープが解除されるため、たいていは初期設定の②で問題ない。
Interpolateスムージングの設定。処理の重さなどが原因で動きがぎこちなくなる時に利用する
Constraintsリジットボディーのモーション制限(移動/回転)。positionのx、yどちらかをonにすると縦or横にしか動かなくなる。rotationのzをonにすると回転しなくなる。

LinerDragとAngulerDragを調節することで粘り気のある液体のなかを動くような表現に使える。

Rigidbody2Dコンポーネントを利用してキャラクターの動作などをさせる場合には、FiedUpdate関数内で操作すると決められている。
これはFixedUpdate関数はUpdate関数と違い、固定フレームレートで動くため、動作環境依存でフレームレートが変わり、遅延してしまったり、不安定になることがないためである。

復習

velocity:Rigidbodyの速度ベクトルのこと。
enum:列挙型。列挙型で変数の宣言を行うときは「タグ名 変数名;」とする。

◇PhysicsMaterial2D

3Dグラフィクスなどでは物体の表面の質感の設定を指す。今回設定するのは物理エンジン用のPhysicsMaterial2Dでは物体が接した時の滑り具合を設定する摩擦と、衝突した時の跳ね返り度合を調整する弾性を設定できる。

復習
・Linecast関数:Physics2Dクラスのラインキャスタ機能の一種で線分上に特定のレイヤーに属するColliderが存在する(ヒットする)場合はtrueを返す。
Physics2D.Linecast(始点、終点、レイヤーマスク、トリガーも対象にするか)

ここではブロックや敵との衝突判定をおこなうために、ラインキャスター関数を用いている。キャラクタープレイヤーの足元を三角状に掘り下げるような判定領域を作っている。敵キャラがブロックにぶつかって移動方向を変える際にも、敵がブロックと衝突したかどうかを検出するために使っている。

・既習のゲーム外の判定について
OnTriggerEnter2D関数でプレイヤーがトリガーのコライダーに接したことを判別している。関数の引数は接触した相手のCollider2D型を参照する。

◇ゲームクリアの処理

ゲームクリアの処理は基本的にはゲームオーバー時と変わらない。
しかし、ゲームオーバーではプレイヤーは消していたが、今回はクリア時にプレイヤーを消さないため、ゴールのオブジェクトに触れ続けると接触判定が繰り返し発生してしまう。
そのため、クリアの演出(UIの表示など)+ ゴールオブジェクトとプレイヤーの衝突判定が消えるようにしなければいけない。

なんやかんやで、chap5時点のゲームはこちら

念願の横スクロールアクションの基礎が勉強できました!
やっていることは今までと同じですが、敵を踏む処理や敵の移動の処理の方法などの基本を学べました。
最近では、「あのゲームのあの敵はこうやれば実装できるのかな?」とか「あの動きはどう処理してるんだろう。」といった考えや疑問がたくさん湧いてきて、それを考える時間がとても楽しいと感じています。
次はプレイヤーや敵にアニメとSEなどの音楽、追加ステージなどをつけて完成です。
画面をスクロールさせるにはマップを広くしたり、カメラにプレイヤーを追従させたりする必要があります。
その辺についても勉強できるのかな?
一応今まで自分が勉強してきたことでどうにかなりそうな気もするので、この本が終わったら挑戦してみたいです。

この本はchap7がアプリ販売についての考え方になっているので、ゲーム作成に関する内容は次のchap6が最後になります。
正直、書く内容が陳腐すぎるだろうなと思いながら書いておりますが、どうでしょうか..?
chap6の記事は少し内容も薄くなる(chap6の内容が今までやってきた本の内容が見についていればできてしまうレベルだと思われる)ので、さらに書くことがなさそうなのが心配ですw
そんな感じではありますが、最後まで頑張ろうと思います!

それではこの辺で。

Unityの寺子屋 2日目

学習内容

  • BGMと効果音を鳴らす
  • オブジェクトにアニメーションを付ける
  • DOTweenを使った演出
  • スコアデータの保存

◇BGMと効果音を鳴らす

ゲーム中のBGMは、ゲームが起動している間、ずっとなり続けてほしいので、ゲームの間常に存在しているオブジェクトから鳴らす。(例えばゲーム中の処理をする空のオブジェクトなど)
方法としては、オブジェクトにAudio Sourceコンポーネントをアタッチし、音源をAudio Clipにドラッグ&ドロップすればよい。

ゲーム中の動作に演出としてSEを付けたい場合にはスクリプトから制御する。
具体的には…
ゲームマネージャーなどの制御オブジェクトにアタッチしているスクリプト上で
AudioSource型の変数(仮にaSource)とpublic なAudio Clipクラスの変数(仮にSE)を宣言しておく。

Start関数内で、aSourceにAudio Sourceコンポーネントを取得させておく。

ヒエラルキービューに戻り、スクリプトをアタッチしているオブジェクトのインスペクタ―ビューからpublicで宣言しているSEに鳴らしたい音源をドラッグ&ドロップし、変数に音源を渡しておく

音声を鳴らしたい処理を行っている関数内でaSource.PlayOneShot(SE);と書くと、処理を行った際に変数に渡していた音声が鳴る。

◇オブジェクトにアニメーションを付ける

アニメーションはwindow→Animation→Animation(もしくはCtrl+6)から作成することが出来る。アニメーションを付けるとAnimaterウィンドウとAnimationウィンドウの2つが現れる。
前者は複数のアニメーションを切り替える仕組み。アニメーターウィンドウでは、複数のアニメーションがボックスとして表示されている。これらボックスはステートと呼ばれている。特定のボックス間には矢印が伸びているが、これはアニメの遷移(トランジション)を表している。

後者では具体的にどんなアニメーションをオブジェクトに付けるか編集することが出来る。アニメーションウィンドウでは位置を変えたり、スケールを調整したりと様々なことが出来るが、どのようなアニメが存在するのかはここでは割愛する。
このアニメーションでは素材さえあればパラパラ漫画のようなアニメを付けることも可能である。
また、スクリプトからアニメーションを制御することもできるため、特定の処理を行う場面でのみアニメーションさせることも可能である。

GetCurrentAnimatorStateInfo関数:レイヤー数(アニメーターウィンドウ内のレイヤー?)を引数にとり、現在のアニメーションステートを返す関数。返り値のステートはAnimatorStateInfo型。
引数のレイヤー数は0だとBaseLayerを参照するのだと思う。が、あっているのかな…?
有識者の方がいましたら、コメントお願いします。

上記関数が持つfullPathHashは現在のステート(レイヤー名.ステート名)をIDに変換してくれるプロパティ。IDはint型の数ケタの数字で、この値を条件文内で比較することでスクリプト上からアニメーションの遷移を制御できる。
AnimetorクラスのStringToHashは引数に渡したstring型の値をint型のIDに変換する関数で、fullPathHashで取得したステートのIDとStringToHashでIDに変換したアニメーションステートを比較して、目的のステートと一致しているのか判断する際に使われる。

使用例は以下参考サイトを参照。

Pop技術ログ – 【Unity】アニメーターによる状態遷移とソース側での制御【技術】
http://blog.livedoor.jp/f_paul/archives/27309591.html

Amnesia~あむねじあ~ – Animator.StringToHash  文字列からパラメーター ID を生成。
http://bestrafung.blog.fc2.com/blog-entry-22.html

◇DOTWEENを使った演出

オブジェクトを曲線を描いて動かしたり、ジャンプさせたりと少し特殊な動かし方をしたい場合に便利なDOTweenというAssetを導入しました。
今回は取得したアイテムが曲線を描いて動く演出を付けるために以下のようなスクリプトを書きました。

各種関数などの簡単な説明は上記のスクリプトにコメントとして残してあります。
DOTweenの関数はDOTweenの公式ドキュメントや、DOTweenについてまとめている方がいらっしゃるので、そちらを見ていただけたらと思います。
自分もいろいろ調べてみて、使い方などその都度書いていこうと思います。

以下参考サイト。

GitHub – anzfactory/HowTo DOTween.md
https://gist.github.com/anzfactory/da73149ba91626ba796d598578b163cc

◇スコアデータの保存

PlayerPrefs:データを保存する仕組み。各OSの特定の場所にデータを保存してくれる。読み書きはキーと呼ばれる値を識別するための名前と値となる数値や文字列をセットにする。
理解のためのに参考にしたサイトは以下を参照

Qitta – Unityで簡単なセーブとロードの方法
https://qiita.com/tilyakuda/items/e3ccfbf507acfb16404f

PlayerPrefsではint、float、stringの3つの型しか使えない。例えば時刻を保存したい時などはDateTime型の値になるので、このままでは保存できない。
しかし、変数名.ToBinary.ToStringとすると、ToBinaryで変数に格納された値を64bitのバイナリ値に直し、その後ToStringでバイナリ値を文字列に変換することで、型の違う値を保存することが出来る。
ちなみにSetIntの扱う整数は32bitの値なのでバイナリ値のままでは保存が出来ない。

少し完成まで時間がかかりましたが、作ったゲームはこちら。

放置ゲーム完成版

やっぱりひとつ前の本よりも内容は難しくなっていて、完成させるのが大変でした。
ただ、調べればすぐ理解できたり、あーあれかってわかるときもあるので、自分の成長を実感しております。
また、やっていることは同じようなことの繰り返しなので復習になっていいですね。

本当は19日に投稿するつもりだったのですが、忘れていたので今日になってしまいました。

今日はchap4+αの内容も投稿しようと思います。

それでは、この辺で。


Unityの寺子屋1日目

学習内容

  • chap2:放置ゲームの作成
  • chap2内でわからなかったところ(UIImageとScript)

UIImage

・インスペクタ―内のRaycastTarget:オフにするとオフにされたイメージはタッチ判定の対象外となる。

Script

・(~)Instantiate(-):インスタンティエイト関数は引数(-)に渡したオブジェクトのクローン(インスタンス)を生成する。関数の前の()内(~)にGameObjectなどの型を入れると、指定した型にキャスト型変換して、指定した型の変数を代入する。

・SetParent関数:セットペアレント関数は親のオブジェクトを設定する関数。
 変数に対してこの関数の処理を行うと、引数に渡したオブジェクトの子として変数が設定される。

EventTriggerについて – Qiita

https://qiita.com/takesuke/items/e3b314aa7fd9111bc17f

代表例はボタンコンポーネントについてるOnClick。
詳細は上記リンクQiitaに記載されているので、参考にしてください!

イベントトリガーコンポーネントを目的のオブジェクト(本内ではプレハブ)にアタッチして、関数を読みだすのですが…ここで問題発生。

イベントトリガーコンポーネントを アタッチした後、関数を読みだすために”使いたい関数(メソッド)の書かれたスクリプトをアタッチしたオブジェクト”をNoneの部分にドラッグ&ドロップし、NoFunctionから目的の関数を呼び出すのですが、オブジェクトの部分にスクリプトを直接当ててしまっていたので、関数が全然呼び出されませんでしたw

そこそこ時間を無駄にしてしまいました…
調べてみるとあまりそういったミスをしている方はいなかったのですが、初心者や初学者、勉強したての方はミスってしまうのではないかと思い、残しておこうと思いました。

・DateTime.UtcNow Property:コンピューター上の現在の日時を世界協定時刻 (UTC) で表した DateTime オブジェクトを取得する。
時刻の差を記録するためにDateTime型同士の引き算をすると、その結果はTimeSpan型になるため、~秒間隔でなにかをする際には、TimeSpan型で時刻差を扱うようにしたほうが良い。

・FromSeconds():指定した秒数を表す TimeSpan を返します。秒数は、ミリ秒単位の精度で指定する。つまり、引数にいれたdouble型の数字をミリ秒単位の精度で秒数に直して返す関数。

・SetSiblingIndex(): ヒエラルキービュー内などのゲームオブジェクトの順番を指定した順番に直すような関数?。この本では、レベルアップの演出で表示する雲のオブジェクトを、2つのオブジェクトの間に表示させるために使用していた。
詳細は下記を参照。

Kanのメモ帳 – Hierarchy内の順序をプログラムで変える

・enum型:連続する定数(列挙体)を定義するための型。曜日や月など特定の値しかとりえないものに対して使われる。
詳細は以下を参照。

++C++;//未確認飛行C – 列挙型

https://ufcpp.net/study/csharp/st_enum.html

なんとかchap2の内容を一通り終えることが出来ました。
今まで2つの本を通して、ゲームってこんな感じでできるんだ!という思いと、意外と理解できるし、もう少し勉強すればサックっと一つくらいゲーム作れるかも!とか思っていました。
こんな調子だったのでこの寺子屋をはじめる前も、サクッと終わらせてゲーム一個作ってみよ!なんてことを考えていましたが、考えが甘かったみたいです….

というのも今までやっていた2冊に比べると内容は格段にレベルアップしております。やっていることは「UnityではじめるC#」の延長なのですが、スクリプトも複雑になってきて、スクリプト一つ一つでやっていることを理解することはできても、自分でこれを作れるのか?という不安が出てきました。

ただ、サンプルとして用意されているゲームのジャンルがとても素晴らしい(汎用性が高い)ので、実際に自作ゲームを作る際にかなり参考になる(流用できるところがかなり多い)だろうと感じています。
あと、そもそも最初の一つ目に作ったゲームなんて、たいていの人がクソゲーしか作れないだろうと思いますし、自分が抜群にできるやつとも思っていないので、最初はほぼスクリプトやシステムが丸パクリみたいなものでも、いいと思うようにしました。
ただ、この数週間でずぶの素人から、ここまで良くこれたものだとも思いますので、そこは褒めてあげて、さらにレベルアップしていきたいと思います。
寺子屋は時間がかかりそうなので少しずつでも進めていこうと思います。
あんまり根を詰めても精神的に良くないですし。

それでは、寺子屋の1日目はこれで終了です。
次はchap3に取り組んでいきます。

あ、あと参考にしたリンクなどを載せるようにしてみました。
同じようなところでつまずいた方が奇跡的にこのブログにたどり着いたとき、参考になればと思いますw
もし、なにかこうしたほうがいいよみたいなアドバイスなどありましたら、コメントを下さるとありがたいです。

それでは、ありがとうございました。
では、この辺で。