カードのレアリティや、ステージのクリア率を表す星のUIをコントロール。
0.5単位を表現するAパターンと、更に細かい単位まで表現するBパターンを用意。
GIMPでの、星の画像素材の作り方もあります。
サンプル動画
【Aパターン】0.5単位で表現
【Bパターン】もっと細かく表現
前提
以下の、2パターンを用意しています。
Aパターンはシンプル版、Bパターンは高機能版といった感じです。
- 【Aパターン】星(半分)を別の画像として扱う。0.25~0.74までを星(半分)として丸める。
- 【Bパターン】星画像をImage Type:Filledに設定して、画像の欠け具合を変更する。
星の画像素材を用意
手持ちのアセットから用意するか、自作する。
もしくは、↓の画像を使っても良い。
【ダウンロード】星の画像素材(簡易)
- 圧縮済み
- ライセンス:CC0
黄色星(フル)
黄色星(半分)
*Aパターンでのみ使用。
一応、白色も。
【GIMP】星の画像素材の作り方
- *GIMPの言語設定:日本語
- キャンバスを任意の大きさに設定(希望する星画像より大きめに)。
- 上部メニュー -> フィルター -> 下塗り -> シェイプ(Gfig)を選択。
- 出現したダイアログ -> 上部メニューの下のアイコン群 -> 左から七番目の「星の作成」を選択。
- ツールオプション -> サイズ:5
- 輪郭を描画する:任意(有効にすると、現在のブラシで輪郭が追加される)
- 塗りつぶし:色で塗りつぶす
- 色:黄色
- グリッドにスナップ:有効
- 画像部分で中心から上にドラッグし、適度な大きさの星作成。
- シェイプ(Gfig)フィルターでのグリッドの設定は、30に固定されている模様。
Unityへ画像をインポート
- Projectウィンドウ -> 任意のフォルダに、画像をドラッグ&ドロップしてインポート。
- 【3Dモードの場合】インスペクター -> Texture Typeを、Sprite (2D and UI)に変更。
(2Dモードの場合は、デフォルトでSprite (2D and UI)になっている)
ざっくりした手順
- Canvas作成。
- UI Scale Mode:Scale With Screen Sizeに設定。
- Reference Resolution:(1920, 1080)等に設定。
- Canvas下に、空のオブジェクト作成、「Stars」と命名。
- Horizontal Layout Groupをアタッチ。
- Child Alignment:Middle Centerに設定。
- Content Size Fitterをアタッチ。
- Horizontal Fit:Preferred Sizeに設定。
- Vertical Fit:Preferred Sizeに設定。
- Horizontal Layout Groupをアタッチ。
- Image作成、”Star”と命名。
- 【Bパターン】Image Type:Filled
- 【Bパターン】Fill Method:Horizontal
- 新規スクリプトをアタッチ、後述のStarのコードを記述。
- インスペクターから、各変数へStar自らをドラッグ&ドロップ。
- プレハブ化。
- 空のオブジェクトを作成、「UIManager」と命名。
- 新規スクリプトをアタッチ、後述のUIManagerのコードを記述。
- インスペクターから、各変数へ対象のオブジェクトをドラッグ&ドロップ。
詳細な手順
Canvas作成
- 上部メニュー -> GameObject -> UI -> Canvasを作成。
- インスペクター -> Canvas Scalerコンポーネントを設定。
- UI Scale Mode:Scale With Screen Size
- Reference Resolution:(X 1920, Y 1080)
Stars(整列用の親オブジェクト)を作成
- ヒエラルキー -> Canvasを選択。
- 上部メニュー -> GameObject -> Create Empty Childを選択、「Stars」と命名。
- インスペクター -> Add Component -> 「Horizontal Layout Group」を作成、続いて設定。
- Spacing:任意の値(星間の距離になる)
- Child Alignment:Middle Center
- インスペクター -> Add Component -> 「Content Size Fitter」を作成、続いて設定。
- Horizontal Fit:Preferred Size
- Vertical Fit:Preferred Size
Star(星本体)を作成
- 上部メニュー -> GameObject -> UI -> Imageを作成、「Star」と命名。
- 【Bパターン】インスペクター -> Imageコンポーネントを設定。
- 【Bパターン】Image Type:Filled
- 【Bパターン】Fill Method:Horizontal
- インスペクター -> Add Component -> New scriptを選択、「Star」と命名。
- 以下のコードを貼り付け。
- インスペクターで各種変数にオブジェクトを紐付けしておく。
【コード】Star
管理クラスで、星にアタッチされたコンポーネントを複数扱うので、このクラスにまとめている。
using UnityEngine;
using UnityEngine.UI;
public class Star : MonoBehaviour
{
//インスペクターから、各種コンポーネントを紐付け。
public GameObject go;
public RectTransform rt;
public Image img;
public bool isActive;
public void SetActive(bool b)
{
isActive = b;
go.SetActive(b);
}
}
UIManager(星管理用オブジェクト)を作成
- 上部メニュー -> GameObject -> Create Emptyを選択、「UIManager」と命名。
- インスペクター -> Add Component -> New scriptを選択、「UIManager」と命名。
- 以下のコードを貼り付け。
- インスペクターで各種変数にオブジェクトを紐付けしておく。
【コード/Aパターン】UIManager
星の表示管理用クラス。
クラス名と合わせれば、任意の名前で良いです。
//使わなかった為、一応コメントアウト。
//using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
//スクリプト名と一致していれば、UIManagerじゃなくて任意の名前で良い。
public class UIManager : MonoBehaviour
{
//インスペクターから、インポートした星の画像を紐付けておく。
[SerializeField]
Sprite starSpr;
//インスペクターから、インポートした星(半分)の画像を紐付けておく。
[SerializeField]
Sprite halfStarSpr;
//インスペクターから、"Stars"(Starの親オブジェクト)を紐付けておく。
[SerializeField]
Transform starsParentTf;
//インスペクターから、Starのプレハブを紐付けておく。
[SerializeField]
GameObject starPrefab;
//Starクラスを保持。
List<Star> starList = new List<Star>(StarCountMax);
//星数の上限。任意の値。
static readonly int StarCountMax = 3;
//Starのサイズ。任意の値。
Vector2 starSize = new Vector2(100.0f, 100.0f);
//HalfStarのサイズ。Xは、StarのXの半分。Yは同じ値で。
Vector2 halfStarSize = new Vector2(50.0f, 100.0f);
//アクティブな最後尾の星のインデックス。
int starEndIndex = -1;
float remainder;
void Awake()
{
InitializeStars();
}
//星々の初期化。
void InitializeStars()
{
for (int i = 0; i < StarCountMax; i++) {
starList.Add(Instantiate(starPrefab, starsParentTf).GetComponent<Star>());
starList[i].SetActive(false);
}
}
//星を表示したい時に呼ぶ。引数には表示したい星数(float型)を渡す。リセットを入れているので、後から星数の変更可能。
void UpdateStars(float starCount)
{
ResetStars();
//星数のリミッター。
if (StarCountMax < starCount)
starCount = StarCountMax;
//starCountに応じて、星をアクティブ化。
for (int i = 0; i < StarCountMax; i++) {
starList[i].SetActive(i < starCount);
}
//端数が0.25~0.74ならば、HalfStarの画像に差し替え。大きさも合わせる。
remainder = starCount % 1.0f;
if (0.25f <= remainder && remainder < 0.75f) {
starEndIndex = Mathf.FloorToInt(starCount / 1.0f);
starList[starEndIndex].img.sprite = halfStarSpr;
starList[starEndIndex].rt.sizeDelta = halfStarSize;
}
}
//弄った星のインデックスを記録しておいて、その部分のみリセット。
void ResetStars()
{
if (starEndIndex != -1) {
starList[starEndIndex].img.sprite = starSpr;
starList[starEndIndex].rt.sizeDelta = starSize;
}
}
}
【コード/Bパターン】UIManager
//使わなかった為、一応コメントアウト。
//using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//using UnityEngine.UI;
//スクリプト名と一致していれば、UIManagerじゃなくて任意の名前で良い。
public class UIManager : MonoBehaviour
{
//インスペクターから、"Stars"(Starの親オブジェクト)を紐付けておく。
[SerializeField]
Transform starsParentTf;
//インスペクターから、Starのプレハブを紐付けておく。
[SerializeField]
GameObject starPrefab;
List<Star> starList = new List<Star>(StarCountMax);
//星数の上限。任意の値。
static readonly int StarCountMax = 3;
//アクティブな最後尾の星のインデックス(fillAmountを変更して欠け具合を調整する星)。
int starEndIndex = -1;
float remainder;
void Awake()
{
InitializeStars();
}
void InitializeStars()
{
for (int i = 0; i < StarCountMax; i++) {
starList.Add(Instantiate(starPrefab, starsParentTf).GetComponent<Star>());
starList[i].SetActive(false);
}
}
void UpdateStars(float starCount)
{
ResetStars();
if (StarCountMax < starCount)
starCount = StarCountMax;
for (int i = 0; i < StarCountMax; i++) {
starList[i].SetActive(i < starCount);
}
//1で割った余りを、fillAmountに入れて星の欠け具合に適用している。
remainder = starCount % 1.0f;
if (0 < remainder) {
starEndIndex = Mathf.FloorToInt(starCount / 1.0f);
starList[starEndIndex].img.fillAmount = remainder;
}
}
void ResetStars()
{
if (starEndIndex != -1) {
starList[starEndIndex].img.fillAmount = 1.0f;
}
}
}