ユニティちゃん音球を追いかける 

#ユニティちゃん音球を追いかける 

前回「[ユニティちゃん歩く走る減衰する](http://qiita.com/tatmos/items/c6b729b3abf294fccbb8)」からの更新点は

・今回はカメラもナビメッシュエージェントで追いかけさせてみた。
・ターゲットの球に音楽をつけてみた。
・レベルメータが処理が重い様子なので、Canvasに表示を切り替えてみた。

#動画

[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/D1qPtrxTfA4/0.jpg)](http://www.youtube.com/watch?v=D1qPtrxTfA4)


#ダウンロード (Unityパッケージ)はこちら
[Unity_FootstepsADX2LE_tatmos20160415.unitypackage](https://drive.google.com/open?id=0B_omSCuMqg3edGJhU0ZMUUNrbkU)　
[UnityChanFootsteps_ADX2LE_20160415.zip](https://drive.google.com/open?id=0B_omSCuMqg3eSVVZSm9WdUVfcHc)　 ADX2LEのAtomCraftTool用データ

```
上記パッケージをインポートして自由に使っていただいて構いません。
ってか遊んでみてね。
```

#今回はカメラもナビメッシュエージェントで追いかけさせてみた。

![image](https://qiita-image-store.s3.amazonaws.com/0/96808/2424589f-864f-6201-ebf8-07c221c6b051.png)

カメラにナビメッシュエージェントつけるだけでいい感じに追いかけてくれる。
ただユニティちゃんより速度は遅く動くようにしてみた。
あんまり遅いとカメラの回転とかも遅くなってしまう。調整難しいところ。

##MoveToTargetのスクリプトも少し変えた

・もともとユニティちゃん用だったので、カメラにはアニメないのでその対策。
・カメラは遅くしたかったので、maxSpeedからの相対値で変化するような感じに変更した。

``` MoveToTarget.cs
using UnityEngine;
using System.Collections;

public class MoveToTarget : MonoBehaviour
{
    public Transform target;
    NavMeshAgent agent;

    public float maxSpeed = 6;

    void Start()
    {
        Reset();
    }

    float lastMoveTime = 0f;

    void Update()
    {
        if (Time.timeSinceLevelLoad > lastMoveTime + 0.1f)
        {
            GotoNextPoint();
            lastMoveTime = Time.timeSinceLevelLoad;
        }

        if (animator != null)
        {
            animator.SetFloat("Speed", agent.velocity.sqrMagnitude / 40f);
        }

        //Debug.Log(agent.remainingDistance );
        //  近いとゆっくり
        if (agent.remainingDistance < 2.5f)
        {
            agent.speed = maxSpeed/6f;
            if (animator != null)
            {
                animator.SetTrigger("Rest");
            }
        } else if (agent.remainingDistance < 10f)
        {
            agent.speed = maxSpeed/2f; 
        } else
        {
            agent.speed = maxSpeed;
        }
    }

    void GotoNextPoint()
    {
        agent.SetDestination(target.position);
    }

    [SerializeField, HideInInspector] Animator animator;

    void Reset()
    {
        agent = GetComponent<NavMeshAgent>();
        animator = GetComponent<Animator>();
    }
}
```


#ターゲットの球に音楽をつけてみた。

![image](https://qiita-image-store.s3.amazonaws.com/0/96808/923a0d0a-5537-a7ca-2a7a-d6d6cf150461.png)

bgmキューシートのskybgmという音をPlayOnStartで鳴るように仕掛け、SphereTargetにつけた。

### bgmキューシートを追加した。
もとの作成者が[ksilogic](http://qiita.com/ksilogic)さんので、足音が結構凝ったデータなのと
何か更新があったときに、困らないようにワークユニットもわけておいた。

![image](https://qiita-image-store.s3.amazonaws.com/0/96808/7a03184a-0296-4503-4fad-b6457ddeaa5b.png)

・skybgmはモノラルの音で減衰距離指定もしてある。
![image](https://qiita-image-store.s3.amazonaws.com/0/96808/641aeb0c-c312-eaa1-da04-d66b72da173a.png)

・ランダムに遷移するようにブロック遷移先を組んである。
短い素材だけどループ感をなくすことができる。
![image](https://qiita-image-store.s3.amazonaws.com/0/96808/2eec8d3d-feea-1661-b3dd-affd78775bba.png)


#前のレベルメータが処理が重い様子なので、Canvasに表示を切り替えてみた。
これ
![image](https://qiita-image-store.s3.amazonaws.com/0/96808/8bf36a6b-67ff-b7b7-073a-aa5f27bd71c2.png)
Sliderをレベルメータとして使ってます。
![image](https://qiita-image-store.s3.amazonaws.com/0/96808/43f4a986-7268-179e-809c-67417be02e9a.png)

``` CanvasAtomDebug.cs
using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class CanvasAtomDebug : MonoBehaviour
{

    public Slider[] sliders = new Slider[4];
    Text[] texts = new Text[4];

    // Use this for initialization
    void Start()
    {
        for (int ch = 0; ch < 4; ch++)
        {
            texts [ch] = sliders [ch].GetComponentInChildren<Text>();
        }
    }
	
    // Update is called once per frame
    void Update()
    {
        for (int ch = 0; ch < 4; ch++)
        {
            int readch = ch;
            if (ch > 1)
                readch = ch + 2;

            float level = CriAtom.GetBusAnalyzerInfo(0).peakLevels [readch];
            sliders [ch].value = level;
            texts [ch].text = getDb(level, ch);
        }
    }

    string[] meterName = new string[]{ "L ", "R ", "Ls", "Rs" };

    private string getDb(float volume, int ch)
    {
        float retValue = Mathf.Floor(20.0f * Mathf.Log10(volume) * 100f) / 100f;
        if (retValue < -96)
        {
            retValue = -96;
        }
        return string.Format("{0}:{1:#0.#0} dB", meterName [ch], retValue);
    }

}

```

##サラウンド側が鳴っていない？
どうもMacだとサラウンド側が鳴っていない様子なので、簡易的にダウンミックス(４ch->2ch)にするように「マトリクス」エフェクトでルーティングを変えている。
(Unity以外なら初期化時にoutputchannel数（最終出力チャンネル数）を選択できるのだが・・・たぶんデフォルト6chになっている。）
これは、バランスは適当調整で、サラウンドが別途ミックスされてしまうwindowsのようなOSがダウンミックスする環境や、ちゃんと6ch対応のデバイスをつけている場合はバランスが崩れる（前からの音が多めになる）。

ちなみに、iOS/Androidの場合は最終出力がデフォルト2chなので、これしなくてもダウンミックス勝手にかかります。

![image](https://qiita-image-store.s3.amazonaws.com/0/96808/1f58a0ae-2bc9-781e-fd22-73b13cbd4247.png)

##忘れがちなDSPバス設定
![image](https://qiita-image-store.s3.amazonaws.com/0/96808/27fa96c7-98fa-11e5-2e4b-4b6027de1836.png)
DspBusSetting_0という名前が抜けていることがよくあるので、ここに書き込む。
あと、今回はbgmキューシートもロードしておくので、「Add CueSheet」ボタンで指定。


##減衰距離のパラメータ調整してみた
前回「[ユニティちゃん歩く走る減衰する](http://qiita.com/tatmos/items/c6b729b3abf294fccbb8)」のは結構遠くまで音が聞こえるようにしていたのだけど、今回は画面にあったように調整してみた。
![image](https://qiita-image-store.s3.amazonaws.com/0/96808/9d987990-60d9-db62-e803-b9ef443ab750.png)
なんとなく「Portal」とかのラジオくらいの距離減衰感なつもり。

#ドップラーもかかってる
高速に音源が移動するとピッチが変化する。救急車のサイレンとかF1の通過音とか。

ボールも高速に移動するようにしてみた。
Slerpで補間してます。
ゴルフボールのショット時の「ビュン」って感じになる。（あれは風切り音がドップラーしているのかな）

![image](https://qiita-image-store.s3.amazonaws.com/0/96808/177bf3f2-08ad-fc59-8332-54fadb1fbb98.png)
ちなみにドップラー係数1.00で1気圧での音速に応じたピッチ変化をする。これ0にすればドップラーかからないようにもできるし、速度が遅いときでもドップラーかけたい場合は1以上の大きな値をセットするとかも可能。

```　RandomMove.cs
using UnityEngine;
using System.Collections;

public class RandomMove : MonoBehaviour {
    void Start () {
        Reset();
	}
	
    float respawnTime = 10f;
    float lastMoveTime = 8f;
    float journeyTime = 1f;

    Vector3 nextPos = new Vector3(0,5,0);

	void Update () {
        if(Time.timeSinceLevelLoad > lastMoveTime+respawnTime)
        {
            Reset();
        }

        float fracComplete = (Time.time - lastMoveTime) / journeyTime;
        if(fracComplete < 1){
            this.transform.localPosition = Vector3.Slerp(this.transform.localPosition,nextPos,
            fracComplete);
        }
	}

    public void Reset()
    {
        nextPos = new Vector3(Random.Range(0,5),5,Random.Range(0,-50));
        lastMoveTime = Time.time;
    }

}
```
#以上