使用了NGUI多年,最终还是转入UGUI门下,刚一上手就发现了一个小问题,没找到图片翻转功能。网上查阅一番,确实没有,那么只好自己造轮子了。
既然两个UI工具开发者相同,那么代码应该也类似,打开我心爱的Rider编辑器(至于为什么又用回Rider,因为它足够强),随便写个Image的变量定义,然后跳转到声明处,Image类源码就展现出来了,不用切源码项目看源码,真香!
先说一下翻转图片的做法原理,一个Image其实就是一个模型片,普通模式的Image就是由4个顶点2个三角形组成的(当然九宫格等模式会复杂喝多)。如果需要左右翻转,我们可以左右翻转所有顶点(翻过来显示背面),也可以左右翻转所有顶点的UV(仅限顶点对称的情况下,比如九宫格就不合适)。所以翻转顶点就是我们要做的事情,我们来看代码。
有源码就是好,很快就锁定了方法OnPopulateMesh(),长成这样还是个override,必定有妖异:
/// <summary>
/// Update the UI renderer mesh.
/// </summary>
protected override void OnPopulateMesh(VertexHelper toFill)
{
if (activeSprite == null)
{
base.OnPopulateMesh(toFill);
return;
}
switch (type)
{
case Type.Simple:
if (!useSpriteMesh)
GenerateSimpleSprite(toFill, m_PreserveAspect);
else
GenerateSprite(toFill, m_PreserveAspect);
break;
case Type.Sliced:
GenerateSlicedSprite(toFill);
break;
case Type.Tiled:
GenerateTiledSprite(toFill);
break;
case Type.Filled:
GenerateFilledSprite(toFill, m_PreserveAspect);
break;
}
}
这个方法干了什么事情呢,就是根据图片类型,把传进来的VertexHelper填入完整的顶点数据,包括每个顶点的位置、顶点色、UV、法线、切线,以及三角形序列,然后再送回去。我们只要在这一步完成后,把所有的顶点位置翻转一下,就可以实现图片翻转了。
下面我们就创建一个 Image2 类,它继承了Image,并重写了OnPopulateMesh(),下面贴完整代码:
using UnityEngine;
using UnityEngine.UI;
public class Image2 : Image
{
/// <summary>
/// 是否水平翻转
/// </summary>
public bool FlipHorizontal
{
get { return flipHor; }
set
{
flipHor = value;
UpdateGeometry();
}
}
/// <summary>
/// 是否垂直翻转
/// </summary>
public bool FlipVertical
{
get { return flipVer; }
set
{
flipVer = value;
UpdateGeometry();
}
}
[SerializeField]
protected bool flipHor;
[SerializeField]
protected bool flipVer;
protected override void OnPopulateMesh(VertexHelper toFill)
{
base.OnPopulateMesh(toFill);
if (flipHor || flipVer)
{
Vector2 rectCenter = rectTransform.rect.center;
int vertCount = toFill.currentVertCount;
for (int i = 0; i < vertCount; i++)
{
UIVertex uiVertex = new UIVertex();
toFill.PopulateUIVertex(ref uiVertex, i);
Vector3 pos = uiVertex.position;
uiVertex.position = new Vector3(
flipHor ? (pos.x + (rectCenter.x - pos.x) * 2) : pos.x,
flipVer ? (pos.y + (rectCenter.y - pos.y) * 2) : pos.y,
pos.z);
toFill.SetUIVertex(uiVertex, i);
}
}
}
}
代码简单明了,再贴一个Editor类:
using UnityEngine;
using UnityEngine.UI;
using UnityEditor;
using UnityEditor.UI;
[CustomEditor(typeof(Image2))]
public class Image2Editor : ImageEditor
{
public new Image2 target;
private SerializedProperty _spFlipHor;
private SerializedProperty _spFlipVer;
private GUIContent _gcFlipHor;
private GUIContent _gcFlipVer;
protected override void OnEnable()
{
base.OnEnable();
target = base.target as Image2;
_spFlipHor = serializedObject.FindProperty("flipHor");
_spFlipVer = serializedObject.FindProperty("flipVer");
_gcFlipHor = EditorGUIUtility.TrTextContent("水平翻转", null);
_gcFlipVer = EditorGUIUtility.TrTextContent("垂直翻转", null);
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
EditorGUILayout.PropertyField(_spFlipHor, _gcFlipHor);
EditorGUILayout.PropertyField(_spFlipVer, _gcFlipVer);
if (GUI.changed)
{
EditorUtility.SetDirty(target);
}
serializedObject.ApplyModifiedProperties();
}
}
只要创建一个物体,添加Image2组件即可,监视窗口UI如下,多了2个翻转Toggle:
来源:CSDN
作者:九德真君
链接:https://blog.csdn.net/lzdidiv/article/details/104813545