Edited at

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

More than 1 year has passed since last update.

本記事はサムザップ Advent Calendar 2017の11日目の記事です。

昨日は@Nitudonさんの「Unityで強化学習しよう!ML-Agentsのススメ」でした


はじめに

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

そんな時、プログレスバーの幅とfillAmountを掛けて座標を計算して動かして・・・などとやるのは若干スマートさに欠けますので、なるべくコードを書かずに実現する方法を紹介したいと思います。


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

まずは一般的なプログレスバー(HPゲージみたいなの)を作ります



  1. プログレスバーを作る


    • スプライトをヒエラルキーに追加し、ImageTypeをFilledにする

    • FillMethodをHorizontalにする




  2. 中継用オブジェクトを追加



    ※このオブジェクトのRectTransformを変化させていきます


  3. 中継オブジェクトに画像やテキストを追加

    お好きな要素をくっつけてください


  4. プログレスバーにスクリプトを追加

    Update中で中継用オブジェクト(RectTransform)のanchorMinanchorMaxにfillAmountの値を代入し、anchoredPositionをゼロにすることで、プログレスバーの先頭にアンカーを移動させています。



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にする




  2. 中継用オブジェクトを追加


  3. 中継オブジェクトに画像やテキストを追加

    お好きな要素をくっつけてください。


  4. 円形プログレスバーにスクリプトを追加

    下記のスクリプトを追加します。

    Updateで中継用オブジェクト(RectTransform)のeulerAnglesを回転させています。



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にもアップしてあります

また、サンプルシーンをunitypackageにまとめてGistにアップしましたのでDLして動かしてみてください


明日は@takahashi_wataruさんの「Unity2017.2.0p3で.Net4.6を使うとVisualStudioのインテリセンスが効かない対処法+α」です。