【Unity】基本チートシート

#はじめに
テクロスというゲーム会社でエンジニアとしてアルバイトしています。
別の言語を触ってて、久しぶりにUnityを触ると「あれ？これどう書くんだっけ？」となって初歩的なこともいちいち調べないと書けなかったりします。レベルが低いだけ説。。。
なので今回は自分用にレベルの低いチートシートを作ります。基本3Dです。

#本文

関数名とクラス名は大文字にしないと注意される。地味に忘れる。

###画面遷移

```C#
using UnityEngine.SceneManagement;
void ChangeScene(string sceneName) {
    SceneManager.LoadScene(sceneName);
}

//呼び出し方の例
public void OnClick() {
    ChangeScene("MainScene");
}
```

OnClick()をボタンに紐づけて、ボタン押したら画面遷移って時に使えます。ボタンに紐づける関数は**publicと明示しないといけない**ので注意。
**ビルドセッティングに遷移先シーンが追加されてないと遷移されない**ので注意。

###GameObject関連(取得、無効化、破壊)
GameObject.Find()はCPUの負荷がちょっと大きいみたいな記事を見たのであまり多用しないようにするべきかも。

取得関連

```C#
//ソースコードでgameObjectを取得する
GameObjact hoge = GameObject.Find("hoge").gameObject;
//enemyタグが付いているgameObjectを複数取得する
GameObject[] enemies = GameObject.FindGameObjectsWithTag("enemy");
foreach(GameObject enemy in enemies){
    //これでenemy一つ一つに処理を施すことができる
}

//editorからgameObjectを設定する.2通り
 [SerializeField] private GameObject hoge;
public GameObject hoge;
```

無効化関連

```C#
//gameObjectの無効化
GameObject.Find("hoge").gameObject.setActive(false);
//gameObjectに付いてるcomponentの無効化
GameObject.Find("hoge").GetComponent<HogeController>().enabled = false;
```

破壊

```C#
GameObject hoge = GameObject.Find("hoge").gameObject;
Destroy(hoge);
```

###クラスのインスタンス化

```C#
//オブジェクト"Cube"にアタッチしてる"HogeController"内のメソッドを使いたい時
HogeController hogeController;
hogeController = GameObject.Find("Cube").GetComponent<HogeController>();

//オブジェクトにアタッチしてない"HogeController"内のメソッドを使いたい時
HogeController hogeController = new HogeController();
```
UnityはSceneを実行したときオブジェクトが生成されるので、そのときアタッチされてるクラスも全てインスタンス化される。それを新しくnewでインスタンス化しようとするとエラーになるので注意。

###プレハブのインスタンス生成
```C#
public GameObject prefab;
GameObject instance = Instantiate(prefab) as GameObject
```
prefab化させるには、HierarchyビューからProjectビューにドラッグアンドドロップする。それでできたprefabをInspectorビュー上で紐づける。

###遅延
void MonoBehaviour.Invoke(string methodname, float time)を使う。

```C#
//3秒後にhoge関数を呼び出したい場合
private float waitTime = 3.0f
Invoke("hoge",waitTime); //関数名はstringで渡す

func hoge(){
    Debug.Log("hoge");
}
```


###数秒ごとに繰り返し

```C#
private float timeLeft = 5.0f; //例えば5秒ごとに
//以下の関数をUpdate()内で呼び出す
func repeat(){
    timeLeft -= Time.deltaTime;
    if (timeLeft <= 0.0f){
        //繰り返したい処理を書く
    }
}
```

###移動と回転
移動はさすがに忘れないから割愛(基準がわからん)。ただ、tranform.positionを書き換えて移動させるのは瞬間移動なので、壁抜け等が発生します。AddForceやらを状況に応じて使い分けよう。
回転はよく忘れるけど目的によって色々あるので用途によって調べましょう。[Unityでオブジェクトを回転させる方法まとめ](https://tama-lab.net/2017/06/unity%E3%81%A7%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%82%92%E5%9B%9E%E8%BB%A2%E3%81%95%E3%81%9B%E3%82%8B%E6%96%B9%E6%B3%95%E3%81%BE%E3%81%A8%E3%82%81/)が分かりやすいと思いました。
一応指定した秒数で指定した角度まで回転させるscriptを置いておきます。

```C#
private bool nowRotating = false; //回ってる途中はtrue
private float startTime;
private float timeSpan = 3.0f; //何秒かけて回転させるか
private float diff;
void startRotation(){
    startTime = Time.timeSinceLevelLoad;
    nowRotating = true;
}
void rotation(){
    diff = Time.timeSinceLevelLoad - startTime;
    if (diff >= timeSpan){ nowRotating = false }; //timeSpanだけ時間経過したらおしまい
    var rate = diff/timeSpan;
    //カメラをゆっくりx軸周り0度から90度に回転させる
    float angle = Mathf.LerpAngle(0.0f, 90.0f, rate);
    gameObject.transform.eulerAngles = new Vector3(angle, 0f, 0f);
}

//使用する時はstartRotation()をボタンクリック等に紐つけて、
void Update(){
    if(nowRotating){
        rotation();
    }
}
```

###親オブジェクトとの位置関係で角度や位置を設定したいとき
地味に大事カモ

```C#
childObject.gameObject.transform.parent = parentObject.gameObject.transform;
childObject.gameObject.transform.localPosition = new Vector3(0.0f, 0.0f, 5f); //親の真上
childObject.gameObject.transform.localEulerAngles = new Vector3(0.0f, 0f, 0f); //親と同じ向き
```

###衝突判定
これは**3Dと2Dで使う関数が違うので注意**。3Dで慣れてて2D作ってみるとあれ？ってなる。2Dは関数名の後ろに2Dってつきます。

```C#
//Playerタグを持ってるオブジェクトとの衝突
private void OnCollisionEnter(Collision col){
    if (col.gameObject.CompareTag("Player")){
        //衝突した時の処理
    }
}
```

オブジェクトと物理的に衝突するならOnCollisionEnter, isTriggerにチェックが入っていてすり抜けるようにしてるならOnTriggerEnterを使う。


#番外編(Editorの使い方)

###コンソールボックスの出し方
Window->General->Console

###画像の出し方
1.表示したい画像をドラッグアンドドロップでProjectビューに入れる。
2.Texture TypeをSprite(2D and UI)に変える
3.Canvas内にCreate->UI->ImageでImage作成
4.そのImageのSourceImageにさっきの画像をセットして、PreserveAspectにチェック入れて完成。


#あとがき

久しぶりに書くと引数の宣言って string name だっけ name:string だっけ みたいなレベルで忘れる。
気を付けなはれや。
いいねがほしいのでいいねください。