当前位置:网站首页>【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();
}
}
边栏推荐
- Because of hard work, the fruit goes with fate
- Basic notes of illusory AI blueprint (10000 words)
- Project practice, redis cluster technology learning (11)
- 【虚幻4】UMG组件的简介与使用(更新中...)
- [IDL] Research
- Bugkuctf-web24 (problem solving ideas and steps)
- C language strawberry
- Remember the use of add method once
- 2837xd代码生成模块学习(4)——idle_task、Simulink Coder
- Junit4 runs MVN test test suite upgrade scheme
猜你喜欢
Blender多鏡頭(多機比特)切換
UE4 night lighting notes
ue虚幻引擎程序化植物生成器设置——如何快速生成大片森林
[ue5] animation redirection: how to import magic tower characters into the game
UE illusory engine programmed plant generator setup -- how to quickly generate large forests
Applet development summary
How to achieve the top progress bar effect in background management projects
This monitoring system makes workers tremble: turnover intention and fishing can be monitored. After the dispute, the product page has 404
Unreal material editor foundation - how to connect a basic material
Junit4运行mvn test 测试套件升级方案
随机推荐
Ue5 - AI pursuit (blueprint, behavior tree)
Deep understanding of redis cache avalanche / cache breakdown / cache penetration
2837xd code generation - stateflow (2)
Project practice, redis cluster technology learning (11)
[ue5] two implementation methods of AI random roaming blueprint (role blueprint and behavior tree)
UE4夜间打光笔记
Alibaba cloud SLS log service
Alibaba cloud Prometheus monitoring service
Bugkuctf-web24 (problem solving ideas and steps)
Project practice, redis cluster technology learning (6)
Introduction to go language
【避坑指南】使用UGUI遇到的坑:Text组件无法首行缩进两格
Remember a simple Oracle offline data migration to tidb process
The primary market project galaxy will conduct public offering on coinlist on February 17
Remember the use of add method once
2837xd code generation module learning (4) -- idle_ task、Simulink Coder
Bookmark collection management software suspension reading and data migration between knowledge base and browser bookmarks
【leetcode】33. Search rotation sort array
2837xd code generation module learning (3) -- IIC, ECAN, SCI, watchdog, ECAP modules
Blender摄像机环绕运动、动画渲染、视频合成