uGUIでプログレスバーの動きに合わせて子要素を動かす

本記事は[サムザップ Advent Calendar 2017](https://qiita.com/advent-calendar/2017/sumzap)の11日目の記事です。
昨日は@Nitudonさんの「[Unityで強化学習しよう！ML-Agentsのススメ](http://myudon.hatenablog.com/entry/2017/12/10/000120)」でした

#はじめに
uGUIでプログレスバーを作るときに、fillAmountの値に合わせてテキストや画像を動かしたい！という事はよくありますよね（そうでもない）。

そんな時、プログレスバーの幅とfillAmountを掛けて座標を計算して動かして・・・などとやるのは若干スマートさに欠けますので、なるべくコードを書かずに実現する方法を紹介したいと思います。
<img src="https://qiita-image-store.s3.amazonaws.com/0/22207/a7cd9d8c-719a-c2c3-3bac-ecf2ed76bed3.gif" width=60%>
#プログレスバーの先頭にくっついて動くやつを作る
まずは一般的なプログレスバー（HPゲージみたいなの）を作ります

1. プログレスバーを作る
 - スプライトをヒエラルキーに追加し、ImageTypeをFilledにする
 - FillMethodをHorizontalにする
<img src="https://qiita-image-store.s3.amazonaws.com/0/22207/4d91b54a-7d55-5343-98f7-e61a11c339fa.png" width=80%>

2. 中継用オブジェクトを追加
<img src="https://qiita-image-store.s3.amazonaws.com/0/22207/cf7bb947-fadd-e8be-f7a0-a2510bd998dc.png" width=80%>
※このオブジェクトのRectTransformを変化させていきます

3. 中継オブジェクトに画像やテキストを追加
お好きな要素をくっつけてください

4. プログレスバーにスクリプトを追加
Update中で中継用オブジェクト（RectTransform）の**anchorMin**と**anchorMax**にfillAmountの値を代入し、**anchoredPosition**をゼロにすることで、プログレスバーの先頭にアンカーを移動させています。

```csharp:barAnchor.cs
using UnityEngine;
using UnityEngine.UI;

public class barAnchor : MonoBehaviour 
{
    Image barImage;

    [SerializeField]
    Text textObj;

    [SerializeField]
    RectTransform anchorObj;

    // Use this for initialization
    void Start()
    {
        barImage = GetComponent<Image>();
    }

    // Update is called once per frame
    void Update()
    {
        // イメージのfillAmountを変化させる
        barImage.fillAmount += 0.01f;
        if (barImage.fillAmount >= 1.0f)
        {
            barImage.fillAmount = 0f;
        }
        // テキストを更新
        textObj.text = barImage.fillAmount.ToString("P1");

        // fillAmountの値に合わせてアンカーを更新
        anchorObj.anchorMin = new Vector2(barImage.fillAmount, anchorObj.anchorMin.y);
        anchorObj.anchorMax = new Vector2(barImage.fillAmount, anchorObj.anchorMax.y);
        anchorObj.anchoredPosition = Vector2.zero;
    }
}
```


#円形プログレスバーの先頭にくっついて動くやつを作る

1. 円形プログレスバーを作る
 - スプライトをヒエラルキーに追加し、ImageTypeをFilledにする
 - FillMethodをRadial360にする
<img src="https://qiita-image-store.s3.amazonaws.com/0/22207/4c0b9822-0044-5cfd-9523-d031dd50df0d.png" width=80%>

2. 中継用オブジェクトを追加
3. 中継オブジェクトに画像やテキストを追加
お好きな要素をくっつけてください。

4. 円形プログレスバーにスクリプトを追加
下記のスクリプトを追加します。
Updateで中継用オブジェクト（RectTransform）のeulerAnglesを回転させています。

```csharp:circleAnchor.cs
using UnityEngine;
using UnityEngine.UI;

public class circleAnchor : MonoBehaviour 
{
    Image barImage;
 
    [SerializeField]
    Text textObj;

    [SerializeField]
    RectTransform anchorObj;

    // Use this for initialization
    void Start()
    {
        barImage = GetComponent<Image>();
    }

    // Update is called once per frame
    void Update()
    {
        // イメージのfillAmountを変化させる
        barImage.fillAmount += 0.01f;
        if (barImage.fillAmount >= 1.0f)
        {
            barImage.fillAmount = 0f;
        }
        // テキストを更新
        textObj.text = barImage.fillAmount.ToString("P1");

        // fillAmountの値に合わせてアンカーの角度を更新
        anchorObj.eulerAngles = new Vector3(0, 0, barImage.fillAmount * -360);
	}
}
```

※この記事のスクリプトは[Gistにもアップしてあります](https://gist.github.com/yosizo/e8d67115a0ba2ab7c4c12b4344620531)
また、サンプルシーンをunitypackageにまとめてGistにアップしましたのでDLして動かしてみてください

----
明日は@takahashi_wataruさんの「[Unity2017.2.0p3で.Net4.6を使うとVisualStudioのインテリセンスが効かない対処法+α](https://qiita.com/takahashi_wataru/items/9bff12e49899f209fd78)」です。