【Unity】理論的な基礎を学ぶ

# Unityを基礎から
今まで，部分部分でUnityを使ったことがあったけれど，毎回使い方を調べて... みたいにやっていたので，基礎を身につけてどういうことをすればいいのか考えてできるようにするというのがねらい．

[(参考)世界よ，これが本当のUnity講座だ](http://archive.fo/z98q9)


## Unityとは

### ゲームエンジン概観

- 3D/2D 描画 => 視覚
- サウンド再生 => 聴覚
- ユーザーインターフェース => 触覚 ( インタラクティブ )
- マルチプラットフォーム => 様々な人ができるように
- データ管理・作成ツール => 楽に
- プログラマブル => 多様性

人間とのやり取りがあってこそゲームは成立する． 
Unity はこれをマルチに比較的簡単にできちゃうすごいもの

### Unityでゲームを作るには

 - Unity のオブジェクト構造とその作り方（Editor）
 - 描画システム（3D / 2D）
 - プログラミングの技術（設計 / 言語）

Unity のオブジェクト構造とその作り方にfocusする

ゲームはすごいだいたいな感じで

 - 何かモノがあって
 - それを人が受け取って（見て）
 - 聞くなども実はありますが一旦無視
 - 人が何かする（画面に触る）と
 - 喋るとか、振るなどもない訳ではないが一旦無視
 - モノが変化する

という流れを何らかのルールに従って繰り返す

#### ◆何かものがあって

>　基本的には、「モノとして存在するものは GameObject というものに置き換えて考える」というのが Unity の流儀です。例えば、ゲームのキャラクターや宝箱といったものです。
　これらに「どういう振る舞いを持たせるのかが Component である」という考え方をします。例えば、どう見えるのか、どう動くのか、触ったら何が起きるのかといった事です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/281857/e96f28f0-54df-d870-9c2f-f8f49fe1d6eb.png)

(Prefab とか意味が全く分かっていなかったのでなるほど！と思った)
たとえば，宝箱で考えると宝箱自体はPrefabに用意しておいて，Componentを変えることで動作を変えられるということか
GameObject 自体も親子関係を作れる，つまりメインの(親の)オブジェクトに対して付属てきなオブジェクトをつけることができるようになるということ


#### ◆人がそれを見る

　GameObjectが並べられた空間を，GameObjectにアタッチしたカメラで切り取り(絞り込み/カリング)，ユーザーに見せたい部分を見せる．そして，それはスクリーンを通して見られるなら2Dになり，VRなどの場合は3Dになる．
　カメラは複数作ることができて，GameObjectにタグ付けして... もできる．

#### ◆人がなにかをする

- 画面を触る
    - 画面を触るということは，2Dのオブジェクトを触るということで，触れた場所を3D空間のどこかに変換する必要がある．
    - 逆透視変換という
    - Unityでは Ray つまり光を飛ばして延長線にものがあるかで判定している．Rayと衝突するためには，Collidar Componentが必要になる．

> 　いきなりですが、ここから先は少し専門用語が多くなってきますので、3D についての基礎的な前提知識の確認をしてみましょう。3D の描画は、おおまかに下記の様なイメージです。

    3次元の座標上の点を結んだ線で表現した面をたくさん集めて、
    その面に絵を貼り付ける付ける事で、
    立体的な形と絵柄を表現している。

>　ここで言うところの、

    3次元の座標上の点＝頂点（バーテックス）
    頂点の集まりの最小単位＝ポリゴン（だいたい三角形）
    ポリゴンの集まり＝メッシュ
    メッシュを物体として意味のある形にしたもの＝モデル
    メッシュに貼り付ける絵＝テクスチャ
    メッシュのどこにテクスチャのどこを対応させるか＝UV マップ
    どういう光がどっちにさしているのか＝ライティング
    メッシュとかテクスチャとかライティングを元にどう描画するかを決めるもの＝シェーダー
    テクスチャとシェーダーに関する設定をひとまとめにしたもの＝マテリアル

とても説明がすっきりして驚いた．すっと理解できた．感動

#### ◆モノが変化する

- どういう絵柄・形なのか
- どういう光が差し込んでどう反射するのか
- 回転・位置・大きさ(rotate/translate/scale) 

考える要素はそれなりにある．

##### どういう絵柄・形なのか
>
    絵柄を変える
        テクスチャを変える
            そもそも差し換える
            UV マッピングを変える
        シェーダーで描画の仕方を変える（フラグメントシェーダー）
            柄は一緒なんだけど色を変えるとか
    形を変える
        アニメーションでモデルの形を変える
            いわゆるボーンアニメーション
        シェーダーでモデルの形を変える（バーテックスシェーダー）
            モデルを形作るポリゴンの形自体を変える

##### どう光が差し込んできて反射するか　

>
    どういう光が、どう射して
        種類（向く方向と範囲）
            ディレクショナルライト
            ポイントライト
            スポットライト
            エリアライト
        光源の位置
        光の強さ
        光の色
    どう反射しているのか
        シェーダーの計算式を変える
        シェーダーに与える値を変える
            ノーマルマップを変える
            バンプマップを変える

##### 位置・大きさ・回転

>
    Transform コンポーネントの値を変更する
        物理エンジンに任せる
            重さや弾性係数、摩擦係数などのパラメータを指定しておくとよしなに動かしてくれる
        アニメーションエンジンに任せる
            ルートモーションという仕組みで、3D オブジェクトのアニメーションに Transform 情報を更新させる事ができる
        自前で Transform の情報をプログラムから変更する
            特殊な動きをさせたい時や動的に生成したオブジェクトなど

この `よしなに動かしてくれる` のがゲームエンジンの強みだよなぁと感じる

#### なんらかのルールに沿って繰り返す．

二回でてきたのでこれは大事なこと
`GameObject がどう振る舞うのかを定義するのは Component`

つまり，ゲーム空間を変化させるにはComponentに記述する．今まで分かっているようで分かっていなかった．やはり，Unityもこうして階層的な構造になって成立している．

オブジェクト指向はもちろんそうだが，htmlやcssなども階層構造でComponentを分ける書き方をすることを最近学んだ，階層構造がとても大切になってくる考え方だと実感する

###### Component はどう記述するのか

- Unity は可変フレームのリアルタイム処理( どういうこと?)
    - リアルタイム処理とは
        - 必要なことを随時計算し画面に反映する
        - だいたいframeRate は 30か60(30FPS, 60FPS)を用いる
    - 可変フレームとは
        - 更新の期間が毎回一定とは限らないということ
        - frameRate=30 の場合 30回同じ感覚で更新されるわけではないということ
            - ではその感覚はどう決めるのか
                - どれぐらい変化したかとか，変化するまで更新しないとかにする(?)
                - 変化させる量が毎回(別に毎回ではなくていいと思うが)変わるようになっていれば，必然的にframeRateの間隔も変わるはず

> 
秒間30回〜60回も更新されるという事はとても細かい単位で「変化」させていく事になりますよね。Unity は内部で「今から更新しますよー何かを変えるなら変えて下さいねー」というタイミングを用意してくれていますので、それが伝えられた段階で自分で変化させる量を決めていく事になりますが、この時利用されるのが「前回の更新からどれだけ時間が経過したのか」という情報になる Time.deltaTime です。例えば、1秒で1m移動するのであれば0.1秒では10cm移動する事になります。この場合の0.1秒が Time.deltaTime から取得できるという訳です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/281857/2a2d1261-74ea-55e2-d792-979a962b8126.png)

- Update＝フレーム更新処理が走る時に呼ばれる
- LateUpdate＝Update が実行された後に呼ばれる
- FixedUpdate＝一定時間に一回呼ばれる

処理をこれらのタイミングでうまく分けることで，目的の処理を実行する．

とりあえず，理論的な部分はここでいったん区切り．見てみると結構シンプルだなと思った．なんだかいけそうな気がする！！