当前位置:网站首页>【Unity3D】制作进度条——让Image同时具有Filled和Sliced的功能
【Unity3D】制作进度条——让Image同时具有Filled和Sliced的功能
2022-07-02 06:36:00 【趁着头发多我想做游戏】
解决方案转载于:UGUI——重写Image类实现进度条 作者:糯米团子滚呀滚
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Sprites;
public class childImage : Image{
protected override void OnPopulateMesh(VertexHelper toFill)
{
base.OnPopulateMesh(toFill);
if (overrideSprite == null)
{
base.OnPopulateMesh(toFill);
return;
}
if (type == Type.Sliced)
{
GenerateSlicedSprite_(toFill);
}
}
Vector4 GetAdjustedBorders(Vector4 border, Rect rect)
{
for (int axis = 0; axis <= 1; axis++)
{
// If the rect is smaller than the combined borders, then there's not room for the borders at their normal size.
// In order to avoid artefacts with overlapping borders, we scale the borders down to fit.
float combinedBorders = border[axis] + border[axis + 2];
if (rect.size[axis] < combinedBorders && combinedBorders != 0)
{
float borderScaleRatio = rect.size[axis] / combinedBorders;
border[axis] *= borderScaleRatio;
border[axis + 2] *= borderScaleRatio;
}
}
return border;
}
static void AddQuad(VertexHelper vertexHelper, Vector2 posMin, Vector2 posMax, Color32 color, Vector2 uvMin, Vector2 uvMax)
{
int startIndex = vertexHelper.currentVertCount;
vertexHelper.AddVert(new Vector3(posMin.x, posMin.y, 0), color, new Vector2(uvMin.x, uvMin.y));
vertexHelper.AddVert(new Vector3(posMin.x, posMax.y, 0), color, new Vector2(uvMin.x, uvMax.y));
vertexHelper.AddVert(new Vector3(posMax.x, posMax.y, 0), color, new Vector2(uvMax.x, uvMax.y));
vertexHelper.AddVert(new Vector3(posMax.x, posMin.y, 0), color, new Vector2(uvMax.x, uvMin.y));
vertexHelper.AddTriangle(startIndex, startIndex + 1, startIndex + 2);
vertexHelper.AddTriangle(startIndex + 2, startIndex + 3, startIndex);
}
private void GenerateSlicedSprite_(VertexHelper toFill)
{
Vector4 outer, inner, padding, border;
if (overrideSprite != null)
{
outer = DataUtility.GetOuterUV(overrideSprite);
inner = DataUtility.GetInnerUV(overrideSprite);
padding = DataUtility.GetPadding(overrideSprite);
border = overrideSprite.border;
}
else
{
outer = Vector4.zero;
inner = Vector4.zero;
padding = Vector4.zero;
border = Vector4.zero;
}
Rect rect = GetPixelAdjustedRect();
border = GetAdjustedBorders(border / pixelsPerUnit, rect);
padding = padding / pixelsPerUnit;
float condition = (border.z + border.x) / rect.width;
#region 实际显示size
float[] x={
0,0,0,0};
x[0] = 0;
if (fillAmount <condition)
{
x[1] = fillAmount / 2 * rect.width;
x[2] = x[1]+ 0;
x[3] = x[1]*2;
}
else
{
x[1] = border.x;
x[2] = rect.width *fillAmount-border.z;
x[3] =x[2]+border.z;
}
float []y ={
0+rect.y,rect.height+rect.y};
for (int i = 0; i < 4; ++i)
{
x[i] += rect.x;
}
#endregion
#region uv值
float[] x_uv = {
0,0,0,0 };
x_uv[0] =0;
if (fillAmount <condition)
{
x_uv[1] = fillAmount*rect.width/2/sprite.rect.size.x;
x_uv[2] = 1 - x_uv[1];
}
else
{
x_uv[1] = inner.x;
x_uv[2] = inner.z;
}
x_uv[3] = outer.z;
float y_uv = 1;
#endregion
toFill.Clear();
for (int i = 0; i < 3; i++)
{
int i2 = i + 1;
AddQuad(toFill,
new Vector2(x[i],y[0]),
new Vector2(x[i2],y[1]),
color,
new Vector2(x_uv[i],0),
new Vector2(x_uv[i2],y_uv));
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor.UI;
using UnityEditor;
using UnityEditor.AnimatedValues;
using System.Linq;
[CustomEditor(typeof(childImage))]
public class ChildchildImageInspector : ImageEditor
{
SerializedProperty m_FillMethod;
SerializedProperty m_FillOrigin;
SerializedProperty m_FillAmount;
SerializedProperty m_FillClockwise;
SerializedProperty m_Type;
SerializedProperty m_FillCenter;
SerializedProperty m_Sprite;
SerializedProperty m_PreserveAspect;
GUIContent m_SpriteContent;
GUIContent m_SpriteTypeContent;
GUIContent m_ClockwiseContent;
AnimBool m_ShowSlicedOrTiled;
AnimBool m_ShowSliced;
AnimBool m_ShowFilled;
AnimBool m_ShowType;
void SetShowNativeSize(bool instant)
{
childImage.Type type = (childImage.Type)m_Type.enumValueIndex;
bool showNativeSize = (type == childImage.Type.Simple || type == childImage.Type.Filled);
base.SetShowNativeSize(showNativeSize, instant);
}
protected override void OnEnable()
{
base.OnEnable();
m_SpriteContent = new GUIContent("Source childImage");
m_SpriteTypeContent = new GUIContent("childImage Type");
m_ClockwiseContent = new GUIContent("Clockwise");
m_Sprite = serializedObject.FindProperty("m_Sprite");
m_Type = serializedObject.FindProperty("m_Type");
m_FillCenter = serializedObject.FindProperty("m_FillCenter");
m_FillMethod = serializedObject.FindProperty("m_FillMethod");
m_FillOrigin = serializedObject.FindProperty("m_FillOrigin");
m_FillClockwise = serializedObject.FindProperty("m_FillClockwise");
m_FillAmount = serializedObject.FindProperty("m_FillAmount");
m_PreserveAspect = serializedObject.FindProperty("m_PreserveAspect");
m_ShowType = new AnimBool(m_Sprite.objectReferenceValue != null);
m_ShowType.valueChanged.AddListener(Repaint);
var typeEnum = (childImage.Type)m_Type.enumValueIndex;
m_ShowSlicedOrTiled = new AnimBool(!m_Type.hasMultipleDifferentValues && typeEnum == childImage.Type.Sliced);
m_ShowSliced = new AnimBool(!m_Type.hasMultipleDifferentValues && typeEnum == childImage.Type.Sliced);
m_ShowFilled = new AnimBool(!m_Type.hasMultipleDifferentValues && typeEnum == childImage.Type.Filled);
m_ShowSlicedOrTiled.valueChanged.AddListener(Repaint);
m_ShowSliced.valueChanged.AddListener(Repaint);
m_ShowFilled.valueChanged.AddListener(Repaint);
SetShowNativeSize(true);
}
public override void OnInspectorGUI()
{
serializedObject.Update();
SpriteGUI();
AppearanceControlsGUI();
RaycastControlsGUI();
m_ShowType.target = m_Sprite.objectReferenceValue != null;
if (EditorGUILayout.BeginFadeGroup(m_ShowType.faded))
{
EditorGUILayout.PropertyField(m_Type, m_SpriteTypeContent);
++EditorGUI.indentLevel;
{
childImage.Type typeEnum = (childImage.Type)m_Type.enumValueIndex;
bool showSlicedOrTiled = (!m_Type.hasMultipleDifferentValues && (typeEnum ==childImage.Type.Sliced|| typeEnum == childImage.Type.Tiled));
if (showSlicedOrTiled && targets.Length > 1)
showSlicedOrTiled = targets.Select(obj => obj as childImage).All(img => img.hasBorder);
m_ShowSlicedOrTiled.target = showSlicedOrTiled;
m_ShowSliced.target = (showSlicedOrTiled && !m_Type.hasMultipleDifferentValues && typeEnum == childImage.Type.Sliced);
m_ShowFilled.target = (!m_Type.hasMultipleDifferentValues && typeEnum == childImage.Type.Filled);
childImage cImage = target as childImage;
if (EditorGUILayout.BeginFadeGroup(m_ShowSlicedOrTiled.faded))
{
if (cImage.hasBorder)
{
EditorGUILayout.PropertyField(m_FillCenter);
EditorGUILayout.PropertyField(m_FillAmount);
}
}
EditorGUILayout.EndFadeGroup();
if (EditorGUILayout.BeginFadeGroup(m_ShowSliced.faded))
{
if (cImage.sprite != null && !cImage.hasBorder)
EditorGUILayout.HelpBox("This childImage doesn't have a border.", MessageType.Warning);
}
EditorGUILayout.EndFadeGroup();
if (EditorGUILayout.BeginFadeGroup(m_ShowFilled.faded))
{
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(m_FillMethod);
if (EditorGUI.EndChangeCheck())
{
m_FillOrigin.intValue = 0;
}
switch ((childImage.FillMethod)m_FillMethod.enumValueIndex)
{
case childImage.FillMethod.Horizontal:
m_FillOrigin.intValue = (int)(childImage.OriginHorizontal)EditorGUILayout.EnumPopup("Fill Origin", (childImage.OriginHorizontal)m_FillOrigin.intValue);
break;
case childImage.FillMethod.Vertical:
m_FillOrigin.intValue = (int)(childImage.OriginVertical)EditorGUILayout.EnumPopup("Fill Origin", (childImage.OriginVertical)m_FillOrigin.intValue);
break;
case childImage.FillMethod.Radial90:
m_FillOrigin.intValue = (int)(childImage.Origin90)EditorGUILayout.EnumPopup("Fill Origin", (childImage.Origin90)m_FillOrigin.intValue);
break;
case childImage.FillMethod.Radial180:
m_FillOrigin.intValue = (int)(childImage.Origin180)EditorGUILayout.EnumPopup("Fill Origin", (childImage.Origin180)m_FillOrigin.intValue);
break;
case childImage.FillMethod.Radial360:
m_FillOrigin.intValue = (int)(childImage.Origin360)EditorGUILayout.EnumPopup("Fill Origin", (childImage.Origin360)m_FillOrigin.intValue);
break;
}
EditorGUILayout.PropertyField(m_FillAmount);
if ((childImage.FillMethod)m_FillMethod.enumValueIndex > childImage.FillMethod.Vertical)
{
EditorGUILayout.PropertyField(m_FillClockwise, m_ClockwiseContent);
}
}
EditorGUILayout.EndFadeGroup();
}
--EditorGUI.indentLevel;
}
EditorGUILayout.EndFadeGroup();
SetShowNativeSize(false);
if (EditorGUILayout.BeginFadeGroup(m_ShowNativeSize.faded))
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_PreserveAspect);
EditorGUI.indentLevel--;
}
EditorGUILayout.EndFadeGroup();
NativeSizeButtonGUI();
serializedObject.ApplyModifiedProperties();
}
}
边栏推荐
- Image recognition - Data Cleaning
- MySQL index
- 2837xd代码生成模块学习(3)——IIC、eCAN、SCI、Watchdog、eCAP模块
- Skywalking theory and Practice
- Configuration programmée du générateur de plantes du moteur illusoire UE - - Comment générer rapidement une grande forêt
- Project practice, redis cluster technology learning (6)
- [200 Shengxin literatures] 96 joint biomarkers of immune checkpoint inhibitor response in advanced solid tumors
- Blender multi lens (multi stand) switching
- 2837xd code generation module learning (4) -- idle_ task、Simulink Coder
- Unreal material editor foundation - how to connect a basic material
猜你喜欢
随机推荐
Judging right triangle in C language
Share a blog (water blog)
Image recognition - Data Cleaning
Network real-time video streaming based on OpenCV
Blender摄像机环绕运动、动画渲染、视频合成
虚幻AI蓝图基础笔记(万字整理)
滲透測試的介紹和防範
Project practice, redis cluster technology learning (VII)
How does {} prevent SQL injection? What is its underlying principle?
Matlab generates DSP program -- official routine learning (6)
Junit4运行mvn test 测试套件升级方案
Metaclass type and using metaclass to implement model class ORM
Error reporting on the first day of work (incomplete awvs unloading)
Vscode auto format
Junit5 supports suite methods
Operator exercises
Remember a simple Oracle offline data migration to tidb process
How to achieve the top progress bar effect in background management projects
ue4材质的入门和原理笔记
2837xd 代码生成——StateFlow(1)









