当前位置:网站首页>【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();
}
}
边栏推荐
- Alibaba cloud Prometheus monitoring service
- ERROR 1118 (42000): Row size too large (&gt; 8126)
- Edge computing accelerates live video scenes: clearer, smoother, and more real-time
- Ue5 - AI pursuit (blueprint, behavior tree)
- What is the relationship between realizing page watermarking and mutationobserver?
- What wires are suitable for wiring on bread board?
- Image recognition - Data Cleaning
- 虚幻AI蓝图基础笔记(万字整理)
- MySQL index
- Career planning and development
猜你喜欢

Matlab生成dsp程序——官方例程学习(6)

Image recognition - data annotation

2837xd code generation module learning (2) -- ADC, epwm module, timer0

UE5——AI追逐(藍圖、行為樹)

UE4夜间打光笔记

Attack and defense world web advanced area unserialize3

2837xd 代码生成——StateFlow(1)

Leetcode -- the nearest common ancestor of 236 binary tree

The latest progress and development trend of 2022 intelligent voice technology

渗透测试的介绍和防范
随机推荐
Project practice, redis cluster technology learning (13)
Large neural networks may be beginning to realize: the chief scientist of openai leads to controversy, and everyone quarrels
阿里云短信服务
[200 Shengxin literatures] 96 joint biomarkers of immune checkpoint inhibitor response in advanced solid tumors
Ue5 - ai Pursuit (Blueprint, Behavior tree)
【leetcode】33. Search rotation sort array
【虚幻4】从U3D到UE4的转型之路
[ue5] animation redirection: how to import magic tower characters into the game
阿里云Prometheus监控服务
Mysql索引
Blender多鏡頭(多機比特)切換
Ctrip starts mixed office. How can small and medium-sized enterprises achieve mixed office?
MySQL -- time zone / connector / driver type
Mixed development of uni app -- Taking wechat applet as an example
2837xd代码生成模块学习(4)——idle_task、Simulink Coder
Aiphacode is not a substitute for programmers, but a tool for developers
How much is it to develop a system software in Beijing, and what funds are needed to develop the software
Blender multi lens (multi stand) switching
Skywalking理论与实践
UE4 night lighting notes