背景
uGUI の Image で Source Image を None にすると白の塗りつぶし画像になります。
一見白塗り画像として使えそうに見えますが、実はこれは Unity が None を UnityWhite というテクスチャに差し替えている状態です(Frame Debugger で確認できます)。
もしこのまま Sprite Atlas を利用すると、テクスチャが交互に使われて Batch 数がかさんでしまいます。
Sprite Atlas に白塗り画像を用意して利用すれば解決しますが、Fillter Mode を Point 以外にするとフチが透けてしまいます。
そこで今回は、Sprite Atlas に用意した白塗り画像の辺を透けさせない設定を紹介します。
設定方法
- 用意した白埋め画像の Sprite Editor を開き、Border を全て 1 に設定
- 白埋めしたい Image の Source Image に白埋め画像を指定
- Image Type を Sliced に変更
もし高解像度モニターで端が透けたら、Pixels Per Unit の桁を増やしてみてください。
問題 : Image Type の Filled が使えない
紹介した方法は Image Type の Sliced 固定が必要なので Filled を利用できません。
ということで、Slider で先の白塗り画像を利用できるコンポーネントを作りました。
ご自由にご利用ください。不具合や改善点があれば連絡をお願いします。
SliderFillImage.cs
using UnityEngine;
using UnityEngine.UI;
[ExecuteAlways]
public class SliderFillImage : MonoBehaviour
{
[SerializeField] private Slider slider;
[SerializeField] private RectTransform backGroundRectTransform;
[SerializeField] private RectTransform fillRectTransform;
[SerializeField] private float offsetWidth;
private void Start()
{
slider.onValueChanged.AddListener(UpdateImageSize);
}
private void UpdateImageSize(float value)
{
var rate = Mathf.LerpUnclamped(slider.minValue, slider.maxValue, value);
switch (slider.direction)
{
default:
case Slider.Direction.LeftToRight:
case Slider.Direction.RightToLeft:
fillRectTransform.sizeDelta = new Vector2(
(backGroundRectTransform.rect.size.x + offsetWidth) * rate,
backGroundRectTransform.rect.size.y);
break;
case Slider.Direction.BottomToTop:
case Slider.Direction.TopToBottom:
fillRectTransform.sizeDelta = new Vector2(
backGroundRectTransform.rect.size.x,
(backGroundRectTransform.rect.size.y + offsetWidth) * rate);
break;
}
}
#if UNITY_EDITOR
private void Update()
{
if (Application.isPlaying) return;
if (slider == null) return;
if (backGroundRectTransform == null) return;
if (fillRectTransform == null) return;
Vector2 pivot, anchorMin, anchorMax;
switch (slider.direction)
{
default:
case Slider.Direction.LeftToRight:
pivot = new Vector2(0.0f, -0.5f);
anchorMin = new Vector2(0.0f, 0.5f);
anchorMax = new Vector2(0.0f, 0.5f);
break;
case Slider.Direction.RightToLeft:
pivot = new Vector2(1.0f, 0.5f);
anchorMin = new Vector2(1.0f, 0.5f);
anchorMax = new Vector2(1.0f, 0.5f);
break;
case Slider.Direction.BottomToTop:
pivot = new Vector2(-0.5f, 0.0f);
anchorMin = new Vector2(0.5f, 0.0f);
anchorMax = new Vector2(0.5f, 0.0f);
break;
case Slider.Direction.TopToBottom:
pivot = new Vector2(0.5f, 1.0f);
anchorMin = new Vector2(0.5f, 1.0f);
anchorMax = new Vector2(0.5f, 1.0f);
break;
}
fillRectTransform.pivot = pivot;
fillRectTransform.anchorMin = anchorMin;
fillRectTransform.anchorMax = anchorMax;
UpdateImageSize(slider.value);
}
#endif
}