GGJ2017 個人作業メモ(RealTime)

#GGJ2017 個人作業メモ

Evernote サービスは利用できません

ということなのでこちらに移動。
##開発環境
Unity 5.5.0f3 + Android

##目標
**画面タッチで████が出て判定を行うシステム**

※海苔が貼ってあるところが今回のテーマ

##部分進捗
:ok: ビルド＆Run
:ok: タッチされたらアクションを起こす
:ok: レーダー用オブジェクトをタッチで大きさ変化させる
:ok: １回タッチしたら自動で大きくする
:ok: 大きさが設定値を超えたら元に戻って待機する
□ターゲットオブジェクトに当たったらアクションを起こす
□連打出来ないようにする。
□衝突数をカウントする
□ターゲットがレーダーに当たったらタッチできるようにする
□ターゲットのタッチ可能時間を規定秒間(2秒くらい)に限定する
□レーダーを見えなくする


##タッチ検出： タッチされたらアクションを起こす

UnityでiOS/Android/Editorの共通タッチ処理を実装する - Qiita
http://qiita.com/tempura/items/4a5482ff6247ec8873df

を参考に作ってみる。
→”AppConst”というのが見つからないので動かない。パス。

【UnityAsset】GodTouch - Unityエディタ上でタッチの動作を確認できる | てんぷらの館
http://okamura0510.jp/%E9%96%8B%E7%99%BA%E3%83%96%E3%83%AD%E3%82%B0/godtouch/
アセット化したという。

GitHub - okamura0510/GodTouch: 【UnityAsset】GodTouch – Unityエディタ上でタッチの動作を確認できる
https://github.com/okamura0510/GodTouch
Zipをダウンロード。インポート、デモシーンを走らせる。
…んむ。よくわからない。

-----
new sceneでやりなおし。
【Unity】タッチ処理を検出する。 | albatrus.com
http://albatrus.com/main/unity/6520
スクリプトをコピってみたが、一部がエラーで動かない。

Unityで回転したかったお話 - Qiita
http://qiita.com/utah/items/005e34e6888b0b6c63c3

```
void Update () {
  //タッチがあるかどうか？
  if (Input.touchCount > 0)
  {
  //タッチ直後
  if (Input.touches[0].phase == TouchPhase.Began)
  {
  //タッチの処理
  //回転させてみる
  gameObject.transform.eulerAngles += new Vector3(0f, 0f, 10f);
  }
  }
  }
```

にしたら動いた。``Input.touches[0].``のところがエラーになっていた。
見つけたタッチ箇所の一個目を取り出すコード。

```
        //タッチがあるかどうか？
        if (Input.touchCount > 0)
        {
            //タッチ直後
            if (Input.touches[0].phase == TouchPhase.Began)
            {
                //タッチの処理
                //ソナー拡散 数回分ループさせる処理を呼ぶ
                StartCoroutine(waveloop());

            }
        }

        //マウス操作用
        if (Input.GetMouseButtonDown(0))
        {
            //transform.localScale += new Vector3(0.5F, 0.5F, 0);
            StartCoroutine(waveloop());
           // transform.localScale += new Vector3(0.1F, 0.1F, 0);
        }

```
というコードになった。


##素材
妖精のイラスト（空想上の生物） | かわいいフリー素材集 いらすとや
http://www.irasutoya.com/2013/05/blog-post.html
素材元。

##レーダー用オブジェクトをタッチで大きさ変化させる

徐々に大きくするには？：transformをいじればよいらしい。

Unity - スクリプトリファレンス: Transform.localScale
https://docs.unity3d.com/jp/current/ScriptReference/Transform-localScale.html

```
public class ExampleClass : MonoBehaviour {
    void Example() {
        // Widen the object by 0.1
        transform.localScale += new Vector3(0.1F, 0, 0);
    }
}
```
タッチ判定後にこれをぶちこむ。```1F, 1F```にしてみよう。
タッチするたびに大きくなるようにできた。

##１回タッチしたら自動で大きくする
ループ処理を書く。

コルーチンの初歩的な使い方【Unity, 初心者】 - Qiita
http://qiita.com/kwst/items/ce04abce7c1e2c72e023

```
    //波を徐々に大きくする
    private IEnumerator WavePropagation(float second)
    {
        // ループ
        Debug.Log("wave loop. in");
        while (true)
        {
            // secondで指定した秒数ループします
            yield return new WaitForSeconds(second);
            if (wave)
            {
                while (wave.transform.localScale.x <= 100f)
                {
                    wave.transform.localScale += new Vector3(1F, 1F, 0);
                }
                Debug.Log("wave 拡散中");
            }
        }
    }
```
ちょっとこれはおいといて。

###とりあえず動いたぽい
トリガーとなるところ。

```
            StartCoroutine(waveloop());
```

設定用変数

```
    private float minWaveRadius = 1.0f;     //最小レーダーサイズ
    private float stepWaveRadius = 0.5f;    //毎フレーム拡散サイズ
    private float maxWaveRadius = 15.0f;    //最大サイズ
```

ループするコルーチン

```
    private IEnumerator waveloop()
{
        // ループ　最大サイズを超えるまで繰り返す
        while (transform.localScale.x < maxWaveRadius)
        {
            // wave 拡散
            yield return null;
            transform.localScale += new Vector3(stepWaveRadius, stepWaveRadius, 0);
        }
//最大サイズを超えたらリセットする。
        if (transform.localScale.x >= maxWaveRadius)
        {
            transform.localScale = new Vector3(minWaveRadius, minWaveRadius, 0);
        }
    }
```
→二回目以降が見えない？ずっと動き続けている？

###コルーチンを止めるには？

処理を停止したい！Unityでコルーチンを使う方法 | TechAcademyマガジン
https://techacademy.jp/magazine/9316

```
  yield break;
```

最大サイズまで行ったらこれ実行させよう。
うまくいったぽい。
一回タッチしたら自動で大きくするのできた。


###画像素材を軽く作る

https://pixlr.com/editor/
このサイト便利。

##自分にタッチされたときだけ動く

```
    bool OnTouchDown()
    {
        // タッチされているとき
        if (0 < Input.touchCount)
        {
            // タッチされている指の数だけ処理
            for (int i = 0; i < Input.touchCount; i++)
            {
                // タッチ情報をコピー
                Touch t = Input.GetTouch(i);
                // タッチしたときかどうか
                if (t.phase == TouchPhase.Began)
                {
                    //タッチした位置からRayを飛ばす
                    Ray ray = Camera.main.ScreenPointToRay(t.position);
                    RaycastHit hit = new RaycastHit();
                    if (Physics.Raycast(ray, out hit))
                    {
                        //Rayを飛ばしてあたったオブジェクトが自分自身だったら
                        if (hit.collider.gameObject == this.gameObject)
                        {
                            return true;
                        }
                    }
                }
            }
        }
        return false; //タッチされてなかったらfalse
    }
```
というコードをメンバーより拝借。

```
        if (OnTouchDown())
        {
            Debug.Log("タップされました");
            StartCoroutine(SearchCatch());
        }
```
をupdate内に書けば…うごかぬ。

----

```
    bool OnTouchDown()
    {
        // タッチされているとき
        if (0 < Input.touchCount)
        {

            // タッチされている指の数だけ処理
            for (int i = 0; i < Input.touchCount; i++)
            {
                // タッチ情報をコピー
                Touch t = Input.GetTouch(i);
                // タッチしたときかどうか
                if (t.phase == TouchPhase.Began)
                {
                    l("タッチした位置からRayを飛ばす。:"+ i); //ここまでいけた
                    //タッチした位置からRayを飛ばす
                    Ray ray = Camera.main.ScreenPointToRay(t.position);
                    RaycastHit hit = new RaycastHit();
                    if (Physics.Raycast(ray, out hit))
                    {
                        l("Rayがオブジェクトにヒットしました。");   //ここいかない
                        //Rayを飛ばしてあたったオブジェクトが「Player」だったら
                        if (hit.collider.gameObject == playerObject.gameObject)
                        {
                            l("プレイヤーがタップされました。");
                            return true;
                        }
                    }
                }
            }
        }
        return false; //タッチされてなかったらfalse
    }
```


```:update
        if (OnTouchDown() || Input.GetMouseButtonDown(0))
        {
            Debug.Log("タップされました");
            l("タップされました。");
            StartCoroutine(waveloop());
        }
```

というのが動かなかったので上のオブジェクトにスクリプトをおく。

###子要素のコンポーネントが持つスクリプトを呼び出すには

Unityで他のスクリプトの変数や関数を利用する
http://hiroyukitsuda.com/archives/1702

```
GetComponentInChildren<SonarController>().transmitSonar();
```
という書き方でいけた。

###Rayが飛ばない問題

```
	void Update () {
        if (OnTouchDown() || Input.GetMouseButtonDown(0))
        {
            l("OnTouchDown通過。");
            //SonarControllerを呼ぶ
            sonar.transmitSonar();
        }
    }

    bool OnTouchDown()
    {
        // タッチされているとき
        if (0 < Input.touchCount)
        {
            // タッチされている指の数だけ処理
            for (int i = 0; i < Input.touchCount; i++)
            {
                // タッチ情報をコピー
                Touch t = Input.GetTouch(i);
                // タッチしたときかどうか
                if (t.phase == TouchPhase.Began)
                {
                    l("タップ認識。" + i + ", x:" + t.position.x + ", y:" + t.position.y);
                    //タッチした位置からRayを飛ばす
                    Ray ray = Camera.main.ScreenPointToRay(t.position);
                    l("Ray処理後");    //ここに来ない
                    RaycastHit hit = new RaycastHit();
                    l("RaycastHit後");
                    if (Physics.Raycast(ray, out hit))
                    {
                        l("RaycastHit!: " + i);
                        //Rayを飛ばしてあたったオブジェクトが自分自身だったら
                        if (hit.collider.gameObject == this.gameObject)
                        {
                            return true;
                        }
                    } else
                    {
                        l("(Physics.Raycast(ray, out hit)) はfalseでした");
                    }
                }
            }
        }
        return false; //タッチされてなかったらfalse
    }
```
*l();はログだし用のメソッド。

###Rayが飛ばずにマウスクリックが発動してしまう。

Rayに頼らないコードへと進化。



##ターゲットオブジェクトに当たったらアクションを起こす

コライダに衝突したら、ターゲットの出現のトリガーとする。

###ログだしメソッド

```
    private void l(string s)
    {
        GameObject debugText = GameObject.Find("TextDebug");
        if (debugText)
        {
            Debug.Log("" + s);
            debugText.GetComponent<UnityEngine.UI.Text>().text += "\n" + s;
        }
    }
```


#便利操作
##Visual Studio

- コード整形：選択範囲：Ctrl+K, Ctrl+F