Unity雑多メモ

# Dictionaryのコピー

```csharp
//
// Create and initialize Dictionary.
//
Dictionary<string, int> dictionary = new Dictionary<string, int>();
dictionary.Add("cat", 1);
dictionary.Add("dog", 3);
dictionary.Add("iguana", 5);

//
// Copy the Dictionary to a second object.
//
Dictionary<string, int> copy = new Dictionary<string, int>(dictionary);
```

[Copy Dictionary.](https://www.dotnetperls.com/copy-dictionary)


# Dictionaryの走査

```csharp
foreach (KeyValuePair<string, string> pair in dic) {
    Debug.Log (pair.Key + " : " + pair.Value);
}
```

[C#のDictionary【Unity, C#】](https://qiita.com/kwst/items/2cfd01b7f28daf0f495e)


# 二点間の角度

```csharp
// p2からp1への角度を求める
// @param p1 自分の座標
// @param p2 相手の座標
// @return 2点の角度(Degree)
public float GetAim(Vector2 p1, Vector2 p2) {
	float dx = p2.x - p1.x;
	float dy = p2.y - p1.y;
	float rad = Mathf.Atan2(dy, dx);
	return rad * Mathf.Rad2Deg;
}
```

[Unity2D】2点間の角度を求める
](https://qiita.com/2dgames_jp/items/60274efb7b90fa6f986a)


# InvalidOperationException: out of sync

foreach内でDictionaryの値を変えようとすると見出しのエラーで怒られる。

```csharp
List<string> keyList = new List<string>(dictionary.Keys);
foreach(string key in keyList){
	 dictionary [key] *= 2;
	 Debug.Log (key + " " + dictionary [key]);
}
```

KeyのみをListにして操作する。

[Dictionaryの値をforeachで変更する【C#】](http://kan-kikuchi.hatenablog.com/entry/Dictionary_foreach)


# 経過時間を取得する

```csharp
public float timeOut;
private float timeTrigger;
void Update() {
	  if(time.Time > timeTrigger) {
	  // Do anything
	  timeTrigger = Time.time + timeOut;
	 }
}
```

[[Unity] 一定の時間間隔で処理を実行する方法まとめ（時間制御)](https://qiita.com/Nagitch/items/fb9157b1cb27f3d37696)


# 指定位置を向く

```csharp
gameObjA.transform.LookAt(gameObjB.transform.position);
```

Unityでの「前」とは、エディター上でオブジェクトを選択した時の青い矢印の向きで現されます。

Cameraの投影設定が*Perspecrive*のときはZ値を設定してやる。

[Unity: Transform.LookAt()の回転軸を制限する](http://hamken100.blogspot.jp/2012/05/unity-transformlookat.html)
[【Unity】ScreenToWorldPointが上手く取れない？](http://ghoul-life.hatenablog.com/entry/2017/05/16/001743)


# GameObjectの複製

```csharp
//オブジェクトを変数名bulletで生成
GameObject bullet = Instantiate(obj) as GameObject;
```

[オブジェクト生成の仕方　Instantiate](https://qiita.com/Teach/items/c28b4fe5ca8dc4c83e26)


# ParticleをPrefab化

prefabにParticleSystemコンポーネントを追加しといて、

```csharp
private ParticleSystem particle;
 
    // Use this for initialization
    void Start ()
    {
        particle = this.GetComponent<ParticleSystem> ();
 
        // ここで Particle System を停止する.
        particle.Stop ();
    }
 
    void OnTriggerEnter (Collider col)
    {
        // ここで Particle System を開始します.
        particle.Play ();
    }
```

[Unity5でのPrefabに設定したParticleSystemをスクリプトで起動する方法](http://www.peliphilo.net/archives/629)



# Unityで使える配列

> 以上、Unityで扱われる広義の配列について述べた。利用指針は次のようになるだろう。

>・大きさがわかっているケースは、ビルトイン配列を使う。メモリ効率も速度ももっともよい。
・ArrayListのかわりにGneric Listを、Hashtableの代わりにGeneric Dictionaryを使う。
・Javascript Arrayは使わない。

>要するに、型のキャストを避けるべき。
開発時はArrayListやHashtableを使ってもよいが、リリース時はGnericに変換するとよいだろう。

*[Unityで使える広義の配列](http://unitygeek.hatenablog.com/entry/2014/10/09/165352)*


# List配列走査中の要素の削除

Listを走査中に要素を削除してしまうと、次の要素が繰り上がると同時に変数 i もインクリメントしてしまうので次の要素の処理を飛ばしてしまうことになる。

```csharp
List<int> test = new List<int> ();
for (int i = 0; i < 5; i++) {
	test.Add (i);
}
for (int i = 0; i < test.Count; i++) {
	Debug.Log ("test1 : " + test[i]);
	if (i == 2) {
		test.RemoveAt (i);
	}
}

// [output]
// test1 : 0
// test1 : 1
// test1 : 2
// test1 : 4
```

なので要素を消したら変数 i をデクリメントしてあげる。

```csharp
List<int> test = new List<int> ();
for (int i = 0; i < 5; i++) {
	test.Add (i);
}
for (int i = 0; i < test.Count; i++) {
	Debug.Log ("test1 : " + test[i]);
	if (i == 2) {
		test.RemoveAt (i);
		i--;
	}
}

// [output]
// test1 : 0
// test1 : 1
// test1 : 2
// test1 : 3
// test1 : 4
```


# floatの絶対値を返す

```csharp
Debug.Log(Mathf.Abs(-10.5);
// 結果 10.5
```

[【Unity】知って得するMathfクラス](http://megumisoft.hatenablog.com/entry/2015/08/29/210310)


# ベクトルの加算・減算

Vector2のまま加算・減算してもちゃんと成分同士で計算してくれる。

```csharp
Vector2 vec1 = new Vector2 (0.2f, 0.3f);
Vector2 vec2 = new Vector2 (0.4f, 0.5f);
Vector2 vecAdd = vec1 + vec2;
Debug.Log (vecAdd);

// [output]
// (0.6, 0.8)
```

[Unityでベクトルを扱おう](http://developer.wonderpla.net/entry/blog/engineer/Unity_Vector3/)


# DictionaryをInspectorで扱う

おいおい使いそう。
[UnityのInspectorで扱えるDictionary](https://qiita.com/k_yanase/items/fb64ccfe1c14567a907d)


#  参照渡し

引数に ref をつけるを参照を渡すことになる。

```csharp
// 参照渡しをする場合には、引数にref修飾子をつけます。
public void addSum (ref int num)
{
    num = 100 + num;
    Debug.LogError ("値: " + num);
}

var addSum = new outTest ();
int a = 100;
 
Debug.Log ("a:" +  a);
addSum.addSum (ref a);
Debug.Log ("結果 a:" + a);
 
// a:100
// 値: 200
// 結果 a: 200
```

[【C#】参照パラメーター(ref) と出力パラメーター (out) とは](http://albatrus.com/main/unity/7611)


# 3つの座標系

## Screen
画面の解像度による座標。
例えば1280 × 800の画面の中央のScreen座標は(640, 400)。

## Viewport
画面の左辺を x = 0、右辺を x = 1 に、下辺を y = 0、上辺を y = 1 とした座標。
解像度によらず、画面の中央のViewport座標は(0.5, 0.5)。

## World
3D空間上における座標。

[UnityのCameraが使う３つの座標系](http://tsubakit1.hateblo.jp/entry/2014/07/22/010739)


# 構造体

●構造体の定義

```csharp
struct 構造体名 {
    //変数郡
    //関数郡
}
```

これをnewして使用します
構造体名 変数名=new 構造体名();

[◇Unityでゲーム開発 -C#の構造体-](http://yun.cup.com/unity051.html)
[Unityメモリ管理「構造体とクラスの比較」](http://gamesonytablet.blogspot.jp/2012/12/unity_27.html)


# TouchScriptを使う

## 標準GUIと混在させる

> EventSystemにあるStandaloneInputModuleをTouchScriptInputModuleに置き換えます。
*[[Unity] TouchScriptの覚え書き ~ holizonglow](https://horizonglow2.blogspot.jp/2017/02/touchscript_76.html)*

[TouchScript - アセットストア - Unity Asset Store](https://assetstore.unity.com/packages/tools/input-management/touchscript-7394)
[Home · TouchScript/TouchScript Wiki · GitHub](https://github.com/TouchScript/TouchScript/wiki)
[[Unity] TouchScriptの覚え書き ~ holizonglow](https://horizonglow2.blogspot.jp/2017/02/touchscript_76.html)


# 標準GUIの操作

## Input Field

### On Value Changed
入力中の文字列が変更された際に発火

### On End Edit
入力中からEnterやフォーカスが外れた祭に発火

### 入力文字列の取得

```csharp
GetComponent<InputField> ().text;
```

[【Unity】uGUIのInputFieldで入力した文字列をプログラムに渡す](http://tech.pjin.jp/blog/2016/09/27/unity_skill_4/)


# コルーチン

一定時間待つ。

```csharp
void Start () {  
    // コルーチンを実行  
    StartCoroutine ("Sample");  
}

private IEnumerator Sample() {  
    // ログ出力  
    Debug.Log ("1");  
  
    // 1秒待つ  
    yield return new WaitForSeconds (1.0f);  
  
    // ログ出力  
    Debug.Log ("2");  
  
    // 2秒待つ  
    yield return new WaitForSeconds (2.0f);  
  
    // ログ出力  
    Debug.Log ("3");  
}  
```

[Unityのコルーチンの使い方をまとめてみた](http://developer.wonderpla.net/entry/blog/engineer/Unity_Co-routine/)


# コールバック

[【Unity】【C#】UnityEvent, Action, delegate, interface でのコールバック実装方法とインスペクタでの登録](http://fantom1x.blog130.fc2.com/blog-entry-252.html)


# キーボードからの入力

```csharp
if (Input.GetKey(KeyCode.Space)) {
    transform.position = new Vector3(0f, transform.position.y + 0.1f, 0f);
} else {
    transform.position = new Vector3(0f, transform.position.y - 0.1f, 0f);
}
```

[UnityのInputで入力を扱う](https://qiita.com/yando/items/c406690c9ad87ecfc8e5)


# Blender からオブジェクトをインポート

[Blender からオブジェクトをインポート](https://docs.unity3d.com/ja/current/Manual/HOWTO-ImportObjectBlender.html)


# Start() の走るタイミング

ヒエラルキの順番とは無関係ぽい。
Canvasは上位からレンダリングされる、んだっけかな。


# イベント処理

[C#のイベント機能](https://dobon.net/vb/dotnet/vb2cs/event.html)
[デリゲートとは【C#】](http://kan-kikuchi.hatenablog.com/entry/Delegate)


# const と static

const を指定すると自動的に static になるらしい。へー。
なので明示的に static const を並ばせるとエラー吐く。


# Editor拡張

```csharp
using UnityEngine;
using UnityEditor; // エディタ拡張関連はUnityEditor名前空間に定義されているのでusingしておく。
using System.Collections;
 
// エディタに独自のウィンドウを作成する
public class EditorExWindow : EditorWindow
{
    // メニューのWindowにEditorExという項目を追加。
    [MenuItem("Window/EditorEx")]
    static void Open()
    {
        // メニューのWindow/EditorExを選択するとOpen()が呼ばれる。
        // 表示させたいウィンドウは基本的にGetWindow()で表示＆取得する。
        EditorWindow.GetWindow<EditorExWindow>( "EditorEx" ); // タイトル名を"EditorEx"に指定（後からでも変えられるけど）
    }
 
    // Windowのクライアント領域のGUI処理を記述
    void OnGUI()
    {
        // 試しにラベルを表示
        EditorGUILayout.LabelField( "ようこそ！　Unityエディタ拡張の沼へ！" );
    }
}
```
[エディタ拡張徹底解説】初級編①：ウィンドウを自作してみよう【Unity】](http://caitsithware.com/wordpress/archives/1377)


# virtual と override

継承元スーパークラスにはメソッド名の前にvirtual
継承先サブクラスにはメソッド名の前にoverride
をつけるとサブクラスのメソッドを呼び出すことができる

[【Unity開発】継承まとめ② virtualとoverride【ひよこエッセンス】](http://hiyotama.hatenablog.com/entry/2015/05/31/090000)