本文内容
开发过程有个很常见的需求:进度条上下限一致时,进度显示为0%或100%。
但ugui的slider组件默认显示进度为0%,并不能满足显示进度为100%的情况,此文主要为扩展slider组件显示100%进度。
内容及效果
ugui默认效果
如图所示,当上下进度一致时,游标默认停在0%处,且不能拖动。
扩展后效果
如图所示,可以通过调整EqualShowValue字段,控制进度条停留位置。
内容分析
通过查看上图slider源码可以发现,当上下限一致时,默认返回的是0,则进度显示为0%。所以我们可以通过修改此返回值,来达到修改slider游标的停留位置(修改如下图)。
代码
ExtendSlider
using System;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace ExtendUI
{
[AddComponentMenu("UI/ExtendSlider")]
[ExecuteInEditMode]
[RequireComponent(typeof(RectTransform))]
public class ExtendSlider : Slider
{
/// <summary>
/// Set the value of the slider without invoking onValueChanged callback.
/// </summary>
/// <param name="input">The new value for the slider.</param>
public virtual void SetValueWithoutNotify(float input)
{
Set(input, false);
}
[SerializeField]
private float m_EqualShowValue = 0;
/// <summary>
/// The current value of the slider normalized into a value between 0 and 1.
/// </summary>
public new float normalizedValue
{
get
{
if (Mathf.Approximately(minValue, maxValue))
return m_EqualShowValue;
return Mathf.InverseLerp(minValue, maxValue, value);
}
set
{
this.value = Mathf.Lerp(minValue, maxValue, value);
}
}
[Space]
// Private fields
private Image m_FillImage;
private Transform m_FillTransform;
private RectTransform m_FillContainerRect;
private Transform m_HandleTransform;
private RectTransform m_HandleContainerRect;
// The offset from handle position to mouse down position
private Vector2 m_Offset = Vector2.zero;
private DrivenRectTransformTracker m_Tracker;
// This "delayed" mechanism is required for case 1037681.
private bool m_DelayedUpdateVisuals = false;
// Size of each step.
float stepSize { get { return wholeNumbers ? 1 : (maxValue - minValue) * 0.1f; } }
protected ExtendSlider()
{ }
#if UNITY_EDITOR
protected override void OnValidate()
{
base.OnValidate();
if (wholeNumbers)
{
minValue = Mathf.Round(minValue);
maxValue = Mathf.Round(maxValue);
}
//Onvalidate is called before OnEnabled. We need to make sure not to touch any other objects before OnEnable is run.
if (IsActive())
{
UpdateCachedReferences();
Set(value, false);
// Update rects in next update since other things might affect them even if value didn't change.
m_DelayedUpdateVisuals = true;
}
if (!UnityEditor.PrefabUtility.IsPartOfPrefabAsset(this) && !Application.isPlaying)
CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild(this);
}
#endif // if UNITY_EDITOR
public override void Rebuild(CanvasUpdate executing)
{
#if UNITY_EDITOR
if (executing == CanvasUpdate.Prelayout)
onValueChanged.Invoke(value);
#endif
}
protected override void OnEnable()
{
base.OnEnable();
UpdateCachedReferences();
Set(value, false);