first commit

This commit is contained in:
lethanhsonvsp
2025-11-17 15:16:36 +07:00
commit a40d0921eb
17012 changed files with 2652386 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: eecc124dc0b994047aac97ccf8c8ed0a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,677 @@
#if HDRP_10_7_OR_NEWER
using UnityEngine;
using UnityEditor;
using UnityEditor.Rendering.HighDefinition;
namespace TMPro.EditorUtilities
{
/// <summary>Base class for TextMesh Pro shader GUIs.</summary>
internal abstract class TMP_BaseHDRPLitShaderGUI : LightingShaderGraphGUI
{
/// <summary>Representation of a #pragma shader_feature.</summary>
/// <description>It is assumed that the first feature option is for no keyword (underscores).</description>
protected class ShaderFeature
{
public string undoLabel;
public GUIContent label;
/// <summary>The keyword labels, for display. Include the no-keyword as the first option.</summary>
public GUIContent[] keywordLabels;
/// <summary>The shader keywords. Exclude the no-keyword option.</summary>
public string[] keywords;
int m_State;
public bool Active
{
get { return m_State >= 0; }
}
public int State
{
get { return m_State; }
}
public void ReadState(Material material)
{
for (int i = 0; i < keywords.Length; i++)
{
if (material.IsKeywordEnabled(keywords[i]))
{
m_State = i;
return;
}
}
m_State = -1;
}
public void SetActive(bool active, Material material)
{
m_State = active ? 0 : -1;
SetStateKeywords(material);
}
public void DoPopup(MaterialEditor editor, Material material)
{
EditorGUI.BeginChangeCheck();
int selection = EditorGUILayout.Popup(label, m_State + 1, keywordLabels);
if (EditorGUI.EndChangeCheck())
{
m_State = selection - 1;
editor.RegisterPropertyChangeUndo(undoLabel);
SetStateKeywords(material);
}
}
void SetStateKeywords(Material material)
{
for (int i = 0; i < keywords.Length; i++)
{
if (i == m_State)
{
material.EnableKeyword(keywords[i]);
}
else
{
material.DisableKeyword(keywords[i]);
}
}
}
}
static GUIContent s_TempLabel = new GUIContent();
protected static bool s_DebugExtended;
static int s_UndoRedoCount, s_LastSeenUndoRedoCount;
static float[][] s_TempFloats =
{
null, new float[1], new float[2], new float[3], new float[4]
};
protected static GUIContent[] s_XywhVectorLabels =
{
new GUIContent("X"),
new GUIContent("Y"),
new GUIContent("W", "Width"),
new GUIContent("H", "Height")
};
protected static GUIContent[] s_LbrtVectorLabels =
{
new GUIContent("L", "Left"),
new GUIContent("B", "Bottom"),
new GUIContent("R", "Right"),
new GUIContent("T", "Top")
};
protected static GUIContent[] s_CullingTypeLabels =
{
new GUIContent("Off"),
new GUIContent("Front"),
new GUIContent("Back")
};
static TMP_BaseHDRPLitShaderGUI()
{
// Keep track of how many undo/redo events happened.
Undo.undoRedoPerformed += () => s_UndoRedoCount += 1;
}
bool m_IsNewGUI = true;
float m_DragAndDropMinY;
protected MaterialEditor m_Editor;
protected Material m_Material;
protected MaterialProperty[] m_Properties;
void PrepareGUI()
{
m_IsNewGUI = false;
ShaderUtilities.GetShaderPropertyIDs();
// New GUI just got constructed. This happens in response to a selection,
// but also after undo/redo events.
if (s_LastSeenUndoRedoCount != s_UndoRedoCount)
{
// There's been at least one undo/redo since the last time this GUI got constructed.
// Maybe the undo/redo was for this material? Assume that is was.
TMPro_EventManager.ON_MATERIAL_PROPERTY_CHANGED(true, m_Material as Material);
}
s_LastSeenUndoRedoCount = s_UndoRedoCount;
}
protected override void OnMaterialGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
m_Editor = materialEditor;
m_Material = materialEditor.target as Material;
this.m_Properties = properties;
if (m_IsNewGUI)
{
PrepareGUI();
}
DoDragAndDropBegin();
EditorGUI.BeginChangeCheck();
DoGUI();
if (EditorGUI.EndChangeCheck())
{
TMPro_EventManager.ON_MATERIAL_PROPERTY_CHANGED(true, m_Material);
}
DoDragAndDropEnd();
}
/// <summary>Override this method to create the specific shader GUI.</summary>
protected abstract void DoGUI();
static string[] s_PanelStateLabel = new string[] { "\t- <i>Click to collapse</i> -", "\t- <i>Click to expand</i> -" };
protected bool BeginPanel(string panel, bool expanded)
{
EditorGUI.indentLevel = 0;
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
Rect r = EditorGUI.IndentedRect(GUILayoutUtility.GetRect(20, 18));
r.x += 20;
r.width += 6;
bool enabled = GUI.enabled;
GUI.enabled = true;
expanded = TMP_EditorUtility.EditorToggle(r, expanded, new GUIContent(panel), TMP_UIStyleManager.panelTitle);
r.width -= 30;
EditorGUI.LabelField(r, new GUIContent(expanded ? s_PanelStateLabel[0] : s_PanelStateLabel[1]), TMP_UIStyleManager.rightLabel);
GUI.enabled = enabled;
EditorGUI.indentLevel += 1;
EditorGUI.BeginDisabledGroup(false);
return expanded;
}
protected bool BeginPanel(string panel, ShaderFeature feature, bool expanded, bool readState = true)
{
EditorGUI.indentLevel = 0;
if (readState)
{
feature.ReadState(m_Material);
}
EditorGUI.BeginChangeCheck();
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
GUILayout.BeginHorizontal();
Rect r = EditorGUI.IndentedRect(GUILayoutUtility.GetRect(20, 20, GUILayout.Width(20f)));
bool active = EditorGUI.Toggle(r, feature.Active);
if (EditorGUI.EndChangeCheck())
{
m_Editor.RegisterPropertyChangeUndo(feature.undoLabel);
feature.SetActive(active, m_Material);
}
r = EditorGUI.IndentedRect(GUILayoutUtility.GetRect(20, 18));
r.width += 6;
bool enabled = GUI.enabled;
GUI.enabled = true;
expanded = TMP_EditorUtility.EditorToggle(r, expanded, new GUIContent(panel), TMP_UIStyleManager.panelTitle);
r.width -= 10;
EditorGUI.LabelField(r, new GUIContent(expanded ? s_PanelStateLabel[0] : s_PanelStateLabel[1]), TMP_UIStyleManager.rightLabel);
GUI.enabled = enabled;
GUILayout.EndHorizontal();
EditorGUI.indentLevel += 1;
EditorGUI.BeginDisabledGroup(!active);
return expanded;
}
protected void EndPanel()
{
EditorGUI.EndDisabledGroup();
EditorGUI.indentLevel -= 1;
EditorGUILayout.EndVertical();
}
MaterialProperty BeginProperty(string name)
{
MaterialProperty property = FindProperty(name, m_Properties);
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = property.hasMixedValue;
m_Editor.BeginAnimatedCheck(Rect.zero, property);
return property;
}
bool EndProperty()
{
m_Editor.EndAnimatedCheck();
EditorGUI.showMixedValue = false;
return EditorGUI.EndChangeCheck();
}
protected void DoPopup(string name, string label, GUIContent[] options)
{
MaterialProperty property = BeginProperty(name);
s_TempLabel.text = label;
int index = EditorGUILayout.Popup(s_TempLabel, (int)property.floatValue, options);
if (EndProperty())
{
property.floatValue = index;
}
}
protected void DoCubeMap(string name, string label)
{
DoTexture(name, label, typeof(Cubemap));
}
protected void DoTexture2D(string name, string label, bool withTilingOffset = false, string[] speedNames = null)
{
DoTexture(name, label, typeof(Texture2D), withTilingOffset, speedNames);
}
void DoTexture(string name, string label, System.Type type, bool withTilingOffset = false, string[] speedNames = null)
{
float objFieldSize = 60f;
bool smallLayout = EditorGUIUtility.currentViewWidth <= 440f && (withTilingOffset || speedNames != null);
float controlHeight = smallLayout ? objFieldSize * 2 : objFieldSize;
MaterialProperty property = FindProperty(name, m_Properties);
m_Editor.BeginAnimatedCheck(Rect.zero, property);
Rect rect = EditorGUILayout.GetControlRect(true, controlHeight);
float totalWidth = rect.width;
rect.width = EditorGUIUtility.labelWidth + objFieldSize;
rect.height = objFieldSize;
s_TempLabel.text = label;
EditorGUI.BeginChangeCheck();
Object tex = EditorGUI.ObjectField(rect, s_TempLabel, property.textureValue, type, false);
if (EditorGUI.EndChangeCheck())
{
property.textureValue = tex as Texture;
}
float additionalHeight = controlHeight - objFieldSize;
float xOffset = smallLayout ? rect.width - objFieldSize : rect.width;
rect.y += additionalHeight;
rect.x += xOffset;
rect.width = totalWidth - xOffset;
rect.height = EditorGUIUtility.singleLineHeight;
if (withTilingOffset)
{
DoTilingOffset(rect, property);
rect.y += (rect.height + 2f) * 2f;
}
m_Editor.EndAnimatedCheck();
if (speedNames != null)
{
DoUVSpeed(rect, speedNames);
}
}
void DoTilingOffset(Rect rect, MaterialProperty property)
{
float labelWidth = EditorGUIUtility.labelWidth;
int indentLevel = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
EditorGUIUtility.labelWidth = Mathf.Min(40f, rect.width * 0.40f);
Vector4 vector = property.textureScaleAndOffset;
bool changed = false;
float[] values = s_TempFloats[2];
s_TempLabel.text = "Tiling";
Rect vectorRect = EditorGUI.PrefixLabel(rect, s_TempLabel);
values[0] = vector.x;
values[1] = vector.y;
EditorGUI.BeginChangeCheck();
EditorGUI.MultiFloatField(vectorRect, s_XywhVectorLabels, values);
if (EditorGUI.EndChangeCheck())
{
vector.x = values[0];
vector.y = values[1];
changed = true;
}
rect.y += rect.height + 2f;
s_TempLabel.text = "Offset";
vectorRect = EditorGUI.PrefixLabel(rect, s_TempLabel);
values[0] = vector.z;
values[1] = vector.w;
EditorGUI.BeginChangeCheck();
EditorGUI.MultiFloatField(vectorRect, s_XywhVectorLabels, values);
if (EditorGUI.EndChangeCheck())
{
vector.z = values[0];
vector.w = values[1];
changed = true;
}
if (changed)
{
property.textureScaleAndOffset = vector;
}
EditorGUIUtility.labelWidth = labelWidth;
EditorGUI.indentLevel = indentLevel;
}
void DoUVSpeed(Rect rect, string[] names)
{
float labelWidth = EditorGUIUtility.labelWidth;
int indentLevel = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
EditorGUIUtility.labelWidth = Mathf.Min(40f, rect.width * 0.40f);
s_TempLabel.text = "Speed";
rect = EditorGUI.PrefixLabel(rect, s_TempLabel);
EditorGUIUtility.labelWidth = 10f;
rect.width = rect.width * 0.5f - 2f;
if (names.Length == 1)
{
DoFloat2(rect, names[0]);
}
else
{
DoFloat(rect, names[0], "X");
rect.x += rect.width + 4f;
DoFloat(rect, names[1], "Y");
}
EditorGUIUtility.labelWidth = labelWidth;
EditorGUI.indentLevel = indentLevel;
}
protected void DoToggle(string name, string label)
{
MaterialProperty property = BeginProperty(name);
s_TempLabel.text = label;
bool value = EditorGUILayout.Toggle(s_TempLabel, property.floatValue == 1f);
if (EndProperty())
{
property.floatValue = value ? 1f : 0f;
}
}
protected void DoFloat(string name, string label)
{
MaterialProperty property = BeginProperty(name);
Rect rect = EditorGUILayout.GetControlRect();
rect.width = EditorGUIUtility.labelWidth + 55f;
s_TempLabel.text = label;
float value = EditorGUI.FloatField(rect, s_TempLabel, property.floatValue);
if (EndProperty())
{
property.floatValue = value;
}
}
protected void DoColor(string name, string label)
{
MaterialProperty property = BeginProperty(name);
s_TempLabel.text = label;
Color value = EditorGUI.ColorField(EditorGUILayout.GetControlRect(), s_TempLabel, property.colorValue, false, true, true);
if (EndProperty())
{
property.colorValue = value;
}
}
void DoFloat(Rect rect, string name, string label)
{
MaterialProperty property = BeginProperty(name);
s_TempLabel.text = label;
float value = EditorGUI.FloatField(rect, s_TempLabel, property.floatValue);
if (EndProperty())
{
property.floatValue = value;
}
}
void DoFloat2(Rect rect, string name)
{
MaterialProperty property = BeginProperty(name);
float x = EditorGUI.FloatField(rect, "X", property.vectorValue.x);
rect.x += rect.width + 4f;
float y = EditorGUI.FloatField(rect, "Y", property.vectorValue.y);
if (EndProperty())
{
property.vectorValue = new Vector2(x, y);
}
}
protected void DoOffset(string name, string label)
{
MaterialProperty property = BeginProperty(name);
s_TempLabel.text = label;
Vector2 value = EditorGUI.Vector2Field(EditorGUILayout.GetControlRect(), s_TempLabel, property.vectorValue);
if (EndProperty())
{
property.vectorValue = value;
}
}
protected void DoSlider(string name, string label)
{
MaterialProperty property = BeginProperty(name);
Vector2 range = property.rangeLimits;
s_TempLabel.text = label;
float value = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, property.floatValue, range.x, range.y);
if (EndProperty())
{
property.floatValue = value;
}
}
protected void DoSlider(string name, Vector2 range, string label)
{
MaterialProperty property = BeginProperty(name);
s_TempLabel.text = label;
float value = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, property.floatValue, range.x, range.y);
if (EndProperty())
{
property.floatValue = value;
}
}
protected void DoSlider(string propertyName, string propertyField, string label)
{
MaterialProperty property = BeginProperty(propertyName);
Vector2 range = property.rangeLimits;
s_TempLabel.text = label;
Vector4 value = property.vectorValue;
switch (propertyField)
{
case "X":
value.x = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.x, range.x, range.y);
break;
case "Y":
value.y = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.y, range.x, range.y);
break;
case "Z":
value.z = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.z, range.x, range.y);
break;
case "W":
value.w = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.w, range.x, range.y);
break;
}
if (EndProperty())
{
property.vectorValue = value;
}
}
protected void DoSlider(string propertyName, string propertyField, Vector2 range, string label)
{
MaterialProperty property = BeginProperty(propertyName);
s_TempLabel.text = label;
Vector4 value = property.vectorValue;
switch (propertyField)
{
case "X":
value.x = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.x, range.x, range.y);
break;
case "Y":
value.y = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.y, range.x, range.y);
break;
case "Z":
value.z = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.z, range.x, range.y);
break;
case "W":
value.w = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.w, range.x, range.y);
break;
}
if (EndProperty())
{
property.vectorValue = value;
}
}
protected void DoVector2(string name, string label)
{
MaterialProperty property = BeginProperty(name);
s_TempLabel.text = label;
Vector4 value = EditorGUILayout.Vector3Field(s_TempLabel, property.vectorValue);
if (EndProperty())
{
property.vectorValue = value;
}
}
protected void DoVector3(string name, string label)
{
MaterialProperty property = BeginProperty(name);
s_TempLabel.text = label;
Vector4 value = EditorGUILayout.Vector3Field(s_TempLabel, property.vectorValue);
if (EndProperty())
{
property.vectorValue = value;
}
}
protected void DoVector(string name, string label, GUIContent[] subLabels)
{
MaterialProperty property = BeginProperty(name);
Rect rect = EditorGUILayout.GetControlRect();
s_TempLabel.text = label;
rect = EditorGUI.PrefixLabel(rect, s_TempLabel);
Vector4 vector = property.vectorValue;
float[] values = s_TempFloats[subLabels.Length];
for (int i = 0; i < subLabels.Length; i++)
{
values[i] = vector[i];
}
EditorGUI.MultiFloatField(rect, subLabels, values);
if (EndProperty())
{
for (int i = 0; i < subLabels.Length; i++)
{
vector[i] = values[i];
}
property.vectorValue = vector;
}
}
void DoDragAndDropBegin()
{
m_DragAndDropMinY = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true)).y;
}
void DoDragAndDropEnd()
{
Rect rect = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true));
Event evt = Event.current;
if (evt.type == EventType.DragUpdated)
{
DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
evt.Use();
}
else if (
evt.type == EventType.DragPerform &&
Rect.MinMaxRect(rect.xMin, m_DragAndDropMinY, rect.xMax, rect.yMax).Contains(evt.mousePosition)
)
{
DragAndDrop.AcceptDrag();
evt.Use();
Material droppedMaterial = DragAndDrop.objectReferences[0] as Material;
if (droppedMaterial && droppedMaterial != m_Material)
{
PerformDrop(droppedMaterial);
}
}
}
void PerformDrop(Material droppedMaterial)
{
Texture droppedTex = droppedMaterial.GetTexture(ShaderUtilities.ID_MainTex);
if (!droppedTex)
{
return;
}
Texture currentTex = m_Material.GetTexture(ShaderUtilities.ID_MainTex);
TMP_FontAsset requiredFontAsset = null;
if (droppedTex != currentTex)
{
requiredFontAsset = TMP_EditorUtility.FindMatchingFontAsset(droppedMaterial);
if (!requiredFontAsset)
{
return;
}
}
foreach (GameObject o in Selection.gameObjects)
{
if (requiredFontAsset)
{
TMP_Text textComponent = o.GetComponent<TMP_Text>();
if (textComponent)
{
Undo.RecordObject(textComponent, "Font Asset Change");
textComponent.font = requiredFontAsset;
}
}
TMPro_EventManager.ON_DRAG_AND_DROP_MATERIAL_CHANGED(o, m_Material, droppedMaterial);
EditorUtility.SetDirty(o);
}
}
}
}
#endif

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: e3795795b029fde4395e6953ce72b5a6
timeCreated: 1469844810
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,681 @@
#if HDRP_10_7_OR_NEWER
using UnityEngine;
using UnityEditor;
using UnityEditor.Rendering.HighDefinition;
namespace TMPro.EditorUtilities
{
/// <summary>Base class for TextMesh Pro shader GUIs.</summary>
#if HDRP_11_OR_NEWER
internal abstract class TMP_BaseHDRPUnlitShaderGUI : UnlitShaderGraphGUI
#else
internal abstract class TMP_BaseHDRPUnlitShaderGUI : HDUnlitGUI
#endif
{
/// <summary>Representation of a #pragma shader_feature.</summary>
/// <description>It is assumed that the first feature option is for no keyword (underscores).</description>
protected class ShaderFeature
{
public string undoLabel;
public GUIContent label;
/// <summary>The keyword labels, for display. Include the no-keyword as the first option.</summary>
public GUIContent[] keywordLabels;
/// <summary>The shader keywords. Exclude the no-keyword option.</summary>
public string[] keywords;
int m_State;
public bool Active
{
get { return m_State >= 0; }
}
public int State
{
get { return m_State; }
}
public void ReadState(Material material)
{
for (int i = 0; i < keywords.Length; i++)
{
if (material.IsKeywordEnabled(keywords[i]))
{
m_State = i;
return;
}
}
m_State = -1;
}
public void SetActive(bool active, Material material)
{
m_State = active ? 0 : -1;
SetStateKeywords(material);
}
public void DoPopup(MaterialEditor editor, Material material)
{
EditorGUI.BeginChangeCheck();
int selection = EditorGUILayout.Popup(label, m_State + 1, keywordLabels);
if (EditorGUI.EndChangeCheck())
{
m_State = selection - 1;
editor.RegisterPropertyChangeUndo(undoLabel);
SetStateKeywords(material);
}
}
void SetStateKeywords(Material material)
{
for (int i = 0; i < keywords.Length; i++)
{
if (i == m_State)
{
material.EnableKeyword(keywords[i]);
}
else
{
material.DisableKeyword(keywords[i]);
}
}
}
}
static GUIContent s_TempLabel = new GUIContent();
protected static bool s_DebugExtended;
static int s_UndoRedoCount, s_LastSeenUndoRedoCount;
static float[][] s_TempFloats =
{
null, new float[1], new float[2], new float[3], new float[4]
};
protected static GUIContent[] s_XywhVectorLabels =
{
new GUIContent("X"),
new GUIContent("Y"),
new GUIContent("W", "Width"),
new GUIContent("H", "Height")
};
protected static GUIContent[] s_LbrtVectorLabels =
{
new GUIContent("L", "Left"),
new GUIContent("B", "Bottom"),
new GUIContent("R", "Right"),
new GUIContent("T", "Top")
};
protected static GUIContent[] s_CullingTypeLabels =
{
new GUIContent("Off"),
new GUIContent("Front"),
new GUIContent("Back")
};
static TMP_BaseHDRPUnlitShaderGUI()
{
// Keep track of how many undo/redo events happened.
Undo.undoRedoPerformed += () => s_UndoRedoCount += 1;
}
bool m_IsNewGUI = true;
float m_DragAndDropMinY;
protected MaterialEditor m_Editor;
protected Material m_Material;
protected MaterialProperty[] m_Properties;
void PrepareGUI()
{
m_IsNewGUI = false;
ShaderUtilities.GetShaderPropertyIDs();
// New GUI just got constructed. This happens in response to a selection,
// but also after undo/redo events.
if (s_LastSeenUndoRedoCount != s_UndoRedoCount)
{
// There's been at least one undo/redo since the last time this GUI got constructed.
// Maybe the undo/redo was for this material? Assume that is was.
TMPro_EventManager.ON_MATERIAL_PROPERTY_CHANGED(true, m_Material as Material);
}
s_LastSeenUndoRedoCount = s_UndoRedoCount;
}
protected override void OnMaterialGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
m_Editor = materialEditor;
m_Material = materialEditor.target as Material;
this.m_Properties = properties;
if (m_IsNewGUI)
{
PrepareGUI();
}
DoDragAndDropBegin();
EditorGUI.BeginChangeCheck();
DoGUI();
if (EditorGUI.EndChangeCheck())
{
TMPro_EventManager.ON_MATERIAL_PROPERTY_CHANGED(true, m_Material);
}
DoDragAndDropEnd();
}
/// <summary>Override this method to create the specific shader GUI.</summary>
protected abstract void DoGUI();
static string[] s_PanelStateLabel = new string[] { "\t- <i>Click to collapse</i> -", "\t- <i>Click to expand</i> -" };
protected bool BeginPanel(string panel, bool expanded)
{
EditorGUI.indentLevel = 0;
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
Rect r = EditorGUI.IndentedRect(GUILayoutUtility.GetRect(20, 18));
r.x += 20;
r.width += 6;
bool enabled = GUI.enabled;
GUI.enabled = true;
expanded = TMP_EditorUtility.EditorToggle(r, expanded, new GUIContent(panel), TMP_UIStyleManager.panelTitle);
r.width -= 30;
EditorGUI.LabelField(r, new GUIContent(expanded ? s_PanelStateLabel[0] : s_PanelStateLabel[1]), TMP_UIStyleManager.rightLabel);
GUI.enabled = enabled;
EditorGUI.indentLevel += 1;
EditorGUI.BeginDisabledGroup(false);
return expanded;
}
protected bool BeginPanel(string panel, ShaderFeature feature, bool expanded, bool readState = true)
{
EditorGUI.indentLevel = 0;
if (readState)
{
feature.ReadState(m_Material);
}
EditorGUI.BeginChangeCheck();
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
GUILayout.BeginHorizontal();
Rect r = EditorGUI.IndentedRect(GUILayoutUtility.GetRect(20, 20, GUILayout.Width(20f)));
bool active = EditorGUI.Toggle(r, feature.Active);
if (EditorGUI.EndChangeCheck())
{
m_Editor.RegisterPropertyChangeUndo(feature.undoLabel);
feature.SetActive(active, m_Material);
}
r = EditorGUI.IndentedRect(GUILayoutUtility.GetRect(20, 18));
r.width += 6;
bool enabled = GUI.enabled;
GUI.enabled = true;
expanded = TMP_EditorUtility.EditorToggle(r, expanded, new GUIContent(panel), TMP_UIStyleManager.panelTitle);
r.width -= 10;
EditorGUI.LabelField(r, new GUIContent(expanded ? s_PanelStateLabel[0] : s_PanelStateLabel[1]), TMP_UIStyleManager.rightLabel);
GUI.enabled = enabled;
GUILayout.EndHorizontal();
EditorGUI.indentLevel += 1;
EditorGUI.BeginDisabledGroup(!active);
return expanded;
}
protected void EndPanel()
{
EditorGUI.EndDisabledGroup();
EditorGUI.indentLevel -= 1;
EditorGUILayout.EndVertical();
}
MaterialProperty BeginProperty(string name)
{
MaterialProperty property = FindProperty(name, m_Properties);
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = property.hasMixedValue;
m_Editor.BeginAnimatedCheck(Rect.zero, property);
return property;
}
bool EndProperty()
{
m_Editor.EndAnimatedCheck();
EditorGUI.showMixedValue = false;
return EditorGUI.EndChangeCheck();
}
protected void DoPopup(string name, string label, GUIContent[] options)
{
MaterialProperty property = BeginProperty(name);
s_TempLabel.text = label;
int index = EditorGUILayout.Popup(s_TempLabel, (int)property.floatValue, options);
if (EndProperty())
{
property.floatValue = index;
}
}
protected void DoCubeMap(string name, string label)
{
DoTexture(name, label, typeof(Cubemap));
}
protected void DoTexture2D(string name, string label, bool withTilingOffset = false, string[] speedNames = null)
{
DoTexture(name, label, typeof(Texture2D), withTilingOffset, speedNames);
}
void DoTexture(string name, string label, System.Type type, bool withTilingOffset = false, string[] speedNames = null)
{
float objFieldSize = 60f;
bool smallLayout = EditorGUIUtility.currentViewWidth <= 440f && (withTilingOffset || speedNames != null);
float controlHeight = smallLayout ? objFieldSize * 2 : objFieldSize;
MaterialProperty property = FindProperty(name, m_Properties);
m_Editor.BeginAnimatedCheck(Rect.zero, property);
Rect rect = EditorGUILayout.GetControlRect(true, controlHeight);
float totalWidth = rect.width;
rect.width = EditorGUIUtility.labelWidth + objFieldSize;
rect.height = objFieldSize;
s_TempLabel.text = label;
EditorGUI.BeginChangeCheck();
Object tex = EditorGUI.ObjectField(rect, s_TempLabel, property.textureValue, type, false);
if (EditorGUI.EndChangeCheck())
{
property.textureValue = tex as Texture;
}
float additionalHeight = controlHeight - objFieldSize;
float xOffset = smallLayout ? rect.width - objFieldSize : rect.width;
rect.y += additionalHeight;
rect.x += xOffset;
rect.width = totalWidth - xOffset;
rect.height = EditorGUIUtility.singleLineHeight;
if (withTilingOffset)
{
DoTilingOffset(rect, property);
rect.y += (rect.height + 2f) * 2f;
}
m_Editor.EndAnimatedCheck();
if (speedNames != null)
{
DoUVSpeed(rect, speedNames);
}
}
void DoTilingOffset(Rect rect, MaterialProperty property)
{
float labelWidth = EditorGUIUtility.labelWidth;
int indentLevel = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
EditorGUIUtility.labelWidth = Mathf.Min(40f, rect.width * 0.40f);
Vector4 vector = property.textureScaleAndOffset;
bool changed = false;
float[] values = s_TempFloats[2];
s_TempLabel.text = "Tiling";
Rect vectorRect = EditorGUI.PrefixLabel(rect, s_TempLabel);
values[0] = vector.x;
values[1] = vector.y;
EditorGUI.BeginChangeCheck();
EditorGUI.MultiFloatField(vectorRect, s_XywhVectorLabels, values);
if (EditorGUI.EndChangeCheck())
{
vector.x = values[0];
vector.y = values[1];
changed = true;
}
rect.y += rect.height + 2f;
s_TempLabel.text = "Offset";
vectorRect = EditorGUI.PrefixLabel(rect, s_TempLabel);
values[0] = vector.z;
values[1] = vector.w;
EditorGUI.BeginChangeCheck();
EditorGUI.MultiFloatField(vectorRect, s_XywhVectorLabels, values);
if (EditorGUI.EndChangeCheck())
{
vector.z = values[0];
vector.w = values[1];
changed = true;
}
if (changed)
{
property.textureScaleAndOffset = vector;
}
EditorGUIUtility.labelWidth = labelWidth;
EditorGUI.indentLevel = indentLevel;
}
void DoUVSpeed(Rect rect, string[] names)
{
float labelWidth = EditorGUIUtility.labelWidth;
int indentLevel = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
EditorGUIUtility.labelWidth = Mathf.Min(40f, rect.width * 0.40f);
s_TempLabel.text = "Speed";
rect = EditorGUI.PrefixLabel(rect, s_TempLabel);
EditorGUIUtility.labelWidth = 10f;
rect.width = rect.width * 0.5f - 2f;
if (names.Length == 1)
{
DoFloat2(rect, names[0]);
}
else
{
DoFloat(rect, names[0], "X");
rect.x += rect.width + 4f;
DoFloat(rect, names[1], "Y");
}
EditorGUIUtility.labelWidth = labelWidth;
EditorGUI.indentLevel = indentLevel;
}
protected void DoToggle(string name, string label)
{
MaterialProperty property = BeginProperty(name);
s_TempLabel.text = label;
bool value = EditorGUILayout.Toggle(s_TempLabel, property.floatValue == 1f);
if (EndProperty())
{
property.floatValue = value ? 1f : 0f;
}
}
protected void DoFloat(string name, string label)
{
MaterialProperty property = BeginProperty(name);
Rect rect = EditorGUILayout.GetControlRect();
rect.width = EditorGUIUtility.labelWidth + 55f;
s_TempLabel.text = label;
float value = EditorGUI.FloatField(rect, s_TempLabel, property.floatValue);
if (EndProperty())
{
property.floatValue = value;
}
}
protected void DoColor(string name, string label)
{
MaterialProperty property = BeginProperty(name);
s_TempLabel.text = label;
Color value = EditorGUI.ColorField(EditorGUILayout.GetControlRect(), s_TempLabel, property.colorValue, false, true, true);
if (EndProperty())
{
property.colorValue = value;
}
}
void DoFloat(Rect rect, string name, string label)
{
MaterialProperty property = BeginProperty(name);
s_TempLabel.text = label;
float value = EditorGUI.FloatField(rect, s_TempLabel, property.floatValue);
if (EndProperty())
{
property.floatValue = value;
}
}
void DoFloat2(Rect rect, string name)
{
MaterialProperty property = BeginProperty(name);
float x = EditorGUI.FloatField(rect, "X", property.vectorValue.x);
rect.x += rect.width + 4f;
float y = EditorGUI.FloatField(rect, "Y", property.vectorValue.y);
if (EndProperty())
{
property.vectorValue = new Vector2(x, y);
}
}
protected void DoOffset(string name, string label)
{
MaterialProperty property = BeginProperty(name);
s_TempLabel.text = label;
Vector2 value = EditorGUI.Vector2Field(EditorGUILayout.GetControlRect(), s_TempLabel, property.vectorValue);
if (EndProperty())
{
property.vectorValue = value;
}
}
protected void DoSlider(string name, string label)
{
MaterialProperty property = BeginProperty(name);
Vector2 range = property.rangeLimits;
s_TempLabel.text = label;
float value = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, property.floatValue, range.x, range.y);
if (EndProperty())
{
property.floatValue = value;
}
}
protected void DoSlider(string name, Vector2 range, string label)
{
MaterialProperty property = BeginProperty(name);
s_TempLabel.text = label;
float value = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, property.floatValue, range.x, range.y);
if (EndProperty())
{
property.floatValue = value;
}
}
protected void DoSlider(string propertyName, string propertyField, string label)
{
MaterialProperty property = BeginProperty(propertyName);
Vector2 range = property.rangeLimits;
s_TempLabel.text = label;
Vector4 value = property.vectorValue;
switch (propertyField)
{
case "X":
value.x = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.x, range.x, range.y);
break;
case "Y":
value.y = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.y, range.x, range.y);
break;
case "Z":
value.z = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.z, range.x, range.y);
break;
case "W":
value.w = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.w, range.x, range.y);
break;
}
if (EndProperty())
{
property.vectorValue = value;
}
}
protected void DoSlider(string propertyName, string propertyField, Vector2 range, string label)
{
MaterialProperty property = BeginProperty(propertyName);
s_TempLabel.text = label;
Vector4 value = property.vectorValue;
switch (propertyField)
{
case "X":
value.x = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.x, range.x, range.y);
break;
case "Y":
value.y = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.y, range.x, range.y);
break;
case "Z":
value.z = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.z, range.x, range.y);
break;
case "W":
value.w = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.w, range.x, range.y);
break;
}
if (EndProperty())
{
property.vectorValue = value;
}
}
protected void DoVector2(string name, string label)
{
MaterialProperty property = BeginProperty(name);
s_TempLabel.text = label;
Vector4 value = EditorGUILayout.Vector3Field(s_TempLabel, property.vectorValue);
if (EndProperty())
{
property.vectorValue = value;
}
}
protected void DoVector3(string name, string label)
{
MaterialProperty property = BeginProperty(name);
s_TempLabel.text = label;
Vector4 value = EditorGUILayout.Vector3Field(s_TempLabel, property.vectorValue);
if (EndProperty())
{
property.vectorValue = value;
}
}
protected void DoVector(string name, string label, GUIContent[] subLabels)
{
MaterialProperty property = BeginProperty(name);
Rect rect = EditorGUILayout.GetControlRect();
s_TempLabel.text = label;
rect = EditorGUI.PrefixLabel(rect, s_TempLabel);
Vector4 vector = property.vectorValue;
float[] values = s_TempFloats[subLabels.Length];
for (int i = 0; i < subLabels.Length; i++)
{
values[i] = vector[i];
}
EditorGUI.MultiFloatField(rect, subLabels, values);
if (EndProperty())
{
for (int i = 0; i < subLabels.Length; i++)
{
vector[i] = values[i];
}
property.vectorValue = vector;
}
}
void DoDragAndDropBegin()
{
m_DragAndDropMinY = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true)).y;
}
void DoDragAndDropEnd()
{
Rect rect = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true));
Event evt = Event.current;
if (evt.type == EventType.DragUpdated)
{
DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
evt.Use();
}
else if (
evt.type == EventType.DragPerform &&
Rect.MinMaxRect(rect.xMin, m_DragAndDropMinY, rect.xMax, rect.yMax).Contains(evt.mousePosition)
)
{
DragAndDrop.AcceptDrag();
evt.Use();
Material droppedMaterial = DragAndDrop.objectReferences[0] as Material;
if (droppedMaterial && droppedMaterial != m_Material)
{
PerformDrop(droppedMaterial);
}
}
}
void PerformDrop(Material droppedMaterial)
{
Texture droppedTex = droppedMaterial.GetTexture(ShaderUtilities.ID_MainTex);
if (!droppedTex)
{
return;
}
Texture currentTex = m_Material.GetTexture(ShaderUtilities.ID_MainTex);
TMP_FontAsset requiredFontAsset = null;
if (droppedTex != currentTex)
{
requiredFontAsset = TMP_EditorUtility.FindMatchingFontAsset(droppedMaterial);
if (!requiredFontAsset)
{
return;
}
}
foreach (GameObject o in Selection.gameObjects)
{
if (requiredFontAsset)
{
TMP_Text textComponent = o.GetComponent<TMP_Text>();
if (textComponent)
{
Undo.RecordObject(textComponent, "Font Asset Change");
textComponent.font = requiredFontAsset;
}
}
TMPro_EventManager.ON_DRAG_AND_DROP_MATERIAL_CHANGED(o, m_Material, droppedMaterial);
EditorUtility.SetDirty(o);
}
}
}
}
#endif

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 645409e9544820042937871953f20509
timeCreated: 1469844810
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,631 @@
#if HDRP_10_7_OR_NEWER
using UnityEngine;
using UnityEditor;
using UnityEditor.Rendering.HighDefinition;
namespace TMPro.EditorUtilities
{
internal class TMP_SDF_HDRPLitShaderGUI : TMP_BaseHDRPLitShaderGUI
{
static ShaderFeature s_OutlineFeature, s_UnderlayFeature, s_BevelFeature, s_GlowFeature, s_MaskFeature;
static bool s_Face = true, s_Outline = true, s_Outline2 = true, s_Outline3 = true, s_Underlay = true, s_Lighting = true, s_Glow, s_Bevel, s_Light, s_Bump, s_Env;
static string[]
s_FaceUVSpeedName = { "_FaceUVSpeed" },
s_FaceUvSpeedNames = { "_FaceUVSpeedX", "_FaceUVSpeedY" },
s_OutlineUvSpeedNames = { "_OutlineUVSpeedX", "_OutlineUVSpeedY" },
s_OutlineUvSpeedName = { "_OutlineUVSpeed" };
/// <summary>
///
/// </summary>
static TMP_SDF_HDRPLitShaderGUI()
{
s_OutlineFeature = new ShaderFeature()
{
undoLabel = "Outline",
keywords = new[] { "OUTLINE_ON" }
};
s_UnderlayFeature = new ShaderFeature()
{
undoLabel = "Underlay",
keywords = new[] { "UNDERLAY_ON", "UNDERLAY_INNER" },
label = new GUIContent("Underlay Type"),
keywordLabels = new[]
{
new GUIContent("None"), new GUIContent("Normal"), new GUIContent("Inner")
}
};
s_BevelFeature = new ShaderFeature()
{
undoLabel = "Bevel",
keywords = new[] { "BEVEL_ON" }
};
s_GlowFeature = new ShaderFeature()
{
undoLabel = "Glow",
keywords = new[] { "GLOW_ON" }
};
s_MaskFeature = new ShaderFeature()
{
undoLabel = "Mask",
keywords = new[] { "MASK_HARD", "MASK_SOFT" },
label = new GUIContent("Mask"),
keywordLabels = new[]
{
new GUIContent("Mask Off"), new GUIContent("Mask Hard"), new GUIContent("Mask Soft")
}
};
}
/// <summary>
///
/// </summary>
public TMP_SDF_HDRPLitShaderGUI()
{
// Remove the ShaderGraphUIBlock to avoid having duplicated properties in the UI.
uiBlocks.RemoveAll(b => b is ShaderGraphUIBlock);
}
protected override void DoGUI()
{
s_Face = BeginPanel("Face", s_Face);
if (s_Face)
{
DoFacePanel();
}
EndPanel();
// Outline panels
DoOutlinePanels();
// Underlay panel
s_Underlay = BeginPanel("Underlay", s_Underlay);
if (s_Underlay)
{
DoUnderlayPanel();
}
EndPanel();
// Lighting panel
DrawLightingPanel();
/*
if (m_Material.HasProperty(ShaderUtilities.ID_GlowColor))
{
s_Glow = BeginPanel("Glow", s_GlowFeature, s_Glow);
if (s_Glow)
{
DoGlowPanel();
}
EndPanel();
}
*/
s_DebugExtended = BeginPanel("Debug Settings", s_DebugExtended);
if (s_DebugExtended)
{
DoDebugPanelSRP();
}
EndPanel();
EditorGUILayout.Space();
EditorGUILayout.Space();
// Draw HDRP panels
uiBlocks.OnGUI(m_Editor, m_Properties);
#if HDRP_12_OR_NEWER
ValidateMaterial(m_Material);
#else
SetupMaterialKeywordsAndPass(m_Material);
#endif
}
void DoFacePanel()
{
EditorGUI.indentLevel += 1;
DoColor("_FaceColor", "Color");
if (m_Material.HasProperty(ShaderUtilities.ID_FaceTex))
{
if (m_Material.HasProperty("_FaceUVSpeedX"))
{
DoTexture2D("_FaceTex", "Texture", true, s_FaceUvSpeedNames);
}
else if (m_Material.HasProperty("_FaceUVSpeed"))
{
DoTexture2D("_FaceTex", "Texture", true, s_FaceUVSpeedName);
}
else
{
DoTexture2D("_FaceTex", "Texture", true);
}
}
if (m_Material.HasProperty("_Softness"))
{
DoSlider("_Softness", "X", new Vector2(0, 1), "Softness");
}
if (m_Material.HasProperty("_OutlineSoftness"))
{
DoSlider("_OutlineSoftness", "Softness");
}
if (m_Material.HasProperty(ShaderUtilities.ID_FaceDilate))
{
DoSlider("_FaceDilate", "Dilate");
if (m_Material.HasProperty(ShaderUtilities.ID_Shininess))
{
DoSlider("_FaceShininess", "Gloss");
}
}
if (m_Material.HasProperty(ShaderUtilities.ID_IsoPerimeter))
{
DoSlider("_IsoPerimeter", "X", new Vector2(-1, 1), "Dilate");
}
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoOutlinePanels()
{
s_Outline = BeginPanel("Outline 1", s_Outline);
if (s_Outline)
DoOutlinePanelWithTexture(1, "Y", "Color");
EndPanel();
s_Outline2 = BeginPanel("Outline 2", s_Outline2);
if (s_Outline2)
DoOutlinePanel(2, "Z", "Color");
EndPanel();
s_Outline3 = BeginPanel("Outline 3", s_Outline3);
if (s_Outline3)
DoOutlinePanel(3, "W", "Color");
EndPanel();
}
void DoOutlinePanel(int outlineID, string propertyField, string label)
{
EditorGUI.indentLevel += 1;
DoColor("_OutlineColor" + outlineID, label);
if (outlineID != 3)
DoOffset("_OutlineOffset" + outlineID, "Offset");
else
{
if (m_Material.GetFloat(ShaderUtilities.ID_OutlineMode) == 0)
DoOffset("_OutlineOffset" + outlineID, "Offset");
}
DoSlider("_Softness", propertyField, new Vector2(0, 1), "Softness");
DoSlider("_IsoPerimeter", propertyField, new Vector2(-1, 1), "Dilate");
if (outlineID == 3)
{
DoToggle("_OutlineMode", "Outline Mode");
}
if (m_Material.HasProperty("_OutlineShininess"))
{
//DoSlider("_OutlineShininess", "Gloss");
}
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoOutlinePanelWithTexture(int outlineID, string propertyField, string label)
{
EditorGUI.indentLevel += 1;
DoColor("_OutlineColor" + outlineID, label);
if (m_Material.HasProperty(ShaderUtilities.ID_OutlineTex))
{
if (m_Material.HasProperty("_OutlineUVSpeedX"))
{
DoTexture2D("_OutlineTex", "Texture", true, s_OutlineUvSpeedNames);
}
else if (m_Material.HasProperty("_OutlineUVSpeed"))
{
DoTexture2D("_OutlineTex", "Texture", true, s_OutlineUvSpeedName);
}
else
{
DoTexture2D("_OutlineTex", "Texture", true);
}
}
DoOffset("_OutlineOffset" + outlineID, "Offset");
DoSlider("_Softness", propertyField, new Vector2(0, 1), "Softness");
DoSlider("_IsoPerimeter", propertyField, new Vector2(-1, 1), "Dilate");
if (m_Material.HasProperty("_OutlineShininess"))
{
//DoSlider("_OutlineShininess", "Gloss");
}
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoUnderlayPanel()
{
EditorGUI.indentLevel += 1;
if (m_Material.HasProperty(ShaderUtilities.ID_IsoPerimeter))
{
DoColor("_UnderlayColor", "Color");
DoSlider("_UnderlayOffset", "X", new Vector2(-1, 1), "Offset X");
DoSlider("_UnderlayOffset", "Y", new Vector2(-1, 1), "Offset Y");
DoSlider("_UnderlayDilate", new Vector2(-1, 1), "Dilate");
DoSlider("_UnderlaySoftness", new Vector2(0, 1), "Softness");
}
else
{
s_UnderlayFeature.DoPopup(m_Editor, m_Material);
DoColor("_UnderlayColor", "Color");
DoSlider("_UnderlayOffsetX", "Offset X");
DoSlider("_UnderlayOffsetY", "Offset Y");
DoSlider("_UnderlayDilate", "Dilate");
DoSlider("_UnderlaySoftness", "Softness");
}
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
static GUIContent[] s_BevelTypeLabels =
{
new GUIContent("Outer Bevel"),
new GUIContent("Inner Bevel")
};
void DrawLightingPanel()
{
s_Lighting = BeginPanel("Lighting", s_Lighting);
if (s_Lighting)
{
s_Bevel = BeginPanel("Bevel", s_Bevel);
if (s_Bevel)
{
DoBevelPanel();
}
EndPanel();
s_Light = BeginPanel("Local Lighting", s_Light);
if (s_Light)
{
DoLocalLightingPanel();
}
EndPanel();
/*
s_Bump = BeginPanel("Bump Map", s_Bump);
if (s_Bump)
{
DoBumpMapPanel();
}
EndPanel();
s_Env = BeginPanel("Environment Map", s_Env);
if (s_Env)
{
DoEnvMapPanel();
}
EndPanel();
*/
}
EndPanel();
}
void DoBevelPanel()
{
EditorGUI.indentLevel += 1;
DoPopup("_BevelType", "Type", s_BevelTypeLabels);
DoSlider("_BevelAmount", "Amount");
DoSlider("_BevelOffset", "Offset");
DoSlider("_BevelWidth", "Width");
DoSlider("_BevelRoundness", "Roundness");
DoSlider("_BevelClamp", "Clamp");
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoLocalLightingPanel()
{
EditorGUI.indentLevel += 1;
DoSlider("_LightAngle", "Light Angle");
DoColor("_SpecularColor", "Specular Color");
DoSlider("_SpecularPower", "Specular Power");
DoSlider("_Reflectivity", "Reflectivity Power");
DoSlider("_Diffuse", "Diffuse Shadow");
DoSlider("_Ambient", "Ambient Shadow");
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoSurfaceLightingPanel()
{
EditorGUI.indentLevel += 1;
DoColor("_SpecColor", "Specular Color");
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoBumpMapPanel()
{
EditorGUI.indentLevel += 1;
DoTexture2D("_BumpMap", "Texture");
DoSlider("_BumpFace", "Face");
DoSlider("_BumpOutline", "Outline");
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoEnvMapPanel()
{
EditorGUI.indentLevel += 1;
DoColor("_ReflectFaceColor", "Face Color");
DoColor("_ReflectOutlineColor", "Outline Color");
DoCubeMap("_Cube", "Texture");
DoVector3("_EnvMatrixRotation", "Rotation");
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoGlowPanel()
{
EditorGUI.indentLevel += 1;
DoColor("_GlowColor", "Color");
DoSlider("_GlowOffset", "Offset");
DoSlider("_GlowInner", "Inner");
DoSlider("_GlowOuter", "Outer");
DoSlider("_GlowPower", "Power");
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoDebugPanel()
{
EditorGUI.indentLevel += 1;
DoTexture2D("_MainTex", "Font Atlas");
DoFloat("_GradientScale", "Gradient Scale");
DoFloat("_TextureWidth", "Texture Width");
DoFloat("_TextureHeight", "Texture Height");
EditorGUILayout.Space();
DoFloat("_ScaleX", "Scale X");
DoFloat("_ScaleY", "Scale Y");
if (m_Material.HasProperty(ShaderUtilities.ID_Sharpness))
DoSlider("_Sharpness", "Sharpness");
DoSlider("_PerspectiveFilter", "Perspective Filter");
EditorGUILayout.Space();
DoFloat("_VertexOffsetX", "Offset X");
DoFloat("_VertexOffsetY", "Offset Y");
if (m_Material.HasProperty(ShaderUtilities.ID_MaskCoord))
{
EditorGUILayout.Space();
s_MaskFeature.ReadState(m_Material);
s_MaskFeature.DoPopup(m_Editor, m_Material);
if (s_MaskFeature.Active)
{
DoMaskSubgroup();
}
EditorGUILayout.Space();
DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels);
}
else if (m_Material.HasProperty("_MaskTex"))
{
DoMaskTexSubgroup();
}
else if (m_Material.HasProperty(ShaderUtilities.ID_MaskSoftnessX))
{
EditorGUILayout.Space();
DoFloat("_MaskSoftnessX", "Softness X");
DoFloat("_MaskSoftnessY", "Softness Y");
DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels);
}
if (m_Material.HasProperty(ShaderUtilities.ID_StencilID))
{
EditorGUILayout.Space();
DoFloat("_Stencil", "Stencil ID");
DoFloat("_StencilComp", "Stencil Comp");
}
EditorGUILayout.Space();
EditorGUI.BeginChangeCheck();
bool useRatios = EditorGUILayout.Toggle("Use Ratios", !m_Material.IsKeywordEnabled("RATIOS_OFF"));
if (EditorGUI.EndChangeCheck())
{
m_Editor.RegisterPropertyChangeUndo("Use Ratios");
if (useRatios)
{
m_Material.DisableKeyword("RATIOS_OFF");
}
else
{
m_Material.EnableKeyword("RATIOS_OFF");
}
}
if (m_Material.HasProperty(ShaderUtilities.ShaderTag_CullMode))
{
EditorGUILayout.Space();
DoPopup("_CullMode", "Cull Mode", s_CullingTypeLabels);
}
EditorGUILayout.Space();
EditorGUI.BeginDisabledGroup(true);
DoFloat("_ScaleRatioA", "Scale Ratio A");
DoFloat("_ScaleRatioB", "Scale Ratio B");
DoFloat("_ScaleRatioC", "Scale Ratio C");
EditorGUI.EndDisabledGroup();
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoDebugPanelSRP()
{
EditorGUI.indentLevel += 1;
DoTexture2D("_MainTex", "Font Atlas");
DoFloat("_GradientScale", "Gradient Scale");
//DoFloat("_TextureWidth", "Texture Width");
//DoFloat("_TextureHeight", "Texture Height");
EditorGUILayout.Space();
/*
DoFloat("_ScaleX", "Scale X");
DoFloat("_ScaleY", "Scale Y");
if (m_Material.HasProperty(ShaderUtilities.ID_Sharpness))
DoSlider("_Sharpness", "Sharpness");
DoSlider("_PerspectiveFilter", "Perspective Filter");
EditorGUILayout.Space();
DoFloat("_VertexOffsetX", "Offset X");
DoFloat("_VertexOffsetY", "Offset Y");
if (m_Material.HasProperty(ShaderUtilities.ID_MaskCoord))
{
EditorGUILayout.Space();
s_MaskFeature.ReadState(m_Material);
s_MaskFeature.DoPopup(m_Editor, m_Material);
if (s_MaskFeature.Active)
{
DoMaskSubgroup();
}
EditorGUILayout.Space();
DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels);
}
else if (m_Material.HasProperty("_MaskTex"))
{
DoMaskTexSubgroup();
}
else if (m_Material.HasProperty(ShaderUtilities.ID_MaskSoftnessX))
{
EditorGUILayout.Space();
DoFloat("_MaskSoftnessX", "Softness X");
DoFloat("_MaskSoftnessY", "Softness Y");
DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels);
}
if (m_Material.HasProperty(ShaderUtilities.ID_StencilID))
{
EditorGUILayout.Space();
DoFloat("_Stencil", "Stencil ID");
DoFloat("_StencilComp", "Stencil Comp");
}
EditorGUILayout.Space();
EditorGUI.BeginChangeCheck();
bool useRatios = EditorGUILayout.Toggle("Use Ratios", !m_Material.IsKeywordEnabled("RATIOS_OFF"));
if (EditorGUI.EndChangeCheck())
{
m_Editor.RegisterPropertyChangeUndo("Use Ratios");
if (useRatios)
{
m_Material.DisableKeyword("RATIOS_OFF");
}
else
{
m_Material.EnableKeyword("RATIOS_OFF");
}
}
*/
if (m_Material.HasProperty(ShaderUtilities.ShaderTag_CullMode))
{
EditorGUILayout.Space();
DoPopup("_CullMode", "Cull Mode", s_CullingTypeLabels);
}
EditorGUILayout.Space();
/*
EditorGUI.BeginDisabledGroup(true);
DoFloat("_ScaleRatioA", "Scale Ratio A");
DoFloat("_ScaleRatioB", "Scale Ratio B");
DoFloat("_ScaleRatioC", "Scale Ratio C");
EditorGUI.EndDisabledGroup();
*/
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoMaskSubgroup()
{
DoVector("_MaskCoord", "Mask Bounds", s_XywhVectorLabels);
if (Selection.activeGameObject != null)
{
Renderer renderer = Selection.activeGameObject.GetComponent<Renderer>();
if (renderer != null)
{
Rect rect = EditorGUILayout.GetControlRect();
rect.x += EditorGUIUtility.labelWidth;
rect.width -= EditorGUIUtility.labelWidth;
if (GUI.Button(rect, "Match Renderer Bounds"))
{
FindProperty("_MaskCoord", m_Properties).vectorValue = new Vector4(
0,
0,
Mathf.Round(renderer.bounds.extents.x * 1000) / 1000,
Mathf.Round(renderer.bounds.extents.y * 1000) / 1000
);
}
}
}
if (s_MaskFeature.State == 1)
{
DoFloat("_MaskSoftnessX", "Softness X");
DoFloat("_MaskSoftnessY", "Softness Y");
}
}
void DoMaskTexSubgroup()
{
EditorGUILayout.Space();
DoTexture2D("_MaskTex", "Mask Texture");
DoToggle("_MaskInverse", "Inverse Mask");
DoColor("_MaskEdgeColor", "Edge Color");
DoSlider("_MaskEdgeSoftness", "Edge Softness");
DoSlider("_MaskWipeControl", "Wipe Position");
DoFloat("_MaskSoftnessX", "Softness X");
DoFloat("_MaskSoftnessY", "Softness Y");
DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels);
}
// protected override void SetupMaterialKeywordsAndPassInternal(Material material)
// {
// BaseLitGUI.SetupBaseLitKeywords(material);
// BaseLitGUI.SetupBaseLitMaterialPass(material);
// }
}
}
#endif

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 85016528879d5d644981050d1d0a4368
timeCreated: 1469844718
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,642 @@
#if HDRP_10_7_OR_NEWER
using UnityEngine;
using UnityEditor;
using UnityEditor.Rendering.HighDefinition;
namespace TMPro.EditorUtilities
{
internal class TMP_SDF_HDRPUnlitShaderGUI : TMP_BaseHDRPUnlitShaderGUI
{
#if !HDRP_11_OR_NEWER
const SurfaceOptionUIBlock.Features surfaceOptionFeatures = SurfaceOptionUIBlock.Features.Unlit;
private readonly MaterialUIBlockList uiBlocks = new MaterialUIBlockList
{
new SurfaceOptionUIBlock(MaterialUIBlock.Expandable.Base, features: surfaceOptionFeatures),
new ShaderGraphUIBlock(MaterialUIBlock.Expandable.ShaderGraph, ShaderGraphUIBlock.Features.Unlit),
new AdvancedOptionsUIBlock(MaterialUIBlock.Expandable.Advance, ~AdvancedOptionsUIBlock.Features.SpecularOcclusion)
};
#endif
static ShaderFeature s_OutlineFeature, s_UnderlayFeature, s_BevelFeature, s_GlowFeature, s_MaskFeature;
static bool s_Face = true, s_Outline = true, s_Outline2 = true, s_Outline3 = true, s_Underlay = true, s_Lighting = true, s_Glow, s_Bevel, s_Light, s_Bump, s_Env;
static string[]
s_FaceUVSpeedName = { "_FaceUVSpeed" },
s_FaceUvSpeedNames = { "_FaceUVSpeedX", "_FaceUVSpeedY" },
s_OutlineUvSpeedNames = { "_OutlineUVSpeedX", "_OutlineUVSpeedY" },
s_OutlineUvSpeedName = { "_OutlineUVSpeed" };
/// <summary>
///
/// </summary>
static TMP_SDF_HDRPUnlitShaderGUI()
{
s_OutlineFeature = new ShaderFeature()
{
undoLabel = "Outline",
keywords = new[] { "OUTLINE_ON" }
};
s_UnderlayFeature = new ShaderFeature()
{
undoLabel = "Underlay",
keywords = new[] { "UNDERLAY_ON", "UNDERLAY_INNER" },
label = new GUIContent("Underlay Type"),
keywordLabels = new[]
{
new GUIContent("None"), new GUIContent("Normal"), new GUIContent("Inner")
}
};
s_BevelFeature = new ShaderFeature()
{
undoLabel = "Bevel",
keywords = new[] { "BEVEL_ON" }
};
s_GlowFeature = new ShaderFeature()
{
undoLabel = "Glow",
keywords = new[] { "GLOW_ON" }
};
s_MaskFeature = new ShaderFeature()
{
undoLabel = "Mask",
keywords = new[] { "MASK_HARD", "MASK_SOFT" },
label = new GUIContent("Mask"),
keywordLabels = new[]
{
new GUIContent("Mask Off"), new GUIContent("Mask Hard"), new GUIContent("Mask Soft")
}
};
}
/// <summary>
///
/// </summary>
public TMP_SDF_HDRPUnlitShaderGUI()
{
// Remove the ShaderGraphUIBlock to avoid having duplicated properties in the UI.
uiBlocks.RemoveAll(b => b is ShaderGraphUIBlock);
}
protected override void DoGUI()
{
s_Face = BeginPanel("Face", s_Face);
if (s_Face)
{
DoFacePanel();
}
EndPanel();
// Outline panels
DoOutlinePanels();
// Underlay panel
s_Underlay = BeginPanel("Underlay", s_Underlay);
if (s_Underlay)
{
DoUnderlayPanel();
}
EndPanel();
// Lighting panel
DrawLightingPanel();
/*
if (m_Material.HasProperty(ShaderUtilities.ID_GlowColor))
{
s_Glow = BeginPanel("Glow", s_GlowFeature, s_Glow);
if (s_Glow)
{
DoGlowPanel();
}
EndPanel();
}
*/
s_DebugExtended = BeginPanel("Debug Settings", s_DebugExtended);
if (s_DebugExtended)
{
DoDebugPanelSRP();
}
EndPanel();
EditorGUILayout.Space();
EditorGUILayout.Space();
// Draw HDRP panels
uiBlocks.OnGUI(m_Editor, m_Properties);
#if HDRP_12_OR_NEWER
ValidateMaterial(m_Material);
#else
SetupMaterialKeywordsAndPass(m_Material);
#endif
}
void DoFacePanel()
{
EditorGUI.indentLevel += 1;
DoColor("_FaceColor", "Color");
if (m_Material.HasProperty(ShaderUtilities.ID_FaceTex))
{
if (m_Material.HasProperty("_FaceUVSpeedX"))
{
DoTexture2D("_FaceTex", "Texture", true, s_FaceUvSpeedNames);
}
else if (m_Material.HasProperty("_FaceUVSpeed"))
{
DoTexture2D("_FaceTex", "Texture", true, s_FaceUVSpeedName);
}
else
{
DoTexture2D("_FaceTex", "Texture", true);
}
}
if (m_Material.HasProperty("_Softness"))
{
DoSlider("_Softness", "X", new Vector2(0, 1), "Softness");
}
if (m_Material.HasProperty("_OutlineSoftness"))
{
DoSlider("_OutlineSoftness", "Softness");
}
if (m_Material.HasProperty(ShaderUtilities.ID_FaceDilate))
{
DoSlider("_FaceDilate", "Dilate");
if (m_Material.HasProperty(ShaderUtilities.ID_Shininess))
{
DoSlider("_FaceShininess", "Gloss");
}
}
if (m_Material.HasProperty(ShaderUtilities.ID_IsoPerimeter))
{
DoSlider("_IsoPerimeter", "X", new Vector2(-1, 1), "Dilate");
}
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoOutlinePanels()
{
s_Outline = BeginPanel("Outline 1", s_Outline);
if (s_Outline)
DoOutlinePanelWithTexture(1, "Y", "Color");
EndPanel();
s_Outline2 = BeginPanel("Outline 2", s_Outline2);
if (s_Outline2)
DoOutlinePanel(2, "Z", "Color");
EndPanel();
s_Outline3 = BeginPanel("Outline 3", s_Outline3);
if (s_Outline3)
DoOutlinePanel(3, "W", "Color");
EndPanel();
}
void DoOutlinePanel(int outlineID, string propertyField, string label)
{
EditorGUI.indentLevel += 1;
DoColor("_OutlineColor" + outlineID, label);
if (outlineID != 3)
DoOffset("_OutlineOffset" + outlineID, "Offset");
else
{
if (m_Material.GetFloat(ShaderUtilities.ID_OutlineMode) == 0)
DoOffset("_OutlineOffset" + outlineID, "Offset");
}
DoSlider("_Softness", propertyField, new Vector2(0, 1), "Softness");
DoSlider("_IsoPerimeter", propertyField, new Vector2(-1, 1), "Dilate");
if (outlineID == 3)
{
DoToggle("_OutlineMode", "Outline Mode");
}
if (m_Material.HasProperty("_OutlineShininess"))
{
//DoSlider("_OutlineShininess", "Gloss");
}
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoOutlinePanelWithTexture(int outlineID, string propertyField, string label)
{
EditorGUI.indentLevel += 1;
DoColor("_OutlineColor" + outlineID, label);
if (m_Material.HasProperty(ShaderUtilities.ID_OutlineTex))
{
if (m_Material.HasProperty("_OutlineUVSpeedX"))
{
DoTexture2D("_OutlineTex", "Texture", true, s_OutlineUvSpeedNames);
}
else if (m_Material.HasProperty("_OutlineUVSpeed"))
{
DoTexture2D("_OutlineTex", "Texture", true, s_OutlineUvSpeedName);
}
else
{
DoTexture2D("_OutlineTex", "Texture", true);
}
}
DoOffset("_OutlineOffset" + outlineID, "Offset");
DoSlider("_Softness", propertyField, new Vector2(0, 1), "Softness");
DoSlider("_IsoPerimeter", propertyField, new Vector2(-1, 1), "Dilate");
if (m_Material.HasProperty("_OutlineShininess"))
{
//DoSlider("_OutlineShininess", "Gloss");
}
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoUnderlayPanel()
{
EditorGUI.indentLevel += 1;
if (m_Material.HasProperty(ShaderUtilities.ID_IsoPerimeter))
{
DoColor("_UnderlayColor", "Color");
DoSlider("_UnderlayOffset", "X", new Vector2(-1, 1), "Offset X");
DoSlider("_UnderlayOffset", "Y", new Vector2(-1, 1), "Offset Y");
DoSlider("_UnderlayDilate", new Vector2(-1, 1), "Dilate");
DoSlider("_UnderlaySoftness", new Vector2(0, 1), "Softness");
}
else
{
s_UnderlayFeature.DoPopup(m_Editor, m_Material);
DoColor("_UnderlayColor", "Color");
DoSlider("_UnderlayOffsetX", "Offset X");
DoSlider("_UnderlayOffsetY", "Offset Y");
DoSlider("_UnderlayDilate", "Dilate");
DoSlider("_UnderlaySoftness", "Softness");
}
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
static GUIContent[] s_BevelTypeLabels =
{
new GUIContent("Outer Bevel"),
new GUIContent("Inner Bevel")
};
void DrawLightingPanel()
{
s_Lighting = BeginPanel("Lighting", s_Lighting);
if (s_Lighting)
{
s_Bevel = BeginPanel("Bevel", s_Bevel);
if (s_Bevel)
{
DoBevelPanel();
}
EndPanel();
s_Light = BeginPanel("Local Lighting", s_Light);
if (s_Light)
{
DoLocalLightingPanel();
}
EndPanel();
/*
s_Bump = BeginPanel("Bump Map", s_Bump);
if (s_Bump)
{
DoBumpMapPanel();
}
EndPanel();
s_Env = BeginPanel("Environment Map", s_Env);
if (s_Env)
{
DoEnvMapPanel();
}
EndPanel();
*/
}
EndPanel();
}
void DoBevelPanel()
{
EditorGUI.indentLevel += 1;
DoPopup("_BevelType", "Type", s_BevelTypeLabels);
DoSlider("_BevelAmount", "Amount");
DoSlider("_BevelOffset", "Offset");
DoSlider("_BevelWidth", "Width");
DoSlider("_BevelRoundness", "Roundness");
DoSlider("_BevelClamp", "Clamp");
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoLocalLightingPanel()
{
EditorGUI.indentLevel += 1;
DoSlider("_LightAngle", "Light Angle");
DoColor("_SpecularColor", "Specular Color");
DoSlider("_SpecularPower", "Specular Power");
DoSlider("_Reflectivity", "Reflectivity Power");
DoSlider("_Diffuse", "Diffuse Shadow");
DoSlider("_Ambient", "Ambient Shadow");
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoSurfaceLightingPanel()
{
EditorGUI.indentLevel += 1;
DoColor("_SpecColor", "Specular Color");
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoBumpMapPanel()
{
EditorGUI.indentLevel += 1;
DoTexture2D("_BumpMap", "Texture");
DoSlider("_BumpFace", "Face");
DoSlider("_BumpOutline", "Outline");
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoEnvMapPanel()
{
EditorGUI.indentLevel += 1;
DoColor("_ReflectFaceColor", "Face Color");
DoColor("_ReflectOutlineColor", "Outline Color");
DoCubeMap("_Cube", "Texture");
DoVector3("_EnvMatrixRotation", "Rotation");
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoGlowPanel()
{
EditorGUI.indentLevel += 1;
DoColor("_GlowColor", "Color");
DoSlider("_GlowOffset", "Offset");
DoSlider("_GlowInner", "Inner");
DoSlider("_GlowOuter", "Outer");
DoSlider("_GlowPower", "Power");
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoDebugPanel()
{
EditorGUI.indentLevel += 1;
DoTexture2D("_MainTex", "Font Atlas");
DoFloat("_GradientScale", "Gradient Scale");
DoFloat("_TextureWidth", "Texture Width");
DoFloat("_TextureHeight", "Texture Height");
EditorGUILayout.Space();
DoFloat("_ScaleX", "Scale X");
DoFloat("_ScaleY", "Scale Y");
if (m_Material.HasProperty(ShaderUtilities.ID_Sharpness))
DoSlider("_Sharpness", "Sharpness");
DoSlider("_PerspectiveFilter", "Perspective Filter");
EditorGUILayout.Space();
DoFloat("_VertexOffsetX", "Offset X");
DoFloat("_VertexOffsetY", "Offset Y");
if (m_Material.HasProperty(ShaderUtilities.ID_MaskCoord))
{
EditorGUILayout.Space();
s_MaskFeature.ReadState(m_Material);
s_MaskFeature.DoPopup(m_Editor, m_Material);
if (s_MaskFeature.Active)
{
DoMaskSubgroup();
}
EditorGUILayout.Space();
DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels);
}
else if (m_Material.HasProperty("_MaskTex"))
{
DoMaskTexSubgroup();
}
else if (m_Material.HasProperty(ShaderUtilities.ID_MaskSoftnessX))
{
EditorGUILayout.Space();
DoFloat("_MaskSoftnessX", "Softness X");
DoFloat("_MaskSoftnessY", "Softness Y");
DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels);
}
if (m_Material.HasProperty(ShaderUtilities.ID_StencilID))
{
EditorGUILayout.Space();
DoFloat("_Stencil", "Stencil ID");
DoFloat("_StencilComp", "Stencil Comp");
}
EditorGUILayout.Space();
EditorGUI.BeginChangeCheck();
bool useRatios = EditorGUILayout.Toggle("Use Ratios", !m_Material.IsKeywordEnabled("RATIOS_OFF"));
if (EditorGUI.EndChangeCheck())
{
m_Editor.RegisterPropertyChangeUndo("Use Ratios");
if (useRatios)
{
m_Material.DisableKeyword("RATIOS_OFF");
}
else
{
m_Material.EnableKeyword("RATIOS_OFF");
}
}
if (m_Material.HasProperty(ShaderUtilities.ShaderTag_CullMode))
{
EditorGUILayout.Space();
DoPopup("_CullMode", "Cull Mode", s_CullingTypeLabels);
}
EditorGUILayout.Space();
EditorGUI.BeginDisabledGroup(true);
DoFloat("_ScaleRatioA", "Scale Ratio A");
DoFloat("_ScaleRatioB", "Scale Ratio B");
DoFloat("_ScaleRatioC", "Scale Ratio C");
EditorGUI.EndDisabledGroup();
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoDebugPanelSRP()
{
EditorGUI.indentLevel += 1;
DoTexture2D("_MainTex", "Font Atlas");
DoFloat("_GradientScale", "Gradient Scale");
//DoFloat("_TextureWidth", "Texture Width");
//DoFloat("_TextureHeight", "Texture Height");
EditorGUILayout.Space();
/*
DoFloat("_ScaleX", "Scale X");
DoFloat("_ScaleY", "Scale Y");
if (m_Material.HasProperty(ShaderUtilities.ID_Sharpness))
DoSlider("_Sharpness", "Sharpness");
DoSlider("_PerspectiveFilter", "Perspective Filter");
EditorGUILayout.Space();
DoFloat("_VertexOffsetX", "Offset X");
DoFloat("_VertexOffsetY", "Offset Y");
if (m_Material.HasProperty(ShaderUtilities.ID_MaskCoord))
{
EditorGUILayout.Space();
s_MaskFeature.ReadState(m_Material);
s_MaskFeature.DoPopup(m_Editor, m_Material);
if (s_MaskFeature.Active)
{
DoMaskSubgroup();
}
EditorGUILayout.Space();
DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels);
}
else if (m_Material.HasProperty("_MaskTex"))
{
DoMaskTexSubgroup();
}
else if (m_Material.HasProperty(ShaderUtilities.ID_MaskSoftnessX))
{
EditorGUILayout.Space();
DoFloat("_MaskSoftnessX", "Softness X");
DoFloat("_MaskSoftnessY", "Softness Y");
DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels);
}
if (m_Material.HasProperty(ShaderUtilities.ID_StencilID))
{
EditorGUILayout.Space();
DoFloat("_Stencil", "Stencil ID");
DoFloat("_StencilComp", "Stencil Comp");
}
EditorGUILayout.Space();
EditorGUI.BeginChangeCheck();
bool useRatios = EditorGUILayout.Toggle("Use Ratios", !m_Material.IsKeywordEnabled("RATIOS_OFF"));
if (EditorGUI.EndChangeCheck())
{
m_Editor.RegisterPropertyChangeUndo("Use Ratios");
if (useRatios)
{
m_Material.DisableKeyword("RATIOS_OFF");
}
else
{
m_Material.EnableKeyword("RATIOS_OFF");
}
}
*/
if (m_Material.HasProperty(ShaderUtilities.ShaderTag_CullMode))
{
EditorGUILayout.Space();
DoPopup("_CullMode", "Cull Mode", s_CullingTypeLabels);
}
EditorGUILayout.Space();
/*
EditorGUI.BeginDisabledGroup(true);
DoFloat("_ScaleRatioA", "Scale Ratio A");
DoFloat("_ScaleRatioB", "Scale Ratio B");
DoFloat("_ScaleRatioC", "Scale Ratio C");
EditorGUI.EndDisabledGroup();
*/
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoMaskSubgroup()
{
DoVector("_MaskCoord", "Mask Bounds", s_XywhVectorLabels);
if (Selection.activeGameObject != null)
{
Renderer renderer = Selection.activeGameObject.GetComponent<Renderer>();
if (renderer != null)
{
Rect rect = EditorGUILayout.GetControlRect();
rect.x += EditorGUIUtility.labelWidth;
rect.width -= EditorGUIUtility.labelWidth;
if (GUI.Button(rect, "Match Renderer Bounds"))
{
FindProperty("_MaskCoord", m_Properties).vectorValue = new Vector4(
0,
0,
Mathf.Round(renderer.bounds.extents.x * 1000) / 1000,
Mathf.Round(renderer.bounds.extents.y * 1000) / 1000
);
}
}
}
if (s_MaskFeature.State == 1)
{
DoFloat("_MaskSoftnessX", "Softness X");
DoFloat("_MaskSoftnessY", "Softness Y");
}
}
void DoMaskTexSubgroup()
{
EditorGUILayout.Space();
DoTexture2D("_MaskTex", "Mask Texture");
DoToggle("_MaskInverse", "Inverse Mask");
DoColor("_MaskEdgeColor", "Edge Color");
DoSlider("_MaskEdgeSoftness", "Edge Softness");
DoSlider("_MaskWipeControl", "Wipe Position");
DoFloat("_MaskSoftnessX", "Softness X");
DoFloat("_MaskSoftnessY", "Softness Y");
DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels);
}
// protected override void SetupMaterialKeywordsAndPassInternal(Material material)
// {
// BaseLitGUI.SetupBaseLitKeywords(material);
// BaseLitGUI.SetupBaseLitMaterialPass(material);
// }
}
}
#endif

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: bad96c2cfa78a124cb8ec890d2386dfe
timeCreated: 1469844718
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ea7c31b5b377c314db28ad3fabbbd38d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,63 @@
using UnityEditorInternal;
using UnityEngine;
using UnityEngine.UI;
using UnityEditor;
namespace TMPro.EditorUtilities
{
[CustomPropertyDrawer(typeof(TMP_Dropdown.OptionDataList), true)]
class DropdownOptionListDrawer : PropertyDrawer
{
private ReorderableList m_ReorderableList;
private void Init(SerializedProperty property)
{
if (m_ReorderableList != null)
return;
SerializedProperty array = property.FindPropertyRelative("m_Options");
m_ReorderableList = new ReorderableList(property.serializedObject, array);
m_ReorderableList.drawElementCallback = DrawOptionData;
m_ReorderableList.drawHeaderCallback = DrawHeader;
m_ReorderableList.elementHeight += 40;
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
Init(property);
m_ReorderableList.DoList(position);
}
private void DrawHeader(Rect rect)
{
GUI.Label(rect, "Options");
}
private void DrawOptionData(Rect rect, int index, bool isActive, bool isFocused)
{
SerializedProperty itemData = m_ReorderableList.serializedProperty.GetArrayElementAtIndex(index);
SerializedProperty itemText = itemData.FindPropertyRelative("m_Text");
SerializedProperty itemImage = itemData.FindPropertyRelative("m_Image");
SerializedProperty itemColor = itemData.FindPropertyRelative("m_Color");
RectOffset offset = new RectOffset(0, 0, -1, -3);
rect = offset.Add(rect);
rect.height = EditorGUIUtility.singleLineHeight;
EditorGUI.PropertyField(rect, itemText, GUIContent.none);
rect.y += EditorGUIUtility.singleLineHeight + 2;
EditorGUI.PropertyField(rect, itemImage, GUIContent.none);
rect.y += EditorGUIUtility.singleLineHeight + 2;
EditorGUI.PropertyField(rect, itemColor, GUIContent.none);
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
Init(property);
return m_ReorderableList.GetHeight();
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 9545c9eb3bf94265810463794fec8334
timeCreated: 1464818008
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,60 @@
using UnityEngine;
using UnityEngine.TextCore;
using UnityEditor;
using System.Collections;
namespace TMPro.EditorUtilities
{
[CustomPropertyDrawer(typeof(GlyphMetrics))]
internal class GlyphMetricsPropertyDrawer : PropertyDrawer
{
private static readonly GUIContent k_GlyphMetricLabel = new GUIContent("Glyph Metrics", "The layout metrics of the glyph.");
private static readonly GUIContent k_WidthPropertyLabel = new GUIContent("W:", "The width of the glyph.");
private static readonly GUIContent k_HeightPropertyLabel = new GUIContent("H:", "The height of the glyph.");
private static readonly GUIContent k_BearingXPropertyLabel = new GUIContent("BX:", "The horizontal bearing X of the glyph.");
private static readonly GUIContent k_BearingYPropertyLabel = new GUIContent("BY:", "The horizontal bearing Y of the glyph.");
private static readonly GUIContent k_HorizontalAdvancePropertyLabel = new GUIContent("AD:", "The horizontal advance of the glyph.");
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
SerializedProperty prop_Width = property.FindPropertyRelative("m_Width");
SerializedProperty prop_Height = property.FindPropertyRelative("m_Height");
SerializedProperty prop_HoriBearingX = property.FindPropertyRelative("m_HorizontalBearingX");
SerializedProperty prop_HoriBearingY = property.FindPropertyRelative("m_HorizontalBearingY");
SerializedProperty prop_HoriAdvance = property.FindPropertyRelative("m_HorizontalAdvance");
// We get Rect since a valid position may not be provided by the caller.
Rect rect = new Rect(position.x, position.y, position.width, 49);
EditorGUI.LabelField(new Rect(rect.x, rect.y - 2.5f, rect.width, 18), k_GlyphMetricLabel);
EditorGUIUtility.labelWidth = 20f;
EditorGUIUtility.fieldWidth = 15f;
//GUI.enabled = false;
float width = (rect.width - 75f) / 2;
EditorGUI.PropertyField(new Rect(rect.x + width * 0, rect.y + 20, width - 5f, 18), prop_Width, k_WidthPropertyLabel);
EditorGUI.PropertyField(new Rect(rect.x + width * 1, rect.y + 20, width - 5f, 18), prop_Height, k_HeightPropertyLabel);
//GUI.enabled = true;
width = (rect.width - 75f) / 3;
EditorGUI.BeginChangeCheck();
EditorGUI.PropertyField(new Rect(rect.x + width * 0, rect.y + 40, width - 5f, 18), prop_HoriBearingX, k_BearingXPropertyLabel);
EditorGUI.PropertyField(new Rect(rect.x + width * 1, rect.y + 40, width - 5f, 18), prop_HoriBearingY, k_BearingYPropertyLabel);
EditorGUI.PropertyField(new Rect(rect.x + width * 2, rect.y + 40, width - 5f, 18), prop_HoriAdvance, k_HorizontalAdvancePropertyLabel);
if (EditorGUI.EndChangeCheck())
{
}
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return 65f;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e3882522a08b6f5459b4dea6f8791278
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,372 @@
using UnityEngine;
using UnityEngine.TextCore;
using UnityEngine.TextCore.LowLevel;
using UnityEditor;
using System.Collections.Generic;
namespace TMPro.EditorUtilities
{
[CustomPropertyDrawer(typeof(GlyphPairAdjustmentRecord))]
internal class GlyphPairAdjustmentRecordPropertyDrawer : PropertyDrawer
{
private bool isEditingEnabled;
private bool isSelectable;
private Dictionary<uint, GlyphProxy> m_GlyphLookupDictionary;
private string m_FirstCharacter = string.Empty;
private string m_SecondCharacter = string.Empty;
private string m_PreviousInput;
static GUIContent s_CharacterTextFieldLabel = new GUIContent("Char:", "Enter the character or its UTF16 or UTF32 Unicode character escape sequence. For UTF16 use \"\\uFF00\" and for UTF32 use \"\\UFF00FF00\" representation.");
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
SerializedProperty prop_FirstAdjustmentRecord = property.FindPropertyRelative("m_FirstAdjustmentRecord");
SerializedProperty prop_SecondAdjustmentRecord = property.FindPropertyRelative("m_SecondAdjustmentRecord");
SerializedProperty prop_FirstGlyphIndex = prop_FirstAdjustmentRecord.FindPropertyRelative("m_GlyphIndex");
SerializedProperty prop_FirstGlyphValueRecord = prop_FirstAdjustmentRecord.FindPropertyRelative("m_GlyphValueRecord");
SerializedProperty prop_SecondGlyphIndex = prop_SecondAdjustmentRecord.FindPropertyRelative("m_GlyphIndex");
SerializedProperty prop_SecondGlyphValueRecord = prop_SecondAdjustmentRecord.FindPropertyRelative("m_GlyphValueRecord");
SerializedProperty prop_FontFeatureLookupFlags = property.FindPropertyRelative("m_FeatureLookupFlags");
// Refresh glyph proxy lookup dictionary if needed
if (TMP_PropertyDrawerUtilities.s_RefreshGlyphProxyLookup)
TMP_PropertyDrawerUtilities.RefreshGlyphProxyLookup(property.serializedObject);
position.yMin += 2;
float width = position.width / 2;
float padding = 5.0f;
Rect rect;
isEditingEnabled = GUI.enabled;
isSelectable = label.text == "Selectable";
if (isSelectable)
GUILayoutUtility.GetRect(position.width, 80);
else
GUILayoutUtility.GetRect(position.width, 55);
GUIStyle style = new GUIStyle(EditorStyles.label);
style.richText = true;
// First Glyph
GUI.enabled = isEditingEnabled;
if (isSelectable)
{
rect = new Rect(position.x + 70, position.y, position.width, 49);
float labelWidth = GUI.skin.label.CalcSize(new GUIContent("ID: " + prop_FirstGlyphIndex.intValue)).x;
EditorGUI.LabelField(new Rect(position.x + (64 - labelWidth) / 2, position.y + 60, 64f, 18f), new GUIContent("ID: <color=#FFFF80>" + prop_FirstGlyphIndex.intValue + "</color>"), style);
GUI.enabled = isEditingEnabled;
EditorGUIUtility.labelWidth = 25f;
rect = new Rect(position.x + 70, position.y + 10, (width - 70) - padding, 18);
EditorGUI.PropertyField(rect, prop_FirstGlyphValueRecord.FindPropertyRelative("m_XPlacement"), new GUIContent("OX:"));
rect.y += 20;
EditorGUI.PropertyField(rect, prop_FirstGlyphValueRecord.FindPropertyRelative("m_YPlacement"), new GUIContent("OY:"));
rect.y += 20;
EditorGUI.PropertyField(rect, prop_FirstGlyphValueRecord.FindPropertyRelative("m_XAdvance"), new GUIContent("AX:"));
//rect.y += 20;
//EditorGUI.PropertyField(rect, prop_FirstGlyphValueRecord.FindPropertyRelative("m_YAdvance"), new GUIContent("AY:"));
DrawGlyph((uint)prop_FirstGlyphIndex.intValue, new Rect(position.x, position.y + 2, 64, 60), property);
}
else
{
rect = new Rect(position.x, position.y, width / 2 * 0.8f - padding, 18);
EditorGUIUtility.labelWidth = 40f;
// First Character Lookup
GUI.SetNextControlName("FirstCharacterField");
EditorGUI.BeginChangeCheck();
string firstCharacter = EditorGUI.TextField(rect, s_CharacterTextFieldLabel, m_FirstCharacter);
if (GUI.GetNameOfFocusedControl() == "FirstCharacterField")
{
if (ValidateInput(firstCharacter))
{
//Debug.Log("1st Unicode value: [" + firstCharacter + "]");
uint unicode = GetUnicodeCharacter(firstCharacter);
// Lookup glyph index
TMP_SerializedPropertyHolder propertyHolder = property.serializedObject.targetObject as TMP_SerializedPropertyHolder;
TMP_FontAsset fontAsset = propertyHolder.fontAsset;
if (fontAsset != null)
{
prop_FirstGlyphIndex.intValue = (int)fontAsset.GetGlyphIndex(unicode);
propertyHolder.firstCharacter = unicode;
}
}
}
if (EditorGUI.EndChangeCheck())
m_FirstCharacter = firstCharacter;
// First Glyph Index
rect.x += width / 2 * 0.8f;
EditorGUIUtility.labelWidth = 25f;
EditorGUI.BeginChangeCheck();
EditorGUI.PropertyField(rect, prop_FirstGlyphIndex, new GUIContent("ID:"));
if (EditorGUI.EndChangeCheck())
{
}
GUI.enabled = isEditingEnabled;
EditorGUIUtility.labelWidth = 25f;
rect = new Rect(position.x, position.y + 20, width * 0.5f - padding, 18);
EditorGUI.PropertyField(rect, prop_FirstGlyphValueRecord.FindPropertyRelative("m_XPlacement"), new GUIContent("OX"));
rect.x += width * 0.5f;
EditorGUI.PropertyField(rect, prop_FirstGlyphValueRecord.FindPropertyRelative("m_YPlacement"), new GUIContent("OY"));
rect.x = position.x;
rect.y += 20;
EditorGUI.PropertyField(rect, prop_FirstGlyphValueRecord.FindPropertyRelative("m_XAdvance"), new GUIContent("AX"));
//rect.x += width * 0.5f;
//EditorGUI.PropertyField(rect, prop_FirstGlyphAdjustment.FindPropertyRelative("m_YAdvance"), new GUIContent("AY"));
}
// Second Glyph
GUI.enabled = isEditingEnabled;
if (isSelectable)
{
float labelWidth = GUI.skin.label.CalcSize(new GUIContent("ID: " + prop_SecondGlyphIndex.intValue)).x;
EditorGUI.LabelField(new Rect(position.width / 2 + 20 + (64 - labelWidth) / 2, position.y + 60, 64f, 18f), new GUIContent("ID: <color=#FFFF80>" + prop_SecondGlyphIndex.intValue + "</color>"), style);
GUI.enabled = isEditingEnabled;
EditorGUIUtility.labelWidth = 25f;
rect = new Rect(position.width / 2 + 20 + 70, position.y + 10, (width - 70) - padding, 18);
EditorGUI.PropertyField(rect, prop_SecondGlyphValueRecord.FindPropertyRelative("m_XPlacement"), new GUIContent("OX:"));
rect.y += 20;
EditorGUI.PropertyField(rect, prop_SecondGlyphValueRecord.FindPropertyRelative("m_YPlacement"), new GUIContent("OY:"));
rect.y += 20;
EditorGUI.PropertyField(rect, prop_SecondGlyphValueRecord.FindPropertyRelative("m_XAdvance"), new GUIContent("AX:"));
//rect.y += 20;
//EditorGUI.PropertyField(rect, prop_SecondGlyphAdjustment.FindPropertyRelative("m_YAdvance"), new GUIContent("AY"));
DrawGlyph((uint)prop_SecondGlyphIndex.intValue, new Rect(position.width / 2 + 20, position.y + 2, 64, 60), property);
}
else
{
rect = new Rect(position.width / 2 + 20, position.y, width / 2 * 0.8f - padding, 18);
EditorGUIUtility.labelWidth = 40f;
// Second Character Lookup
GUI.SetNextControlName("SecondCharacterField");
EditorGUI.BeginChangeCheck();
string secondCharacter = EditorGUI.TextField(rect, s_CharacterTextFieldLabel, m_SecondCharacter);
if (GUI.GetNameOfFocusedControl() == "SecondCharacterField")
{
if (ValidateInput(secondCharacter))
{
//Debug.Log("2nd Unicode value: [" + secondCharacter + "]");
uint unicode = GetUnicodeCharacter(secondCharacter);
// Lookup glyph index
TMP_SerializedPropertyHolder propertyHolder = property.serializedObject.targetObject as TMP_SerializedPropertyHolder;
TMP_FontAsset fontAsset = propertyHolder.fontAsset;
if (fontAsset != null)
{
prop_SecondGlyphIndex.intValue = (int)fontAsset.GetGlyphIndex(unicode);
propertyHolder.secondCharacter = unicode;
}
}
}
if (EditorGUI.EndChangeCheck())
m_SecondCharacter = secondCharacter;
// Second Glyph Index
rect.x += width / 2 * 0.8f;
EditorGUIUtility.labelWidth = 25f;
EditorGUI.BeginChangeCheck();
EditorGUI.PropertyField(rect, prop_SecondGlyphIndex, new GUIContent("ID:"));
if (EditorGUI.EndChangeCheck())
{
}
GUI.enabled = isEditingEnabled;
EditorGUIUtility.labelWidth = 25f;
rect = new Rect(position.width / 2 + 20, position.y + 20, width * 0.5f - padding, 18);
EditorGUI.PropertyField(rect, prop_SecondGlyphValueRecord.FindPropertyRelative("m_XPlacement"), new GUIContent("OX"));
rect.x += width * 0.5f;
EditorGUI.PropertyField(rect, prop_SecondGlyphValueRecord.FindPropertyRelative("m_YPlacement"), new GUIContent("OY"));
rect.x = position.width / 2 + 20;
rect.y += 20;
EditorGUI.PropertyField(rect, prop_SecondGlyphValueRecord.FindPropertyRelative("m_XAdvance"), new GUIContent("AX"));
//rect.x += width * 0.5f;
//EditorGUI.PropertyField(rect, prop_SecondGlyphAdjustment.FindPropertyRelative("m_YAdvance"), new GUIContent("AY"));
}
// Font Feature Lookup Flags
if (isSelectable)
{
EditorGUIUtility.labelWidth = 50f;
rect.width = position.width * 0.5f;
rect.x = rect.width + 16;
rect.y += 28;
FontFeatureLookupFlags flags = (FontFeatureLookupFlags)prop_FontFeatureLookupFlags.intValue;
EditorGUI.BeginChangeCheck();
flags = (FontFeatureLookupFlags)EditorGUI.EnumFlagsField(rect, new GUIContent("Options:"), flags);
if (EditorGUI.EndChangeCheck())
{
prop_FontFeatureLookupFlags.intValue = (int)flags;
}
}
}
bool ValidateInput(string source)
{
int length = string.IsNullOrEmpty(source) ? 0 : source.Length;
////Filter out unwanted characters.
Event evt = Event.current;
char c = evt.character;
if (c != '\0')
{
switch (length)
{
case 0:
break;
case 1:
if (source != m_PreviousInput)
return true;
if ((source[0] == '\\' && (c == 'u' || c == 'U')) == false)
evt.character = '\0';
break;
case 2:
case 3:
case 4:
case 5:
if ((c < '0' || c > '9') && (c < 'a' || c > 'f') && (c < 'A' || c > 'F'))
evt.character = '\0';
break;
case 6:
case 7:
case 8:
case 9:
if (source[1] == 'u' || (c < '0' || c > '9') && (c < 'a' || c > 'f') && (c < 'A' || c > 'F'))
evt.character = '\0';
// Validate input
if (length == 6 && source[1] == 'u' && source != m_PreviousInput)
return true;
break;
case 10:
if (source != m_PreviousInput)
return true;
evt.character = '\0';
break;
}
}
m_PreviousInput = source;
return false;
}
uint GetUnicodeCharacter (string source)
{
uint unicode;
if (source.Length == 1)
unicode = source[0];
else if (source.Length == 6)
unicode = (uint)TMP_TextUtilities.StringHexToInt(source.Replace("\\u", ""));
else
unicode = (uint)TMP_TextUtilities.StringHexToInt(source.Replace("\\U", ""));
return unicode;
}
void DrawGlyph(uint glyphIndex, Rect glyphDrawPosition, SerializedProperty property)
{
// Get a reference to the serialized object which can either be a TMP_FontAsset or FontAsset.
SerializedObject so = property.serializedObject;
if (so == null)
return;
if (m_GlyphLookupDictionary == null)
m_GlyphLookupDictionary = TMP_PropertyDrawerUtilities.GetGlyphProxyLookupDictionary(so);
// Try getting a reference to the glyph for the given glyph index.
if (!m_GlyphLookupDictionary.TryGetValue(glyphIndex, out GlyphProxy glyph))
return;
Texture2D atlasTexture;
if (TMP_PropertyDrawerUtilities.TryGetAtlasTextureFromSerializedObject(so, glyph.atlasIndex, out atlasTexture) == false)
return;
Material mat;
if (TMP_PropertyDrawerUtilities.TryGetMaterial(so, atlasTexture, out mat) == false)
return;
int padding = so.FindProperty("m_AtlasPadding").intValue;
GlyphRect glyphRect = glyph.glyphRect;
int glyphOriginX = glyphRect.x - padding;
int glyphOriginY = glyphRect.y - padding;
int glyphWidth = glyphRect.width + padding * 2;
int glyphHeight = glyphRect.height + padding * 2;
SerializedProperty faceInfoProperty = so.FindProperty("m_FaceInfo");
float ascentLine = faceInfoProperty.FindPropertyRelative("m_AscentLine").floatValue;
float descentLine = faceInfoProperty.FindPropertyRelative("m_DescentLine").floatValue;
float normalizedHeight = ascentLine - descentLine;
float scale = glyphDrawPosition.width / normalizedHeight;
// Compute the normalized texture coordinates
Rect texCoords = new Rect((float)glyphOriginX / atlasTexture.width, (float)glyphOriginY / atlasTexture.height, (float)glyphWidth / atlasTexture.width, (float)glyphHeight / atlasTexture.height);
if (Event.current.type == EventType.Repaint)
{
glyphDrawPosition.x += (glyphDrawPosition.width - glyphWidth * scale) / 2;
glyphDrawPosition.y += (glyphDrawPosition.height - glyphHeight * scale) / 2;
glyphDrawPosition.width = glyphWidth * scale;
glyphDrawPosition.height = glyphHeight * scale;
// Could switch to using the default material of the font asset which would require passing scale to the shader.
Graphics.DrawTexture(glyphDrawPosition, atlasTexture, texCoords, 0, 0, 0, 0, new Color(1f, 1f, 1f), mat);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d256fa541faf5d4409992c631adb98a1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,50 @@
using UnityEngine;
using UnityEngine.TextCore;
using UnityEditor;
using System.Collections;
namespace TMPro.EditorUtilities
{
[CustomPropertyDrawer(typeof(GlyphRect))]
public class GlyphRectPropertyDrawer : PropertyDrawer
{
private static readonly GUIContent k_GlyphRectLabel = new GUIContent("Glyph Rect", "A rectangle (rect) that represents the position of the glyph in the atlas texture.");
private static readonly GUIContent k_XPropertyLabel = new GUIContent("X:", "The X coordinate of the glyph in the atlas texture.");
private static readonly GUIContent k_YPropertyLabel = new GUIContent("Y:", "The Y coordinate of the glyph in the atlas texture.");
private static readonly GUIContent k_WidthPropertyLabel = new GUIContent("W:", "The width of the glyph in the atlas texture.");
private static readonly GUIContent k_HeightPropertyLabel = new GUIContent("H:", "The height of the glyph in the atlas texture.");
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
//EditorGUI.BeginProperty(position, label, property);
SerializedProperty prop_X = property.FindPropertyRelative("m_X");
SerializedProperty prop_Y = property.FindPropertyRelative("m_Y");
SerializedProperty prop_Width = property.FindPropertyRelative("m_Width");
SerializedProperty prop_Height = property.FindPropertyRelative("m_Height");
// We get Rect since a valid position may not be provided by the caller.
Rect rect = new Rect(position.x, position.y, position.width, 49);
EditorGUI.LabelField(new Rect(rect.x, rect.y - 2.5f, rect.width, 18), k_GlyphRectLabel);
EditorGUIUtility.labelWidth = 20f;
EditorGUIUtility.fieldWidth = 20f;
//GUI.enabled = false;
float width = (rect.width - 75f) / 4;
EditorGUI.PropertyField(new Rect(rect.x + width * 0, rect.y + 20, width - 5f, 18), prop_X, k_XPropertyLabel);
EditorGUI.PropertyField(new Rect(rect.x + width * 1, rect.y + 20, width - 5f, 18), prop_Y, k_YPropertyLabel);
EditorGUI.PropertyField(new Rect(rect.x + width * 2, rect.y + 20, width - 5f, 18), prop_Width, k_WidthPropertyLabel);
EditorGUI.PropertyField(new Rect(rect.x + width * 3, rect.y + 20, width - 5f, 18), prop_Height, k_HeightPropertyLabel);
//EditorGUI.EndProperty();
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return 45f;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8bc2b083b068f3546a9509c805e0541c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,123 @@
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.TextCore;
using UnityEngine.TextCore.LowLevel;
namespace TMPro.EditorUtilities
{
[CustomPropertyDrawer(typeof(LigatureSubstitutionRecord))]
class LigatureSubstitutionRecordPropertyDrawer : PropertyDrawer
{
private Dictionary<uint, GlyphProxy> m_GlyphLookupDictionary;
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
SerializedProperty prop_ComponentGlyphIDs = property.FindPropertyRelative("m_ComponentGlyphIDs");
int ComponentGlyphIDCount = prop_ComponentGlyphIDs.arraySize;
SerializedProperty prop_LigatureGlyphID = property.FindPropertyRelative("m_LigatureGlyphID");
// Refresh glyph proxy lookup dictionary if needed
if (TMP_PropertyDrawerUtilities.s_RefreshGlyphProxyLookup)
TMP_PropertyDrawerUtilities.RefreshGlyphProxyLookup(property.serializedObject);
Rect rect = position;
GUILayoutUtility.GetRect(position.width, 100);
EditorGUIUtility.labelWidth = 115;
EditorGUI.BeginChangeCheck();
int size = EditorGUI.DelayedIntField(new Rect(rect.x, position.y + 3, 130, rect.height), new GUIContent("Component Glyphs"), prop_ComponentGlyphIDs.arraySize);
if (EditorGUI.EndChangeCheck())
{
size = Mathf.Clamp(size, 0, 20);
prop_ComponentGlyphIDs.arraySize = size;
return;
}
// Spacing between glyphs
int glyphSpacing = 60;
// Draw Component Glyphs
for (int i = 0; i < ComponentGlyphIDCount; i++)
{
Rect componentGlyphPosition = new Rect(50 + (glyphSpacing * i), position.y + 24, 48, 48);
// Draw glyph
uint glyphIndex = (uint)prop_ComponentGlyphIDs.GetArrayElementAtIndex(i).intValue;
DrawGlyph(glyphIndex, componentGlyphPosition, property);
EditorGUI.BeginChangeCheck();
EditorGUI.DelayedIntField(new Rect(componentGlyphPosition.x - 13, componentGlyphPosition.y + 73, 40, EditorGUIUtility.singleLineHeight), prop_ComponentGlyphIDs.GetArrayElementAtIndex(i), GUIContent.none);
if (EditorGUI.EndChangeCheck())
{
}
}
// Draw Ligature glyph
Rect ligatureGlyphPosition = new Rect(50 + (glyphSpacing * ComponentGlyphIDCount + 1), position.y + 3, 95, EditorGUIUtility.singleLineHeight);
ligatureGlyphPosition.x = Mathf.Max(200, ligatureGlyphPosition.x);
EditorGUI.LabelField(ligatureGlyphPosition, new GUIContent("Ligature Glyph"));
DrawGlyph((uint)prop_LigatureGlyphID.intValue, new Rect(ligatureGlyphPosition.x + 37, ligatureGlyphPosition.y + 21, 48, 48), property);
EditorGUI.BeginChangeCheck();
EditorGUI.DelayedIntField(new Rect(ligatureGlyphPosition.x + 24, ligatureGlyphPosition.y + 94, 40, EditorGUIUtility.singleLineHeight), prop_LigatureGlyphID, GUIContent.none);
if (EditorGUI.EndChangeCheck())
{
}
}
void DrawGlyph(uint glyphIndex, Rect glyphDrawPosition, SerializedProperty property)
{
// Get a reference to the serialized object which can either be a TMP_FontAsset or FontAsset.
SerializedObject so = property.serializedObject;
if (so == null)
return;
if (m_GlyphLookupDictionary == null)
m_GlyphLookupDictionary = TMP_PropertyDrawerUtilities.GetGlyphProxyLookupDictionary(so);
// Try getting a reference to the glyph for the given glyph index.
if (!m_GlyphLookupDictionary.TryGetValue(glyphIndex, out GlyphProxy glyph))
return;
Texture2D atlasTexture;
if (TMP_PropertyDrawerUtilities.TryGetAtlasTextureFromSerializedObject(so, glyph.atlasIndex, out atlasTexture) == false)
return;
Material mat;
if (TMP_PropertyDrawerUtilities.TryGetMaterial(so, atlasTexture, out mat) == false)
return;
int padding = so.FindProperty("m_AtlasPadding").intValue;
GlyphRect glyphRect = glyph.glyphRect;
int glyphOriginX = glyphRect.x - padding;
int glyphOriginY = glyphRect.y - padding;
int glyphWidth = glyphRect.width + padding * 2;
int glyphHeight = glyphRect.height + padding * 2;
SerializedProperty faceInfoProperty = so.FindProperty("m_FaceInfo");
float ascentLine = faceInfoProperty.FindPropertyRelative("m_AscentLine").floatValue;
float descentLine = faceInfoProperty.FindPropertyRelative("m_DescentLine").floatValue;
float normalizedHeight = ascentLine - descentLine;
float scale = glyphDrawPosition.width / normalizedHeight;
// Compute the normalized texture coordinates
Rect texCoords = new Rect((float)glyphOriginX / atlasTexture.width, (float)glyphOriginY / atlasTexture.height, (float)glyphWidth / atlasTexture.width, (float)glyphHeight / atlasTexture.height);
if (Event.current.type == EventType.Repaint)
{
glyphDrawPosition.x += -(glyphWidth * scale / 2 - padding * scale);
glyphDrawPosition.y += glyphDrawPosition.height - glyph.metrics.horizontalBearingY * scale;
glyphDrawPosition.width = glyphWidth * scale;
glyphDrawPosition.height = glyphHeight * scale;
// Could switch to using the default material of the font asset which would require passing scale to the shader.
Graphics.DrawTexture(glyphDrawPosition, atlasTexture, texCoords, 0, 0, 0, 0, new Color(1f, 1f, 1f), mat);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7b6c2e51603686247afd5ab620c490e6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,209 @@
using UnityEngine;
using UnityEngine.TextCore;
using UnityEngine.TextCore.LowLevel;
using UnityEditor;
using System.Collections.Generic;
namespace TMPro.EditorUtilities
{
[CustomPropertyDrawer(typeof(TMP_Character))]
public class TMP_CharacterPropertyDrawer : PropertyDrawer
{
private Dictionary<uint, GlyphProxy> m_GlyphLookupDictionary;
int m_GlyphSelectedForEditing = -1;
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
SerializedProperty prop_Unicode = property.FindPropertyRelative("m_Unicode");
SerializedProperty prop_GlyphIndex = property.FindPropertyRelative("m_GlyphIndex");
SerializedProperty prop_Scale = property.FindPropertyRelative("m_Scale");
// Refresh glyph proxy lookup dictionary if needed
if (TMP_PropertyDrawerUtilities.s_RefreshGlyphProxyLookup)
TMP_PropertyDrawerUtilities.RefreshGlyphProxyLookup(property.serializedObject);
GUIStyle style = new GUIStyle(EditorStyles.label);
style.richText = true;
EditorGUIUtility.labelWidth = 40f;
EditorGUIUtility.fieldWidth = 50;
Rect rect = new Rect(position.x + 50, position.y, position.width, 49);
// Display non-editable fields
if (GUI.enabled == false)
{
int unicode = prop_Unicode.intValue;
EditorGUI.LabelField(new Rect(rect.x, rect.y, 120f, 18), new GUIContent("Unicode: <color=#FFFF80>0x" + unicode.ToString("X") + "</color>"), style);
EditorGUI.LabelField(new Rect(rect.x + 115, rect.y, 120f, 18), unicode <= 0xFFFF ? new GUIContent("UTF16: <color=#FFFF80>\\u" + unicode.ToString("X4") + "</color>") : new GUIContent("UTF32: <color=#FFFF80>\\U" + unicode.ToString("X8") + "</color>"), style);
EditorGUI.LabelField(new Rect(rect.x, rect.y + 18, 120, 18), new GUIContent("Glyph ID: <color=#FFFF80>" + prop_GlyphIndex.intValue + "</color>"), style);
EditorGUI.LabelField(new Rect(rect.x, rect.y + 36, 80, 18), new GUIContent("Scale: <color=#FFFF80>" + prop_Scale.floatValue + "</color>"), style);
// Draw Glyph (if exists)
DrawGlyph((uint)prop_GlyphIndex.intValue, new Rect(position.x, position.y, 48, 58), property);
}
else // Display editable fields
{
EditorGUIUtility.labelWidth = 55f;
GUI.SetNextControlName("Unicode Input");
EditorGUI.BeginChangeCheck();
string unicode = EditorGUI.TextField(new Rect(rect.x, rect.y, 120, 18), "Unicode:", prop_Unicode.intValue.ToString("X"));
if (GUI.GetNameOfFocusedControl() == "Unicode Input")
{
//Filter out unwanted characters.
char chr = Event.current.character;
if ((chr < '0' || chr > '9') && (chr < 'a' || chr > 'f') && (chr < 'A' || chr > 'F'))
{
Event.current.character = '\0';
}
}
if (EditorGUI.EndChangeCheck())
{
// Update Unicode value
prop_Unicode.intValue = TMP_TextUtilities.StringHexToInt(unicode);
}
// Cache current glyph index in case it needs to be restored if the new glyph index is invalid.
int currentGlyphIndex = prop_GlyphIndex.intValue;
EditorGUIUtility.labelWidth = 59f;
EditorGUI.BeginChangeCheck();
EditorGUI.DelayedIntField(new Rect(rect.x, rect.y + 18, 100, 18), prop_GlyphIndex, new GUIContent("Glyph ID:"));
if (EditorGUI.EndChangeCheck())
{
// Get a reference to the font asset
TMP_FontAsset fontAsset = property.serializedObject.targetObject as TMP_FontAsset;
// Make sure new glyph index is valid.
int elementIndex = fontAsset.glyphTable.FindIndex(item => item.index == prop_GlyphIndex.intValue);
if (elementIndex == -1)
prop_GlyphIndex.intValue = currentGlyphIndex;
else
fontAsset.IsFontAssetLookupTablesDirty = true;
}
int glyphIndex = prop_GlyphIndex.intValue;
// Reset glyph selection if new character has been selected.
if (GUI.enabled && m_GlyphSelectedForEditing != glyphIndex)
m_GlyphSelectedForEditing = -1;
// Display button to edit the glyph data.
if (GUI.Button(new Rect(rect.x + 120, rect.y + 18, 75, 18), new GUIContent("Edit Glyph")))
{
if (m_GlyphSelectedForEditing == -1)
m_GlyphSelectedForEditing = glyphIndex;
else
m_GlyphSelectedForEditing = -1;
// Button clicks should not result in potential change.
GUI.changed = false;
}
// Show the glyph property drawer if selected
if (glyphIndex == m_GlyphSelectedForEditing && GUI.enabled)
{
// Get a reference to the font asset
TMP_FontAsset fontAsset = property.serializedObject.targetObject as TMP_FontAsset;
if (fontAsset != null)
{
// Get the index of the glyph in the font asset glyph table.
int elementIndex = fontAsset.glyphTable.FindIndex(item => item.index == glyphIndex);
if (elementIndex != -1)
{
SerializedProperty prop_GlyphTable = property.serializedObject.FindProperty("m_GlyphTable");
SerializedProperty prop_Glyph = prop_GlyphTable.GetArrayElementAtIndex(elementIndex);
SerializedProperty prop_GlyphMetrics = prop_Glyph.FindPropertyRelative("m_Metrics");
SerializedProperty prop_GlyphRect = prop_Glyph.FindPropertyRelative("m_GlyphRect");
Rect newRect = EditorGUILayout.GetControlRect(false, 115);
EditorGUI.DrawRect(new Rect(newRect.x + 52, newRect.y - 20, newRect.width - 52, newRect.height - 5), new Color(0.1f, 0.1f, 0.1f, 0.45f));
EditorGUI.DrawRect(new Rect(newRect.x + 53, newRect.y - 19, newRect.width - 54, newRect.height - 7), new Color(0.3f, 0.3f, 0.3f, 0.8f));
// Display GlyphRect
newRect.x += 55;
newRect.y -= 18;
newRect.width += 5;
EditorGUI.PropertyField(newRect, prop_GlyphRect);
// Display GlyphMetrics
newRect.y += 45;
EditorGUI.PropertyField(newRect, prop_GlyphMetrics);
rect.y += 120;
}
}
}
EditorGUIUtility.labelWidth = 39f;
EditorGUI.PropertyField(new Rect(rect.x, rect.y + 36, 80, 18), prop_Scale, new GUIContent("Scale:"));
// Draw Glyph (if exists)
DrawGlyph((uint)prop_GlyphIndex.intValue, new Rect(position.x, position.y, 48, 58), property);
}
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return 58;
}
void DrawGlyph(uint glyphIndex, Rect glyphDrawPosition, SerializedProperty property)
{
// Get a reference to the serialized object which can either be a TMP_FontAsset or FontAsset.
SerializedObject so = property.serializedObject;
if (so == null)
return;
if (m_GlyphLookupDictionary == null)
m_GlyphLookupDictionary = TMP_PropertyDrawerUtilities.GetGlyphProxyLookupDictionary(so);
// Try getting a reference to the glyph for the given glyph index.
if (!m_GlyphLookupDictionary.TryGetValue(glyphIndex, out GlyphProxy glyph))
return;
Texture2D atlasTexture;
if (TMP_PropertyDrawerUtilities.TryGetAtlasTextureFromSerializedObject(so, glyph.atlasIndex, out atlasTexture) == false)
return;
Material mat;
if (TMP_PropertyDrawerUtilities.TryGetMaterial(so, atlasTexture, out mat) == false)
return;
int padding = so.FindProperty("m_AtlasPadding").intValue;
GlyphRect glyphRect = glyph.glyphRect;
int glyphOriginX = glyphRect.x - padding;
int glyphOriginY = glyphRect.y - padding;
int glyphWidth = glyphRect.width + padding * 2;
int glyphHeight = glyphRect.height + padding * 2;
SerializedProperty faceInfoProperty = so.FindProperty("m_FaceInfo");
float ascentLine = faceInfoProperty.FindPropertyRelative("m_AscentLine").floatValue;
float descentLine = faceInfoProperty.FindPropertyRelative("m_DescentLine").floatValue;
float normalizedHeight = ascentLine - descentLine;
float scale = glyphDrawPosition.width / normalizedHeight;
// Compute the normalized texture coordinates
Rect texCoords = new Rect((float)glyphOriginX / atlasTexture.width, (float)glyphOriginY / atlasTexture.height, (float)glyphWidth / atlasTexture.width, (float)glyphHeight / atlasTexture.height);
if (Event.current.type == EventType.Repaint)
{
glyphDrawPosition.x += (glyphDrawPosition.width - glyphWidth * scale) / 2;
glyphDrawPosition.y += (glyphDrawPosition.height - glyphHeight * scale) / 2;
glyphDrawPosition.width = glyphWidth * scale;
glyphDrawPosition.height = glyphHeight * scale;
// Could switch to using the default material of the font asset which would require passing scale to the shader.
Graphics.DrawTexture(glyphDrawPosition, atlasTexture, texCoords, 0, 0, 0, 0, new Color(1f, 1f, 1f), mat);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 01ada73c4792aba4c937ff5d92cce866
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,106 @@
using UnityEngine;
using UnityEngine.TextCore;
using UnityEditor;
using System.Collections.Generic;
namespace TMPro.EditorUtilities
{
[CustomPropertyDrawer(typeof(Glyph))]
public class TMP_GlyphPropertyDrawer : PropertyDrawer
{
private static readonly GUIContent k_ScaleLabel = new GUIContent("Scale:", "The scale of this glyph.");
private static readonly GUIContent k_AtlasIndexLabel = new GUIContent("Atlas Index:", "The index of the atlas texture that contains this glyph.");
private static readonly GUIContent k_ClassTypeLabel = new GUIContent("Class Type:", "The class definition type of this glyph.");
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
SerializedProperty prop_GlyphIndex = property.FindPropertyRelative("m_Index");
SerializedProperty prop_GlyphMetrics = property.FindPropertyRelative("m_Metrics");
SerializedProperty prop_GlyphRect = property.FindPropertyRelative("m_GlyphRect");
SerializedProperty prop_Scale = property.FindPropertyRelative("m_Scale");
SerializedProperty prop_AtlasIndex = property.FindPropertyRelative("m_AtlasIndex");
SerializedProperty prop_ClassDefinitionType = property.FindPropertyRelative("m_ClassDefinitionType");
GUIStyle style = new GUIStyle(EditorStyles.label);
style.richText = true;
Rect rect = new Rect(position.x + 70, position.y, position.width, 49);
float labelWidth = GUI.skin.label.CalcSize(new GUIContent("ID: " + prop_GlyphIndex.intValue)).x;
EditorGUI.LabelField(new Rect(position.x + (64 - labelWidth) / 2, position.y + 85, 64f, 18f), new GUIContent("ID: <color=#FFFF80>" + prop_GlyphIndex.intValue + "</color>"), style);
// We get Rect since a valid position may not be provided by the caller.
EditorGUI.PropertyField(new Rect(rect.x, rect.y, position.width, 49), prop_GlyphRect);
rect.y += 45;
EditorGUI.PropertyField(rect, prop_GlyphMetrics);
EditorGUIUtility.labelWidth = 40f;
EditorGUI.PropertyField(new Rect(rect.x, rect.y + 65, 75, 18), prop_Scale, k_ScaleLabel);
EditorGUIUtility.labelWidth = 70f;
EditorGUI.PropertyField(new Rect(rect.x + 85, rect.y + 65, 95, 18), prop_AtlasIndex, k_AtlasIndexLabel);
if (prop_ClassDefinitionType != null)
{
EditorGUIUtility.labelWidth = 70f;
float minWidth = Mathf.Max(90, rect.width - 270);
EditorGUI.PropertyField(new Rect(rect.x + 190, rect.y + 65, minWidth, 18), prop_ClassDefinitionType, k_ClassTypeLabel);
}
DrawGlyph(new Rect(position.x, position.y + 2, 64, 80), property);
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return 130f;
}
void DrawGlyph(Rect glyphDrawPosition, SerializedProperty property)
{
// Get a reference to the serialized object which can either be a TMP_FontAsset or FontAsset.
SerializedObject so = property.serializedObject;
if (so == null)
return;
Texture2D atlasTexture;
int atlasIndex = property.FindPropertyRelative("m_AtlasIndex").intValue;
int padding = so.FindProperty("m_AtlasPadding").intValue;
if (TMP_PropertyDrawerUtilities.TryGetAtlasTextureFromSerializedObject(so, atlasIndex, out atlasTexture) == false)
return;
Material mat;
if (TMP_PropertyDrawerUtilities.TryGetMaterial(so, atlasTexture, out mat) == false)
return;
GlyphRect glyphRect = TMP_PropertyDrawerUtilities.GetGlyphRectFromGlyphSerializedProperty(property);
int glyphOriginX = glyphRect.x - padding;
int glyphOriginY = glyphRect.y - padding;
int glyphWidth = glyphRect.width + padding * 2;
int glyphHeight = glyphRect.height + padding * 2;
SerializedProperty faceInfoProperty = so.FindProperty("m_FaceInfo");
float ascentLine = faceInfoProperty.FindPropertyRelative("m_AscentLine").floatValue;
float descentLine = faceInfoProperty.FindPropertyRelative("m_DescentLine").floatValue;
float normalizedHeight = ascentLine - descentLine;
float scale = glyphDrawPosition.width / normalizedHeight;
// Compute the normalized texture coordinates
Rect texCoords = new Rect((float)glyphOriginX / atlasTexture.width, (float)glyphOriginY / atlasTexture.height, (float)glyphWidth / atlasTexture.width, (float)glyphHeight / atlasTexture.height);
if (Event.current.type == EventType.Repaint)
{
glyphDrawPosition.x += (glyphDrawPosition.width - glyphWidth * scale) / 2;
glyphDrawPosition.y += (glyphDrawPosition.height - glyphHeight * scale) / 2;
glyphDrawPosition.width = glyphWidth * scale;
glyphDrawPosition.height = glyphHeight * scale;
// Could switch to using the default material of the font asset which would require passing scale to the shader.
Graphics.DrawTexture(glyphDrawPosition, atlasTexture, texCoords, 0, 0, 0, 0, new Color(1f, 1f, 1f), mat);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c4777500b5da6094e956c3d4f04de4db
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,236 @@
using UnityEngine;
using UnityEngine.TextCore;
using UnityEditor;
using System.Collections.Generic;
namespace TMPro.EditorUtilities
{
[CustomPropertyDrawer(typeof(MarkToBaseAdjustmentRecord))]
internal class TMP_MarkToBaseAdjustmentRecordPropertyDrawer : PropertyDrawer
{
private bool isEditingEnabled;
private bool isSelectable;
private Dictionary<uint, GlyphProxy> m_GlyphLookupDictionary;
private string m_PreviousInput;
//static GUIContent s_CharacterTextFieldLabel = new GUIContent("Char:", "Enter the character or its UTF16 or UTF32 Unicode character escape sequence. For UTF16 use \"\\uFF00\" and for UTF32 use \"\\UFF00FF00\" representation.");
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
SerializedProperty prop_BaseGlyphID = property.FindPropertyRelative("m_BaseGlyphID");
SerializedProperty prop_BaseGlyphAnchorPoint = property.FindPropertyRelative("m_BaseGlyphAnchorPoint");
SerializedProperty prop_MarkGlyphID = property.FindPropertyRelative("m_MarkGlyphID");
SerializedProperty prop_MarkAdjustmentRecord = property.FindPropertyRelative("m_MarkPositionAdjustment");
// Refresh glyph proxy lookup dictionary if needed
if (TMP_PropertyDrawerUtilities.s_RefreshGlyphProxyLookup)
TMP_PropertyDrawerUtilities.RefreshGlyphProxyLookup(property.serializedObject);
position.yMin += 2;
float width = position.width / 2;
float padding = 5.0f;
Rect rect;
isEditingEnabled = GUI.enabled;
isSelectable = label.text == "Selectable";
if (isSelectable)
GUILayoutUtility.GetRect(position.width, 75);
else
GUILayoutUtility.GetRect(position.width, 55);
GUIStyle style = new GUIStyle(EditorStyles.label) {richText = true};
// Base Glyph
GUI.enabled = isEditingEnabled;
if (isSelectable)
{
float labelWidth = GUI.skin.label.CalcSize(new GUIContent("ID: " + prop_BaseGlyphID.intValue)).x;
if (!isEditingEnabled)
{
EditorGUI.LabelField(new Rect(position.x + (64 - labelWidth) / 2, position.y + 60, 64f, 18f), new GUIContent("ID: <color=#FFFF80>" + prop_BaseGlyphID.intValue + "</color>"), style);
}
else
{
EditorGUI.BeginChangeCheck();
EditorGUIUtility.labelWidth = 25f;
EditorGUI.DelayedIntField(new Rect(position.x + (64 - labelWidth) / 2, position.y + 60, 64, 18), prop_BaseGlyphID, new GUIContent("ID:"));
if (EditorGUI.EndChangeCheck())
{
}
}
GUI.enabled = isEditingEnabled;
EditorGUIUtility.labelWidth = 30f;
rect = new Rect(position.x + 70, position.y + 10, (width - 70) - padding, 18);
EditorGUI.PropertyField(rect, prop_BaseGlyphAnchorPoint.FindPropertyRelative("m_XCoordinate"), new GUIContent("X:"));
rect.y += 20;
EditorGUI.PropertyField(rect, prop_BaseGlyphAnchorPoint.FindPropertyRelative("m_YCoordinate"), new GUIContent("Y:"));
DrawGlyph((uint)prop_BaseGlyphID.intValue, new Rect(position.x, position.y + 2, 64, 60), property);
}
// Mark Glyph
GUI.enabled = isEditingEnabled;
if (isSelectable)
{
float labelWidth = GUI.skin.label.CalcSize(new GUIContent("ID: " + prop_MarkGlyphID.intValue)).x;
if (!isEditingEnabled)
{
EditorGUI.LabelField(new Rect(position.width / 2 + 20 + (64 - labelWidth) / 2, position.y + 60, 64f, 18f), new GUIContent("ID: <color=#FFFF80>" + prop_MarkGlyphID.intValue + "</color>"), style);
}
else
{
EditorGUI.BeginChangeCheck();
EditorGUIUtility.labelWidth = 25f;
EditorGUI.DelayedIntField(new Rect(position.width / 2 + 20 + (64 - labelWidth) / 2, position.y + 60, 64, 18), prop_MarkGlyphID, new GUIContent("ID:"));
if (EditorGUI.EndChangeCheck())
{
}
}
GUI.enabled = isEditingEnabled;
EditorGUIUtility.labelWidth = 30f;
rect = new Rect(position.width / 2 + 20 + 70, position.y + 10, (width - 70) - padding, 18);
EditorGUI.PropertyField(rect, prop_MarkAdjustmentRecord.FindPropertyRelative("m_XPositionAdjustment"), new GUIContent("X:"));
rect.y += 20;
EditorGUI.PropertyField(rect, prop_MarkAdjustmentRecord.FindPropertyRelative("m_YPositionAdjustment"), new GUIContent("Y:"));
DrawGlyph((uint)prop_MarkGlyphID.intValue, new Rect(position.width / 2 + 20, position.y + 2, 64, 60), property);
}
}
bool ValidateInput(string source)
{
int length = string.IsNullOrEmpty(source) ? 0 : source.Length;
////Filter out unwanted characters.
Event evt = Event.current;
char c = evt.character;
if (c != '\0')
{
switch (length)
{
case 0:
break;
case 1:
if (source != m_PreviousInput)
return true;
if ((source[0] == '\\' && (c == 'u' || c == 'U')) == false)
evt.character = '\0';
break;
case 2:
case 3:
case 4:
case 5:
if ((c < '0' || c > '9') && (c < 'a' || c > 'f') && (c < 'A' || c > 'F'))
evt.character = '\0';
break;
case 6:
case 7:
case 8:
case 9:
if (source[1] == 'u' || (c < '0' || c > '9') && (c < 'a' || c > 'f') && (c < 'A' || c > 'F'))
evt.character = '\0';
// Validate input
if (length == 6 && source[1] == 'u' && source != m_PreviousInput)
return true;
break;
case 10:
if (source != m_PreviousInput)
return true;
evt.character = '\0';
break;
}
}
m_PreviousInput = source;
return false;
}
uint GetUnicodeCharacter (string source)
{
uint unicode;
if (source.Length == 1)
unicode = source[0];
else if (source.Length == 6)
unicode = (uint)TMP_TextUtilities.StringHexToInt(source.Replace("\\u", ""));
else
unicode = (uint)TMP_TextUtilities.StringHexToInt(source.Replace("\\U", ""));
return unicode;
}
void DrawGlyph(uint glyphIndex, Rect glyphDrawPosition, SerializedProperty property)
{
// Get a reference to the serialized object which can either be a TMP_FontAsset or FontAsset.
SerializedObject so = property.serializedObject;
if (so == null)
return;
if (m_GlyphLookupDictionary == null)
m_GlyphLookupDictionary = TMP_PropertyDrawerUtilities.GetGlyphProxyLookupDictionary(so);
// Try getting a reference to the glyph for the given glyph index.
if (!m_GlyphLookupDictionary.TryGetValue(glyphIndex, out GlyphProxy glyph))
return;
Texture2D atlasTexture;
if (TMP_PropertyDrawerUtilities.TryGetAtlasTextureFromSerializedObject(so, glyph.atlasIndex, out atlasTexture) == false)
return;
Material mat;
if (TMP_PropertyDrawerUtilities.TryGetMaterial(so, atlasTexture, out mat) == false)
return;
int padding = so.FindProperty("m_AtlasPadding").intValue;
GlyphRect glyphRect = glyph.glyphRect;
int glyphOriginX = glyphRect.x - padding;
int glyphOriginY = glyphRect.y - padding;
int glyphWidth = glyphRect.width + padding * 2;
int glyphHeight = glyphRect.height + padding * 2;
SerializedProperty faceInfoProperty = so.FindProperty("m_FaceInfo");
float ascentLine = faceInfoProperty.FindPropertyRelative("m_AscentLine").floatValue;
float descentLine = faceInfoProperty.FindPropertyRelative("m_DescentLine").floatValue;
float normalizedHeight = ascentLine - descentLine;
float scale = glyphDrawPosition.width / normalizedHeight;
// Compute the normalized texture coordinates
Rect texCoords = new Rect((float)glyphOriginX / atlasTexture.width, (float)glyphOriginY / atlasTexture.height, (float)glyphWidth / atlasTexture.width, (float)glyphHeight / atlasTexture.height);
if (Event.current.type == EventType.Repaint)
{
glyphDrawPosition.x += (glyphDrawPosition.width - glyphWidth * scale) / 2;
glyphDrawPosition.y += (glyphDrawPosition.height - glyphHeight * scale) / 2;
glyphDrawPosition.width = glyphWidth * scale;
glyphDrawPosition.height = glyphHeight * scale;
// Could switch to using the default material of the font asset which would require passing scale to the shader.
Graphics.DrawTexture(glyphDrawPosition, atlasTexture, texCoords, 0, 0, 0, 0, new Color(1f, 1f, 1f), mat);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 065a7fcf0d7286d418f3114ec18d1a2d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,237 @@
using UnityEngine;
using UnityEngine.TextCore;
using UnityEditor;
using System.Collections.Generic;
namespace TMPro.EditorUtilities
{
[CustomPropertyDrawer(typeof(MarkToMarkAdjustmentRecord))]
public class TMP_MarkToMarkAdjustmentRecordPropertyDrawer : PropertyDrawer
{
private bool isEditingEnabled;
private bool isSelectable;
private Dictionary<uint, GlyphProxy> m_GlyphLookupDictionary;
private string m_PreviousInput;
static GUIContent s_CharacterTextFieldLabel = new GUIContent("Char:", "Enter the character or its UTF16 or UTF32 Unicode character escape sequence. For UTF16 use \"\\uFF00\" and for UTF32 use \"\\UFF00FF00\" representation.");
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
SerializedProperty prop_BaseGlyphID = property.FindPropertyRelative("m_BaseMarkGlyphID");
SerializedProperty prop_BaseGlyphAnchorPoint = property.FindPropertyRelative("m_BaseMarkGlyphAnchorPoint");
SerializedProperty prop_MarkGlyphID = property.FindPropertyRelative("m_CombiningMarkGlyphID");
SerializedProperty prop_MarkAdjustmentRecord = property.FindPropertyRelative("m_CombiningMarkPositionAdjustment");
// Refresh glyph proxy lookup dictionary if needed
if (TMP_PropertyDrawerUtilities.s_RefreshGlyphProxyLookup)
TMP_PropertyDrawerUtilities.RefreshGlyphProxyLookup(property.serializedObject);
position.yMin += 2;
float width = position.width / 2;
float padding = 5.0f;
Rect rect;
isEditingEnabled = GUI.enabled;
isSelectable = label.text == "Selectable";
if (isSelectable)
GUILayoutUtility.GetRect(position.width, 75);
else
GUILayoutUtility.GetRect(position.width, 55);
GUIStyle style = new GUIStyle(EditorStyles.label) {richText = true};
// Base Glyph
GUI.enabled = isEditingEnabled;
if (isSelectable)
{
float labelWidth = GUI.skin.label.CalcSize(new GUIContent("ID: " + prop_BaseGlyphID.intValue)).x;
if (!isEditingEnabled)
{
EditorGUI.LabelField(new Rect(position.x + (64 - labelWidth) / 2, position.y + 60, 64f, 18f), new GUIContent("ID: <color=#FFFF80>" + prop_BaseGlyphID.intValue + "</color>"), style);
}
else
{
EditorGUI.BeginChangeCheck();
EditorGUIUtility.labelWidth = 25f;
EditorGUI.DelayedIntField(new Rect(position.x + (64 - labelWidth) / 2, position.y + 60, 64, 18), prop_BaseGlyphID, new GUIContent("ID:"));
if (EditorGUI.EndChangeCheck())
{
}
}
GUI.enabled = isEditingEnabled;
EditorGUIUtility.labelWidth = 30f;
rect = new Rect(position.x + 70, position.y + 10, (width - 70) - padding, 18);
EditorGUI.PropertyField(rect, prop_BaseGlyphAnchorPoint.FindPropertyRelative("m_XCoordinate"), new GUIContent("X:"));
rect.y += 20;
EditorGUI.PropertyField(rect, prop_BaseGlyphAnchorPoint.FindPropertyRelative("m_YCoordinate"), new GUIContent("Y:"));
DrawGlyph((uint)prop_BaseGlyphID.intValue, new Rect(position.x, position.y + 2, 64, 60), property);
}
// Mark Glyph
GUI.enabled = isEditingEnabled;
if (isSelectable)
{
float labelWidth = GUI.skin.label.CalcSize(new GUIContent("ID: " + prop_MarkGlyphID.intValue)).x;
if (!isEditingEnabled)
{
EditorGUI.LabelField(new Rect(position.width / 2 + 20 + (64 - labelWidth) / 2, position.y + 60, 64f, 18f), new GUIContent("ID: <color=#FFFF80>" + prop_MarkGlyphID.intValue + "</color>"), style);
}
else
{
EditorGUI.BeginChangeCheck();
EditorGUIUtility.labelWidth = 25f;
EditorGUI.DelayedIntField(new Rect(position.width / 2 + 20 + (64 - labelWidth) / 2, position.y + 60, 64, 18), prop_MarkGlyphID, new GUIContent("ID:"));
if (EditorGUI.EndChangeCheck())
{
}
}
GUI.enabled = isEditingEnabled;
EditorGUIUtility.labelWidth = 30f;
rect = new Rect(position.width / 2 + 20 + 70, position.y + 10, (width - 70) - padding, 18);
EditorGUI.PropertyField(rect, prop_MarkAdjustmentRecord.FindPropertyRelative("m_XPositionAdjustment"), new GUIContent("X:"));
rect.y += 20;
EditorGUI.PropertyField(rect, prop_MarkAdjustmentRecord.FindPropertyRelative("m_YPositionAdjustment"), new GUIContent("Y:"));
DrawGlyph((uint)prop_MarkGlyphID.intValue, new Rect(position.width / 2 + 20, position.y + 2, 64, 60), property);
}
}
bool ValidateInput(string source)
{
int length = string.IsNullOrEmpty(source) ? 0 : source.Length;
////Filter out unwanted characters.
Event evt = Event.current;
char c = evt.character;
if (c != '\0')
{
switch (length)
{
case 0:
break;
case 1:
if (source != m_PreviousInput)
return true;
if ((source[0] == '\\' && (c == 'u' || c == 'U')) == false)
evt.character = '\0';
break;
case 2:
case 3:
case 4:
case 5:
if ((c < '0' || c > '9') && (c < 'a' || c > 'f') && (c < 'A' || c > 'F'))
evt.character = '\0';
break;
case 6:
case 7:
case 8:
case 9:
if (source[1] == 'u' || (c < '0' || c > '9') && (c < 'a' || c > 'f') && (c < 'A' || c > 'F'))
evt.character = '\0';
// Validate input
if (length == 6 && source[1] == 'u' && source != m_PreviousInput)
return true;
break;
case 10:
if (source != m_PreviousInput)
return true;
evt.character = '\0';
break;
}
}
m_PreviousInput = source;
return false;
}
uint GetUnicodeCharacter (string source)
{
uint unicode;
if (source.Length == 1)
unicode = source[0];
else if (source.Length == 6)
unicode = (uint)TMP_TextUtilities.StringHexToInt(source.Replace("\\u", ""));
else
unicode = (uint)TMP_TextUtilities.StringHexToInt(source.Replace("\\U", ""));
return unicode;
}
void DrawGlyph(uint glyphIndex, Rect glyphDrawPosition, SerializedProperty property)
{
// Get a reference to the serialized object which can either be a TMP_FontAsset or FontAsset.
SerializedObject so = property.serializedObject;
if (so == null)
return;
if (m_GlyphLookupDictionary == null)
m_GlyphLookupDictionary = TMP_PropertyDrawerUtilities.GetGlyphProxyLookupDictionary(so);
// Try getting a reference to the glyph for the given glyph index.
if (!m_GlyphLookupDictionary.TryGetValue(glyphIndex, out GlyphProxy glyph))
return;
Texture2D atlasTexture;
if (TMP_PropertyDrawerUtilities.TryGetAtlasTextureFromSerializedObject(so, glyph.atlasIndex, out atlasTexture) == false)
return;
Material mat;
if (TMP_PropertyDrawerUtilities.TryGetMaterial(so, atlasTexture, out mat) == false)
return;
int padding = so.FindProperty("m_AtlasPadding").intValue;
GlyphRect glyphRect = glyph.glyphRect;
int glyphOriginX = glyphRect.x - padding;
int glyphOriginY = glyphRect.y - padding;
int glyphWidth = glyphRect.width + padding * 2;
int glyphHeight = glyphRect.height + padding * 2;
SerializedProperty faceInfoProperty = so.FindProperty("m_FaceInfo");
float ascentLine = faceInfoProperty.FindPropertyRelative("m_AscentLine").floatValue;
float descentLine = faceInfoProperty.FindPropertyRelative("m_DescentLine").floatValue;
float normalizedHeight = ascentLine - descentLine;
float scale = glyphDrawPosition.width / normalizedHeight;
// Compute the normalized texture coordinates
Rect texCoords = new Rect((float)glyphOriginX / atlasTexture.width, (float)glyphOriginY / atlasTexture.height, (float)glyphWidth / atlasTexture.width, (float)glyphHeight / atlasTexture.height);
if (Event.current.type == EventType.Repaint)
{
glyphDrawPosition.x += (glyphDrawPosition.width - glyphWidth * scale) / 2;
glyphDrawPosition.y += (glyphDrawPosition.height - glyphHeight * scale) / 2;
glyphDrawPosition.width = glyphWidth * scale;
glyphDrawPosition.height = glyphHeight * scale;
// Could switch to using the default material of the font asset which would require passing scale to the shader.
Graphics.DrawTexture(glyphDrawPosition, atlasTexture, texCoords, 0, 0, 0, 0, new Color(1f, 1f, 1f), mat);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 149e85704eb73624ba2d705408274f3e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,180 @@
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.TextCore;
using UnityEngine.TextCore.LowLevel;
namespace TMPro.EditorUtilities
{
internal struct GlyphProxy
{
public uint index;
public GlyphRect glyphRect;
public GlyphMetrics metrics;
public int atlasIndex;
}
internal static class TMP_PropertyDrawerUtilities
{
internal static bool s_RefreshGlyphProxyLookup;
private static Dictionary<SerializedObject, Dictionary<uint, GlyphProxy>> s_GlyphProxyLookups = new Dictionary<SerializedObject, Dictionary<uint, GlyphProxy>>();
internal static void ClearGlyphProxyLookups()
{
s_GlyphProxyLookups.Clear();
}
internal static void RefreshGlyphProxyLookup(SerializedObject so)
{
if (!s_GlyphProxyLookups.ContainsKey(so))
return;
Dictionary<uint, GlyphProxy> glyphProxyLookup = s_GlyphProxyLookups[so];
glyphProxyLookup.Clear();
PopulateGlyphProxyLookupDictionary(so, glyphProxyLookup);
s_RefreshGlyphProxyLookup = false;
}
internal static Dictionary<uint, GlyphProxy> GetGlyphProxyLookupDictionary(SerializedObject so)
{
if (s_GlyphProxyLookups.ContainsKey(so))
return s_GlyphProxyLookups[so];
Dictionary<uint, GlyphProxy> glyphProxyLookup = new Dictionary<uint, GlyphProxy>();
PopulateGlyphProxyLookupDictionary(so, glyphProxyLookup);
s_GlyphProxyLookups.Add(so, glyphProxyLookup);
return glyphProxyLookup;
}
/// <summary>
///
/// </summary>
/// <param name="so"></param>
/// <param name="lookupDictionary"></param>
static void PopulateGlyphProxyLookupDictionary(SerializedObject so, Dictionary<uint, GlyphProxy> lookupDictionary)
{
if (lookupDictionary == null)
return;
// Get reference to serialized property for the glyph table
SerializedProperty glyphTable = so.FindProperty("m_GlyphTable");
for (int i = 0; i < glyphTable.arraySize; i++)
{
SerializedProperty glyphProperty = glyphTable.GetArrayElementAtIndex(i);
GlyphProxy proxy = GetGlyphProxyFromSerializedProperty(glyphProperty);
lookupDictionary.Add(proxy.index, proxy);
}
}
internal static GlyphRect GetGlyphRectFromGlyphSerializedProperty(SerializedProperty property)
{
SerializedProperty glyphRectProp = property.FindPropertyRelative("m_GlyphRect");
GlyphRect glyphRect = new GlyphRect();
glyphRect.x = glyphRectProp.FindPropertyRelative("m_X").intValue;
glyphRect.y = glyphRectProp.FindPropertyRelative("m_Y").intValue;
glyphRect.width = glyphRectProp.FindPropertyRelative("m_Width").intValue;
glyphRect.height = glyphRectProp.FindPropertyRelative("m_Height").intValue;
return glyphRect;
}
internal static GlyphMetrics GetGlyphMetricsFromGlyphSerializedProperty(SerializedProperty property)
{
SerializedProperty glyphMetricsProperty = property.FindPropertyRelative("m_Metrics");
GlyphMetrics glyphMetrics = new GlyphMetrics();
glyphMetrics.horizontalBearingX = glyphMetricsProperty.FindPropertyRelative("m_HorizontalBearingX").floatValue;
glyphMetrics.horizontalBearingY = glyphMetricsProperty.FindPropertyRelative("m_HorizontalBearingY").floatValue;
glyphMetrics.horizontalAdvance = glyphMetricsProperty.FindPropertyRelative("m_HorizontalAdvance").floatValue;
glyphMetrics.width = glyphMetricsProperty.FindPropertyRelative("m_Width").floatValue;
glyphMetrics.height = glyphMetricsProperty.FindPropertyRelative("m_Height").floatValue;
return glyphMetrics;
}
/// <summary>
///
/// </summary>
/// <param name="property"></param>
/// <returns></returns>
internal static GlyphProxy GetGlyphProxyFromSerializedProperty(SerializedProperty property)
{
GlyphProxy proxy = new GlyphProxy();
proxy.index = (uint)property.FindPropertyRelative("m_Index").intValue;
proxy.glyphRect = GetGlyphRectFromGlyphSerializedProperty(property);
proxy.metrics = GetGlyphMetricsFromGlyphSerializedProperty(property);
proxy.atlasIndex = property.FindPropertyRelative("m_AtlasIndex").intValue;
return proxy;
}
/// <summary>
///
/// </summary>
/// <param name="serializedObject"></param>
/// <param name="glyphIndex"></param>
/// <param name="texture"></param>
/// <returns></returns>
internal static bool TryGetAtlasTextureFromSerializedObject(SerializedObject serializedObject, int glyphIndex, out Texture2D texture)
{
SerializedProperty atlasTextureProperty = serializedObject.FindProperty("m_AtlasTextures");
texture = atlasTextureProperty.GetArrayElementAtIndex(glyphIndex).objectReferenceValue as Texture2D;
if (texture == null)
return false;
return true;
}
/// <summary>
///
/// </summary>
/// <param name="serializedObject"></param>
/// <param name="texture"></param>
/// <param name="mat"></param>
/// <returns></returns>
internal static bool TryGetMaterial(SerializedObject serializedObject, Texture2D texture, out Material mat)
{
GlyphRenderMode atlasRenderMode = (GlyphRenderMode)serializedObject.FindProperty("m_AtlasRenderMode").intValue;
if (((GlyphRasterModes)atlasRenderMode & GlyphRasterModes.RASTER_MODE_BITMAP) == GlyphRasterModes.RASTER_MODE_BITMAP)
{
#if TEXTCORE_FONT_ENGINE_1_5_OR_NEWER
if (atlasRenderMode == GlyphRenderMode.COLOR || atlasRenderMode == GlyphRenderMode.COLOR_HINTED)
mat = TMP_FontAssetEditor.internalRGBABitmapMaterial;
else
mat = TMP_FontAssetEditor.internalBitmapMaterial;
#else
mat = TMP_FontAssetEditor.internalBitmapMaterial;
#endif
if (mat == null)
return false;
mat.mainTexture = texture;
mat.color = Color.white;
}
else
{
mat = TMP_FontAssetEditor.internalSDFMaterial;
if (mat == null)
return false;
int padding = serializedObject.FindProperty("m_AtlasPadding").intValue;
mat.mainTexture = texture;
mat.SetFloat(ShaderUtilities.ID_GradientScale, padding + 1);
}
return true;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 371a2245f9a9ff344997fec3609bf73e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,212 @@
using UnityEngine;
using UnityEngine.TextCore;
using UnityEditor;
using System.Collections.Generic;
namespace TMPro.EditorUtilities
{
[CustomPropertyDrawer(typeof(TMP_SpriteCharacter))]
public class TMP_SpriteCharacterPropertyDrawer : PropertyDrawer
{
int m_GlyphSelectedForEditing = -1;
private Dictionary<uint, GlyphProxy> m_GlyphLookupDictionary;
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
SerializedProperty prop_SpriteName = property.FindPropertyRelative("m_Name");
SerializedProperty prop_SpriteUnicode = property.FindPropertyRelative("m_Unicode");
SerializedProperty prop_SpriteGlyphIndex = property.FindPropertyRelative("m_GlyphIndex");
SerializedProperty prop_SpriteScale = property.FindPropertyRelative("m_Scale");
GUIStyle style = new GUIStyle(EditorStyles.label);
style.richText = true;
EditorGUIUtility.labelWidth = 40f;
EditorGUIUtility.fieldWidth = 50;
Rect rect = new Rect(position.x + 60, position.y, position.width, 49);
// Display non-editable fields
if (GUI.enabled == false)
{
// Sprite Character Index
int spriteCharacterIndex;
int.TryParse(property.displayName.Split(' ')[1], out spriteCharacterIndex);
EditorGUI.LabelField(new Rect(rect.x, rect.y, 75f, 18), new GUIContent("Index: <color=#FFFF80>" + spriteCharacterIndex + "</color>"), style);
EditorGUI.LabelField(new Rect(rect.x + 75f, rect.y, 120f, 18), new GUIContent("Unicode: <color=#FFFF80>0x" + prop_SpriteUnicode.intValue.ToString("X") + "</color>"), style);
EditorGUI.LabelField(new Rect(rect.x + 195f, rect.y, rect.width - 255, 18), new GUIContent("Name: <color=#FFFF80>" + prop_SpriteName.stringValue + "</color>"), style);
EditorGUI.LabelField(new Rect(rect.x, rect.y + 18, 120, 18), new GUIContent("Glyph ID: <color=#FFFF80>" + prop_SpriteGlyphIndex.intValue + "</color>"), style);
// Draw Sprite Glyph (if exists)
DrawSpriteGlyph((uint)prop_SpriteGlyphIndex.intValue, position, property);
EditorGUI.LabelField(new Rect(rect.x, rect.y + 36, 80, 18), new GUIContent("Scale: <color=#FFFF80>" + prop_SpriteScale.floatValue + "</color>"), style);
}
else // Display editable fields
{
// Get a reference to the underlying Sprite Asset
TMP_SpriteAsset spriteAsset = property.serializedObject.targetObject as TMP_SpriteAsset;
// Sprite Character Index
int spriteCharacterIndex;
int.TryParse(property.displayName.Split(' ')[1], out spriteCharacterIndex);
EditorGUI.LabelField(new Rect(rect.x, rect.y, 75f, 18), new GUIContent("Index: <color=#FFFF80>" + spriteCharacterIndex + "</color>"), style);
EditorGUIUtility.labelWidth = 55f;
GUI.SetNextControlName("Unicode Input");
EditorGUI.BeginChangeCheck();
string unicode = EditorGUI.DelayedTextField(new Rect(rect.x + 75f, rect.y, 120, 18), "Unicode:", prop_SpriteUnicode.intValue.ToString("X"));
if (GUI.GetNameOfFocusedControl() == "Unicode Input")
{
//Filter out unwanted characters.
char chr = Event.current.character;
if ((chr < '0' || chr > '9') && (chr < 'a' || chr > 'f') && (chr < 'A' || chr > 'F'))
{
Event.current.character = '\0';
}
}
if (EditorGUI.EndChangeCheck())
{
// Update Unicode value
prop_SpriteUnicode.intValue = TMP_TextUtilities.StringHexToInt(unicode);
spriteAsset.m_IsSpriteAssetLookupTablesDirty = true;
}
EditorGUIUtility.labelWidth = 41f;
EditorGUI.BeginChangeCheck();
EditorGUI.DelayedTextField(new Rect(rect.x + 195f, rect.y, rect.width - 255, 18), prop_SpriteName, new GUIContent("Name:"));
if (EditorGUI.EndChangeCheck())
{
spriteAsset.m_IsSpriteAssetLookupTablesDirty = true;
}
EditorGUIUtility.labelWidth = 59f;
EditorGUI.BeginChangeCheck();
EditorGUI.DelayedIntField(new Rect(rect.x, rect.y + 18, 100, 18), prop_SpriteGlyphIndex, new GUIContent("Glyph ID:"));
if (EditorGUI.EndChangeCheck())
{
spriteAsset.m_IsSpriteAssetLookupTablesDirty = true;
}
// Draw Sprite Glyph (if exists)
DrawSpriteGlyph((uint)prop_SpriteGlyphIndex.intValue, position, property);
int glyphIndex = prop_SpriteGlyphIndex.intValue;
// Reset glyph selection if new character has been selected.
if (GUI.enabled && m_GlyphSelectedForEditing != glyphIndex)
m_GlyphSelectedForEditing = -1;
// Display button to edit the glyph data.
if (GUI.Button(new Rect(rect.x + 120, rect.y + 18, 75, 18), new GUIContent("Edit Glyph")))
{
if (m_GlyphSelectedForEditing == -1)
m_GlyphSelectedForEditing = glyphIndex;
else
m_GlyphSelectedForEditing = -1;
// Button clicks should not result in potential change.
GUI.changed = false;
}
// Show the glyph property drawer if selected
if (glyphIndex == m_GlyphSelectedForEditing && GUI.enabled)
{
if (spriteAsset != null)
{
// Lookup glyph and draw glyph (if available)
int elementIndex = spriteAsset.spriteGlyphTable.FindIndex(item => item.index == glyphIndex);
if (elementIndex != -1)
{
// Get a reference to the Sprite Glyph Table
SerializedProperty prop_SpriteGlyphTable = property.serializedObject.FindProperty("m_GlyphTable");
SerializedProperty prop_SpriteGlyph = prop_SpriteGlyphTable.GetArrayElementAtIndex(elementIndex);
SerializedProperty prop_GlyphMetrics = prop_SpriteGlyph.FindPropertyRelative("m_Metrics");
SerializedProperty prop_GlyphRect = prop_SpriteGlyph.FindPropertyRelative("m_GlyphRect");
Rect newRect = EditorGUILayout.GetControlRect(false, 115);
EditorGUI.DrawRect(new Rect(newRect.x + 62, newRect.y - 20, newRect.width - 62, newRect.height - 5), new Color(0.1f, 0.1f, 0.1f, 0.45f));
EditorGUI.DrawRect(new Rect(newRect.x + 63, newRect.y - 19, newRect.width - 64, newRect.height - 7), new Color(0.3f, 0.3f, 0.3f, 0.8f));
// Display GlyphRect
newRect.x += 65;
newRect.y -= 18;
newRect.width += 5;
EditorGUI.PropertyField(newRect, prop_GlyphRect);
// Display GlyphMetrics
newRect.y += 45;
EditorGUI.PropertyField(newRect, prop_GlyphMetrics);
rect.y += 120;
}
}
}
EditorGUIUtility.labelWidth = 39f;
EditorGUI.PropertyField(new Rect(rect.x, rect.y + 36, 80, 18), prop_SpriteScale, new GUIContent("Scale:"));
}
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return 58;
}
void DrawSpriteGlyph(uint glyphIndex, Rect position, SerializedProperty property)
{
if (m_GlyphLookupDictionary == null)
m_GlyphLookupDictionary = TMP_PropertyDrawerUtilities.GetGlyphProxyLookupDictionary(property.serializedObject);
// Try getting a reference to the glyph for the given glyph index.
if (!m_GlyphLookupDictionary.TryGetValue(glyphIndex, out GlyphProxy glyph))
return;
GlyphRect glyphRect = glyph.glyphRect;
// Get a reference to the sprite texture
Texture tex = property.serializedObject.FindProperty("spriteSheet").objectReferenceValue as Texture;
if (tex == null)
{
Debug.LogWarning("Please assign a valid Sprite Atlas texture to the [" + property.serializedObject.targetObject.name + "] Sprite Asset.", property.serializedObject.targetObject);
return;
}
Vector2 spriteTexPosition = new Vector2(position.x, position.y);
Vector2 spriteSize = new Vector2(48, 48);
Vector2 alignmentOffset = new Vector2((58 - spriteSize.x) / 2, (58 - spriteSize.y) / 2);
float x = glyphRect.x;
float y = glyphRect.y;
float spriteWidth = glyphRect.width;
float spriteHeight = glyphRect.height;
if (spriteWidth >= spriteHeight)
{
spriteSize.y = spriteHeight * spriteSize.x / spriteWidth;
spriteTexPosition.y += (spriteSize.x - spriteSize.y) / 2;
}
else
{
spriteSize.x = spriteWidth * spriteSize.y / spriteHeight;
spriteTexPosition.x += (spriteSize.y - spriteSize.x) / 2;
}
// Compute the normalized texture coordinates
Rect texCoords = new Rect(x / tex.width, y / tex.height, spriteWidth / tex.width, spriteHeight / tex.height);
GUI.DrawTextureWithTexCoords(new Rect(spriteTexPosition.x + alignmentOffset.x, spriteTexPosition.y + alignmentOffset.y, spriteSize.x, spriteSize.y), tex, texCoords, true);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 37cff9f5a86ae494c8cb04423580480d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,88 @@
using UnityEngine;
using UnityEngine.TextCore;
using UnityEditor;
using System.Collections.Generic;
namespace TMPro.EditorUtilities
{
[CustomPropertyDrawer(typeof(TMP_SpriteGlyph))]
public class TMP_SpriteGlyphPropertyDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
SerializedProperty prop_GlyphIndex = property.FindPropertyRelative("m_Index");
SerializedProperty prop_GlyphMetrics = property.FindPropertyRelative("m_Metrics");
SerializedProperty prop_GlyphRect = property.FindPropertyRelative("m_GlyphRect");
SerializedProperty prop_Scale = property.FindPropertyRelative("m_Scale");
SerializedProperty prop_AtlasIndex = property.FindPropertyRelative("m_AtlasIndex");
GUIStyle style = new GUIStyle(EditorStyles.label);
style.richText = true;
Rect rect = new Rect(position.x + 70, position.y, position.width, 49);
// Draw GlyphRect
EditorGUI.PropertyField(rect, prop_GlyphRect);
// Draw GlyphMetrics
rect.y += 45;
EditorGUI.PropertyField(rect, prop_GlyphMetrics);
EditorGUIUtility.labelWidth = 40f;
EditorGUI.PropertyField(new Rect(rect.x, rect.y + 65, 75, 18), prop_Scale, new GUIContent("Scale:"));
EditorGUIUtility.labelWidth = 74f;
EditorGUI.PropertyField(new Rect(rect.x + 85, rect.y + 65, 95, 18), prop_AtlasIndex, new GUIContent("Atlas Index:"));
DrawGlyph(position, property);
int spriteCharacterIndex;
int.TryParse(property.displayName.Split(' ')[1], out spriteCharacterIndex);
EditorGUI.LabelField(new Rect(position.x, position.y + 5, 64f, 18f), new GUIContent("#" + spriteCharacterIndex), style);
float labelWidthID = GUI.skin.label.CalcSize(new GUIContent("ID: " + prop_GlyphIndex.intValue)).x;
EditorGUI.LabelField(new Rect(position.x + (64 - labelWidthID) / 2, position.y + 110, 64f, 18f), new GUIContent("ID: <color=#FFFF80>" + prop_GlyphIndex.intValue + "</color>"), style);
}
void DrawGlyph(Rect position, SerializedProperty property)
{
// Get a reference to the sprite texture
Texture tex = property.serializedObject.FindProperty("spriteSheet").objectReferenceValue as Texture;
// Return if we don't have a texture assigned to the sprite asset.
if (tex == null)
{
Debug.LogWarning("Please assign a valid Sprite Atlas texture to the [" + property.serializedObject.targetObject.name + "] Sprite Asset.", property.serializedObject.targetObject);
return;
}
Vector2 spriteTexPosition = new Vector2(position.x, position.y);
Vector2 spriteSize = new Vector2(65, 65);
GlyphRect glyphRect = TMP_PropertyDrawerUtilities.GetGlyphRectFromGlyphSerializedProperty(property);
if (glyphRect.width >= glyphRect.height)
{
spriteSize.y = glyphRect.height * spriteSize.x / glyphRect.width;
spriteTexPosition.y += (spriteSize.x - spriteSize.y) / 2;
}
else
{
spriteSize.x = glyphRect.width * spriteSize.y / glyphRect.height;
spriteTexPosition.x += (spriteSize.y - spriteSize.x) / 2;
}
// Compute the normalized texture coordinates
Rect texCoords = new Rect((float)glyphRect.x / tex.width, (float)glyphRect.y / tex.height, (float)glyphRect.width / tex.width, (float)glyphRect.height / tex.height);
GUI.DrawTextureWithTexCoords(new Rect(spriteTexPosition.x + 5, spriteTexPosition.y + 32f, spriteSize.x, spriteSize.y), tex, texCoords, true);
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return 130f;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 056819c66570ca54cadb72330a354050
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,273 @@
using UnityEngine;
using UnityEditor;
namespace TMPro.EditorUtilities
{
[CustomPropertyDrawer(typeof(TextAlignmentOptions))]
public class TMP_TextAlignmentDrawer : PropertyDrawer
{
const int k_AlignmentButtonWidth = 24;
const int k_AlignmentButtonHeight = 20;
const int k_WideViewWidth = 504;
const int k_ControlsSpacing = 6;
const int k_GroupWidth = k_AlignmentButtonWidth * 6;
static readonly int k_TextAlignmentHash = "DoTextAligmentControl".GetHashCode();
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUIUtility.currentViewWidth > k_WideViewWidth ? k_AlignmentButtonHeight : k_AlignmentButtonHeight * 2 + 3;
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
var id = GUIUtility.GetControlID(k_TextAlignmentHash, FocusType.Keyboard, position);
EditorGUI.BeginProperty(position, label, property);
{
var controlArea = EditorGUI.PrefixLabel(position, id, label);
var horizontalAligment = new Rect(controlArea.x, controlArea.y, k_GroupWidth, k_AlignmentButtonHeight);
var verticalAligment = new Rect(!(EditorGUIUtility.currentViewWidth > k_WideViewWidth) ? controlArea.x : horizontalAligment.xMax + k_ControlsSpacing, !(EditorGUIUtility.currentViewWidth > k_WideViewWidth) ? controlArea.y + k_AlignmentButtonHeight + 3 : controlArea.y, k_GroupWidth, k_AlignmentButtonHeight);
EditorGUI.BeginChangeCheck();
var selectedHorizontal = DoHorizontalAligmentControl(horizontalAligment, property);
var selectedVertical = DoVerticalAligmentControl(verticalAligment, property);
if (EditorGUI.EndChangeCheck())
{
var value = (0x1 << selectedHorizontal) | (0x100 << selectedVertical);
property.intValue = value;
}
}
EditorGUI.EndProperty();
}
static int DoHorizontalAligmentControl(Rect position, SerializedProperty alignment)
{
var selected = TMP_EditorUtility.GetHorizontalAlignmentGridValue(alignment.intValue);
var values = new bool[6];
values[selected] = true;
if (alignment.hasMultipleDifferentValues)
{
foreach (var obj in alignment.serializedObject.targetObjects)
{
var text = obj as TMP_Text;
if (text != null)
{
values[TMP_EditorUtility.GetHorizontalAlignmentGridValue((int)text.alignment)] = true;
}
}
}
position.width = k_AlignmentButtonWidth;
for (var i = 0; i < values.Length; i++)
{
var oldValue = values[i];
var newValue = TMP_EditorUtility.EditorToggle(position, oldValue, TMP_UIStyleManager.alignContentA[i], i == 0 ? TMP_UIStyleManager.alignmentButtonLeft : (i == 5 ? TMP_UIStyleManager.alignmentButtonRight : TMP_UIStyleManager.alignmentButtonMid));
if (newValue != oldValue)
{
selected = i;
}
position.x += position.width;
}
return selected;
}
static int DoVerticalAligmentControl(Rect position, SerializedProperty alignment)
{
var selected = TMP_EditorUtility.GetVerticalAlignmentGridValue(alignment.intValue);
var values = new bool[6];
values[selected] = true;
if (alignment.hasMultipleDifferentValues)
{
foreach (var obj in alignment.serializedObject.targetObjects)
{
var text = obj as TMP_Text;
if (text != null)
{
values[TMP_EditorUtility.GetVerticalAlignmentGridValue((int)text.alignment)] = true;
}
}
}
position.width = k_AlignmentButtonWidth;
for (var i = 0; i < values.Length; i++)
{
var oldValue = values[i];
var newValue = TMP_EditorUtility.EditorToggle(position, oldValue, TMP_UIStyleManager.alignContentB[i], i == 0 ? TMP_UIStyleManager.alignmentButtonLeft : (i == 5 ? TMP_UIStyleManager.alignmentButtonRight : TMP_UIStyleManager.alignmentButtonMid));
if (newValue != oldValue)
{
selected = i;
}
position.x += position.width;
}
return selected;
}
}
[CustomPropertyDrawer(typeof(HorizontalAlignmentOptions))]
public class TMP_HorizontalAlignmentDrawer : PropertyDrawer
{
const int k_AlignmentButtonWidth = 24;
const int k_AlignmentButtonHeight = 20;
const int k_WideViewWidth = 504;
const int k_ControlsSpacing = 6;
const int k_GroupWidth = k_AlignmentButtonWidth * 6;
static readonly int k_TextAlignmentHash = "DoTextAligmentControl".GetHashCode();
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUIUtility.currentViewWidth > k_WideViewWidth ? k_AlignmentButtonHeight : k_AlignmentButtonHeight * 2 + 3;
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
var id = GUIUtility.GetControlID(k_TextAlignmentHash, FocusType.Keyboard, position);
EditorGUI.BeginProperty(position, label, property);
{
var controlArea = EditorGUI.PrefixLabel(position, id, label);
var horizontalAligment = new Rect(controlArea.x, controlArea.y, k_GroupWidth, k_AlignmentButtonHeight);
//var verticalAligment = new Rect(!(EditorGUIUtility.currentViewWidth > k_WideViewWidth) ? controlArea.x : horizontalAligment.xMax + k_ControlsSpacing, !(EditorGUIUtility.currentViewWidth > k_WideViewWidth) ? controlArea.y + k_AlignmentButtonHeight + 3 : controlArea.y, k_GroupWidth, k_AlignmentButtonHeight);
EditorGUI.BeginChangeCheck();
var selectedHorizontal = DoHorizontalAligmentControl(horizontalAligment, property);
if (EditorGUI.EndChangeCheck())
{
var value = 0x1 << selectedHorizontal;
property.intValue = value;
}
}
EditorGUI.EndProperty();
}
static int DoHorizontalAligmentControl(Rect position, SerializedProperty alignment)
{
var selected = TMP_EditorUtility.GetHorizontalAlignmentGridValue(alignment.intValue);
var values = new bool[6];
values[selected] = true;
if (alignment.hasMultipleDifferentValues)
{
foreach (var obj in alignment.serializedObject.targetObjects)
{
var text = obj as TMP_Text;
if (text != null)
{
values[TMP_EditorUtility.GetHorizontalAlignmentGridValue((int)text.horizontalAlignment)] = true;
}
}
}
position.width = k_AlignmentButtonWidth;
for (var i = 0; i < values.Length; i++)
{
var oldValue = values[i];
var newValue = TMP_EditorUtility.EditorToggle(position, oldValue, TMP_UIStyleManager.alignContentA[i], i == 0 ? TMP_UIStyleManager.alignmentButtonLeft : (i == 5 ? TMP_UIStyleManager.alignmentButtonRight : TMP_UIStyleManager.alignmentButtonMid));
if (newValue != oldValue)
{
selected = i;
}
position.x += position.width;
}
return selected;
}
}
[CustomPropertyDrawer(typeof(VerticalAlignmentOptions))]
public class TMP_VerticalAlignmentDrawer : PropertyDrawer
{
const int k_AlignmentButtonWidth = 24;
const int k_AlignmentButtonHeight = 20;
const int k_WideViewWidth = 504;
const int k_ControlsSpacing = 6;
const int k_GroupWidth = k_AlignmentButtonWidth * 6;
static readonly int k_TextAlignmentHash = "DoTextAligmentControl".GetHashCode();
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUIUtility.currentViewWidth > k_WideViewWidth ? k_AlignmentButtonHeight : k_AlignmentButtonHeight * 2 + 3;
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
var id = GUIUtility.GetControlID(k_TextAlignmentHash, FocusType.Keyboard, position);
EditorGUI.BeginProperty(position, label, property);
{
var controlArea = EditorGUI.PrefixLabel(position, id, label);
var horizontalAligment = new Rect(controlArea.x, controlArea.y, k_GroupWidth, k_AlignmentButtonHeight);
var verticalAligment = new Rect(!(EditorGUIUtility.currentViewWidth > k_WideViewWidth) ? controlArea.x : horizontalAligment.xMax + k_ControlsSpacing, !(EditorGUIUtility.currentViewWidth > k_WideViewWidth) ? controlArea.y + k_AlignmentButtonHeight + 3 : controlArea.y, k_GroupWidth, k_AlignmentButtonHeight);
EditorGUI.BeginChangeCheck();
//var selectedHorizontal = DoHorizontalAligmentControl(horizontalAligment, property);
var selectedVertical = DoVerticalAligmentControl(verticalAligment, property);
if (EditorGUI.EndChangeCheck())
{
var value = 0x100 << selectedVertical;
property.intValue = value;
}
}
EditorGUI.EndProperty();
}
static int DoVerticalAligmentControl(Rect position, SerializedProperty alignment)
{
var selected = TMP_EditorUtility.GetVerticalAlignmentGridValue(alignment.intValue);
var values = new bool[6];
values[selected] = true;
if (alignment.hasMultipleDifferentValues)
{
foreach (var obj in alignment.serializedObject.targetObjects)
{
var text = obj as TMP_Text;
if (text != null)
{
values[TMP_EditorUtility.GetVerticalAlignmentGridValue((int)text.verticalAlignment)] = true;
}
}
}
position.width = k_AlignmentButtonWidth;
for (var i = 0; i < values.Length; i++)
{
var oldValue = values[i];
var newValue = TMP_EditorUtility.EditorToggle(position, oldValue, TMP_UIStyleManager.alignContentB[i], i == 0 ? TMP_UIStyleManager.alignmentButtonLeft : (i == 5 ? TMP_UIStyleManager.alignmentButtonRight : TMP_UIStyleManager.alignmentButtonMid));
if (newValue != oldValue)
{
selected = i;
}
position.x += position.width;
}
return selected;
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: c55a64c7570474f47a94abe39ebfef04
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 91950f78729ab144aa36e94690b28fad
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,697 @@
using UnityEngine;
using UnityEditor;
namespace TMPro.EditorUtilities
{
/// <summary>Base class for TextMesh Pro shader GUIs.</summary>
public abstract class TMP_BaseShaderGUI : ShaderGUI
{
/// <summary>Representation of a #pragma shader_feature.</summary>
/// <description>It is assumed that the first feature option is for no keyword (underscores).</description>
protected class ShaderFeature
{
public string undoLabel;
public GUIContent label;
/// <summary>The keyword labels, for display. Include the no-keyword as the first option.</summary>
public GUIContent[] keywordLabels;
/// <summary>The shader keywords. Exclude the no-keyword option.</summary>
public string[] keywords;
int m_State;
public bool Active
{
get { return m_State >= 0; }
}
public int State
{
get { return m_State; }
}
public void ReadState(Material material)
{
for (int i = 0; i < keywords.Length; i++)
{
if (material.IsKeywordEnabled(keywords[i]))
{
m_State = i;
return;
}
}
m_State = -1;
}
public void SetActive(bool active, Material material)
{
m_State = active ? 0 : -1;
SetStateKeywords(material);
}
public void DoPopup(MaterialEditor editor, Material material)
{
EditorGUI.BeginChangeCheck();
int selection = EditorGUILayout.Popup(label, m_State + 1, keywordLabels);
if (EditorGUI.EndChangeCheck())
{
m_State = selection - 1;
editor.RegisterPropertyChangeUndo(undoLabel);
SetStateKeywords(material);
}
}
void SetStateKeywords(Material material)
{
for (int i = 0; i < keywords.Length; i++)
{
if (i == m_State)
{
material.EnableKeyword(keywords[i]);
}
else
{
material.DisableKeyword(keywords[i]);
}
}
}
}
static GUIContent s_TempLabel = new GUIContent();
protected static bool s_DebugExtended;
static int s_UndoRedoCount, s_LastSeenUndoRedoCount;
static float[][] s_TempFloats =
{
null, new float[1], new float[2], new float[3], new float[4]
};
protected static GUIContent[] s_XywhVectorLabels =
{
new GUIContent("X"),
new GUIContent("Y"),
new GUIContent("W", "Width"),
new GUIContent("H", "Height")
};
protected static GUIContent[] s_LbrtVectorLabels =
{
new GUIContent("L", "Left"),
new GUIContent("B", "Bottom"),
new GUIContent("R", "Right"),
new GUIContent("T", "Top")
};
protected static GUIContent[] s_CullingTypeLabels =
{
new GUIContent("Off"),
new GUIContent("Front"),
new GUIContent("Back")
};
static TMP_BaseShaderGUI()
{
// Keep track of how many undo/redo events happened.
Undo.undoRedoPerformed += () => s_UndoRedoCount += 1;
}
bool m_IsNewGUI = true;
float m_DragAndDropMinY;
protected MaterialEditor m_Editor;
protected Material m_Material;
private int m_ShaderID;
protected MaterialProperty[] m_Properties;
void PrepareGUI()
{
m_IsNewGUI = false;
ShaderUtilities.GetShaderPropertyIDs();
// New GUI just got constructed. This happens in response to a selection,
// but also after undo/redo events.
if (s_LastSeenUndoRedoCount != s_UndoRedoCount)
{
// There's been at least one undo/redo since the last time this GUI got constructed.
// Maybe the undo/redo was for this material? Assume that is was.
TMPro_EventManager.ON_MATERIAL_PROPERTY_CHANGED(true, m_Material);
}
s_LastSeenUndoRedoCount = s_UndoRedoCount;
}
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
m_Editor = materialEditor;
m_Material = materialEditor.target as Material;
this.m_Properties = properties;
if (m_IsNewGUI)
PrepareGUI();
DoDragAndDropBegin();
EditorGUI.BeginChangeCheck();
DoGUI();
if (EditorGUI.EndChangeCheck())
{
TMPro_EventManager.ON_MATERIAL_PROPERTY_CHANGED(true, m_Material);
}
DoDragAndDropEnd();
}
public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader)
{
base.AssignNewShaderToMaterial(material, oldShader, newShader);
TMPro_EventManager.ON_MATERIAL_PROPERTY_CHANGED(true, material);
}
/// <summary>Override this method to create the specific shader GUI.</summary>
protected abstract void DoGUI();
static string[] s_PanelStateLabel = new string[] { "\t- <i>Click to collapse</i> -", "\t- <i>Click to expand</i> -" };
protected bool BeginPanel(string panel, bool expanded)
{
EditorGUI.indentLevel = 0;
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
Rect r = EditorGUI.IndentedRect(GUILayoutUtility.GetRect(20, 18));
r.x += 20;
r.width += 6;
bool enabled = GUI.enabled;
GUI.enabled = true;
expanded = TMP_EditorUtility.EditorToggle(r, expanded, new GUIContent(panel), TMP_UIStyleManager.panelTitle);
r.width -= 30;
EditorGUI.LabelField(r, new GUIContent(expanded ? s_PanelStateLabel[0] : s_PanelStateLabel[1]), TMP_UIStyleManager.rightLabel);
GUI.enabled = enabled;
EditorGUI.indentLevel += 1;
EditorGUI.BeginDisabledGroup(false);
return expanded;
}
protected bool BeginPanel(string panel, ShaderFeature feature, bool expanded, bool readState = true)
{
EditorGUI.indentLevel = 0;
if (readState)
{
feature.ReadState(m_Material);
}
EditorGUI.BeginChangeCheck();
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
GUILayout.BeginHorizontal();
Rect r = EditorGUI.IndentedRect(GUILayoutUtility.GetRect(20, 20, GUILayout.Width(20f)));
bool active = EditorGUI.Toggle(r, feature.Active);
if (EditorGUI.EndChangeCheck())
{
m_Editor.RegisterPropertyChangeUndo(feature.undoLabel);
feature.SetActive(active, m_Material);
}
r = EditorGUI.IndentedRect(GUILayoutUtility.GetRect(20, 18));
r.width += 6;
bool enabled = GUI.enabled;
GUI.enabled = true;
expanded = TMP_EditorUtility.EditorToggle(r, expanded, new GUIContent(panel), TMP_UIStyleManager.panelTitle);
r.width -= 10;
EditorGUI.LabelField(r, new GUIContent(expanded ? s_PanelStateLabel[0] : s_PanelStateLabel[1]), TMP_UIStyleManager.rightLabel);
GUI.enabled = enabled;
GUILayout.EndHorizontal();
EditorGUI.indentLevel += 1;
EditorGUI.BeginDisabledGroup(!active);
return expanded;
}
public void EndPanel()
{
EditorGUI.EndDisabledGroup();
EditorGUI.indentLevel -= 1;
EditorGUILayout.EndVertical();
}
MaterialProperty BeginProperty(string name)
{
MaterialProperty property = FindProperty(name, m_Properties);
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = property.hasMixedValue;
m_Editor.BeginAnimatedCheck(Rect.zero, property);
return property;
}
bool EndProperty()
{
m_Editor.EndAnimatedCheck();
EditorGUI.showMixedValue = false;
return EditorGUI.EndChangeCheck();
}
protected void DoPopup(string name, string label, GUIContent[] options)
{
MaterialProperty property = BeginProperty(name);
s_TempLabel.text = label;
int index = EditorGUILayout.Popup(s_TempLabel, (int)property.floatValue, options);
if (EndProperty())
{
property.floatValue = index;
}
}
protected void DoCubeMap(string name, string label)
{
DoTexture(name, label, typeof(Cubemap));
}
protected void DoTexture2D(string name, string label, bool withTilingOffset = false, string[] speedNames = null)
{
DoTexture(name, label, typeof(Texture2D), withTilingOffset, speedNames);
}
void DoTexture(string name, string label, System.Type type, bool withTilingOffset = false, string[] speedNames = null)
{
float objFieldSize = 60f;
bool smallLayout = EditorGUIUtility.currentViewWidth <= 330f && (withTilingOffset || speedNames != null);
float controlHeight = smallLayout ? objFieldSize * 2 : objFieldSize;
MaterialProperty property = FindProperty(name, m_Properties);
m_Editor.BeginAnimatedCheck(Rect.zero, property);
Rect rect = EditorGUILayout.GetControlRect(true, controlHeight);
float totalWidth = rect.width;
rect.width = EditorGUIUtility.labelWidth + objFieldSize;
rect.height = objFieldSize;
s_TempLabel.text = label;
EditorGUI.BeginChangeCheck();
Object tex = EditorGUI.ObjectField(rect, s_TempLabel, property.textureValue, type, false);
if (EditorGUI.EndChangeCheck())
{
property.textureValue = tex as Texture;
}
float additionalHeight = controlHeight - objFieldSize;
float xOffset = smallLayout ? rect.width - objFieldSize : rect.width;
rect.y += additionalHeight;
rect.x += xOffset;
rect.width = totalWidth - xOffset;
rect.height = EditorGUIUtility.singleLineHeight;
if (withTilingOffset)
{
DoTilingOffset(rect, property);
rect.y += (rect.height + 2f) * 2f;
}
m_Editor.EndAnimatedCheck();
if (speedNames != null)
{
DoUVSpeed(rect, speedNames);
}
}
void DoTilingOffset(Rect rect, MaterialProperty property)
{
float labelWidth = EditorGUIUtility.labelWidth;
int indentLevel = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
EditorGUIUtility.labelWidth = Mathf.Min(40f, rect.width * 0.40f);
Vector4 vector = property.textureScaleAndOffset;
bool changed = false;
float[] values = s_TempFloats[2];
s_TempLabel.text = "Tiling";
Rect vectorRect = EditorGUI.PrefixLabel(rect, s_TempLabel);
values[0] = vector.x;
values[1] = vector.y;
EditorGUI.BeginChangeCheck();
EditorGUI.MultiFloatField(vectorRect, s_XywhVectorLabels, values);
if (EditorGUI.EndChangeCheck())
{
vector.x = values[0];
vector.y = values[1];
changed = true;
}
rect.y += rect.height + 2f;
s_TempLabel.text = "Offset";
vectorRect = EditorGUI.PrefixLabel(rect, s_TempLabel);
values[0] = vector.z;
values[1] = vector.w;
EditorGUI.BeginChangeCheck();
EditorGUI.MultiFloatField(vectorRect, s_XywhVectorLabels, values);
if (EditorGUI.EndChangeCheck())
{
vector.z = values[0];
vector.w = values[1];
changed = true;
}
if (changed)
{
property.textureScaleAndOffset = vector;
}
EditorGUIUtility.labelWidth = labelWidth;
EditorGUI.indentLevel = indentLevel;
}
protected void DoUVSpeed(Rect rect, string[] names)
{
float labelWidth = EditorGUIUtility.labelWidth;
int indentLevel = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
EditorGUIUtility.labelWidth = Mathf.Min(40f, rect.width * 0.40f);
s_TempLabel.text = "Speed";
rect = EditorGUI.PrefixLabel(rect, s_TempLabel);
EditorGUIUtility.labelWidth = 10f;
rect.width = rect.width * 0.5f - 2f;
if (names.Length == 1)
{
DoFloat2(rect, names[0]);
}
else
{
DoFloat(rect, names[0], "X");
rect.x += rect.width + 4f;
DoFloat(rect, names[1], "Y");
}
EditorGUIUtility.labelWidth = labelWidth;
EditorGUI.indentLevel = indentLevel;
}
protected void DoToggle(string name, string label)
{
MaterialProperty property = BeginProperty(name);
s_TempLabel.text = label;
bool value = EditorGUILayout.Toggle(s_TempLabel, property.floatValue == 1f);
if (EndProperty())
{
property.floatValue = value ? 1f : 0f;
}
}
protected void DoFloat(string name, string label)
{
MaterialProperty property = BeginProperty(name);
Rect rect = EditorGUILayout.GetControlRect();
rect.width = EditorGUIUtility.labelWidth + 55f;
s_TempLabel.text = label;
float value = EditorGUI.FloatField(rect, s_TempLabel, property.floatValue);
if (EndProperty())
{
property.floatValue = value;
}
}
protected void DoColor(string name, string label)
{
MaterialProperty property = BeginProperty(name);
s_TempLabel.text = label;
Color value = EditorGUI.ColorField(EditorGUILayout.GetControlRect(), s_TempLabel, property.colorValue, false, true, false);
if (EndProperty())
{
property.colorValue = value;
}
}
void DoFloat(Rect rect, string name, string label)
{
MaterialProperty property = BeginProperty(name);
s_TempLabel.text = label;
float value = EditorGUI.FloatField(rect, s_TempLabel, property.floatValue);
if (EndProperty())
{
property.floatValue = value;
}
}
void DoFloat2(Rect rect, string name)
{
MaterialProperty property = BeginProperty(name);
float x = EditorGUI.FloatField(rect, "X", property.vectorValue.x);
rect.x += rect.width + 4f;
float y = EditorGUI.FloatField(rect, "Y", property.vectorValue.y);
if (EndProperty())
{
property.vectorValue = new Vector2(x, y);
}
}
protected void DoOffset(string name, string label)
{
MaterialProperty property = BeginProperty(name);
s_TempLabel.text = label;
Vector2 value = EditorGUI.Vector2Field(EditorGUILayout.GetControlRect(), s_TempLabel, property.vectorValue);
if (EndProperty())
{
property.vectorValue = value;
}
}
protected void DoSlider(string name, string label)
{
MaterialProperty property = BeginProperty(name);
Vector2 range = property.rangeLimits;
s_TempLabel.text = label;
float value = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, property.floatValue, range.x, range.y);
if (EndProperty())
{
property.floatValue = value;
}
}
protected void DoSlider(string name, Vector2 range, string label)
{
MaterialProperty property = BeginProperty(name);
s_TempLabel.text = label;
float value = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, property.floatValue, range.x, range.y);
if (EndProperty())
{
property.floatValue = value;
}
}
protected void DoSlider(string propertyName, string propertyField, string label)
{
MaterialProperty property = BeginProperty(propertyName);
Vector2 range = property.rangeLimits;
s_TempLabel.text = label;
Vector4 value = property.vectorValue;
switch (propertyField)
{
case "X":
value.x = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.x, range.x, range.y);
break;
case "Y":
value.y = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.y, range.x, range.y);
break;
case "Z":
value.z = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.z, range.x, range.y);
break;
case "W":
value.w = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.w, range.x, range.y);
break;
}
if (EndProperty())
{
property.vectorValue = value;
}
}
protected void DoSlider(string propertyName, string propertyField, Vector2 range, string label)
{
MaterialProperty property = BeginProperty(propertyName);
s_TempLabel.text = label;
Vector4 value = property.vectorValue;
switch (propertyField)
{
case "X":
value.x = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.x, range.x, range.y);
break;
case "Y":
value.y = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.y, range.x, range.y);
break;
case "Z":
value.z = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.z, range.x, range.y);
break;
case "W":
value.w = EditorGUI.Slider(EditorGUILayout.GetControlRect(), s_TempLabel, value.w, range.x, range.y);
break;
}
if (EndProperty())
{
property.vectorValue = value;
}
}
protected void DoVector2(string name, string label)
{
MaterialProperty property = BeginProperty(name);
s_TempLabel.text = label;
Vector4 value = EditorGUILayout.Vector3Field(s_TempLabel, property.vectorValue);
if (EndProperty())
{
property.vectorValue = value;
}
}
protected void DoVector3(string name, string label)
{
MaterialProperty property = BeginProperty(name);
s_TempLabel.text = label;
Vector4 value = EditorGUILayout.Vector3Field(s_TempLabel, property.vectorValue);
if (EndProperty())
{
property.vectorValue = value;
}
}
protected void DoVector(string name, string label, GUIContent[] subLabels)
{
MaterialProperty property = BeginProperty(name);
Rect rect = EditorGUILayout.GetControlRect();
s_TempLabel.text = label;
rect = EditorGUI.PrefixLabel(rect, s_TempLabel);
Vector4 vector = property.vectorValue;
float[] values = s_TempFloats[subLabels.Length];
for (int i = 0; i < subLabels.Length; i++)
{
values[i] = vector[i];
}
EditorGUI.MultiFloatField(rect, subLabels, values);
if (EndProperty())
{
for (int i = 0; i < subLabels.Length; i++)
{
vector[i] = values[i];
}
property.vectorValue = vector;
}
}
bool IsNewShader()
{
if (m_Material == null)
return false;
int currentShaderID = m_Material.shader.GetInstanceID();
if (m_ShaderID == currentShaderID)
return false;
m_ShaderID = currentShaderID;
return true;
}
void DoDragAndDropBegin()
{
m_DragAndDropMinY = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true)).y;
}
void DoDragAndDropEnd()
{
Rect rect = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true));
Event evt = Event.current;
if (evt.type == EventType.DragUpdated)
{
DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
evt.Use();
}
else if (evt.type == EventType.DragPerform && Rect.MinMaxRect(rect.xMin, m_DragAndDropMinY, rect.xMax, rect.yMax).Contains(evt.mousePosition))
{
DragAndDrop.AcceptDrag();
evt.Use();
Material droppedMaterial = DragAndDrop.objectReferences[0] as Material;
if (droppedMaterial && droppedMaterial != m_Material)
{
PerformDrop(droppedMaterial);
}
}
else if (evt.type == EventType.DragExited)
{
if (IsNewShader())
TMPro_EventManager.ON_MATERIAL_PROPERTY_CHANGED(true, m_Material);
}
}
void PerformDrop(Material droppedMaterial)
{
Texture droppedTex = droppedMaterial.GetTexture(ShaderUtilities.ID_MainTex);
if (!droppedTex)
{
return;
}
Texture currentTex = m_Material.GetTexture(ShaderUtilities.ID_MainTex);
TMP_FontAsset requiredFontAsset = null;
if (droppedTex != currentTex)
{
requiredFontAsset = TMP_EditorUtility.FindMatchingFontAsset(droppedMaterial);
if (!requiredFontAsset)
{
return;
}
}
foreach (GameObject o in Selection.gameObjects)
{
if (requiredFontAsset)
{
TMP_Text textComponent = o.GetComponent<TMP_Text>();
if (textComponent)
{
Undo.RecordObject(textComponent, "Font Asset Change");
textComponent.font = requiredFontAsset;
}
}
TMPro_EventManager.ON_DRAG_AND_DROP_MATERIAL_CHANGED(o, m_Material, droppedMaterial);
EditorUtility.SetDirty(o);
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 438efd46088d408d8a53f707fa68d976
timeCreated: 1469844810
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,93 @@
using UnityEngine;
using UnityEditor;
namespace TMPro.EditorUtilities
{
public class TMP_BitmapShaderGUI : TMP_BaseShaderGUI
{
static bool s_Face = true;
protected override void DoGUI()
{
s_Face = BeginPanel("Face", s_Face);
if (s_Face)
{
DoFacePanel();
}
EndPanel();
s_DebugExtended = BeginPanel("Debug Settings", s_DebugExtended);
if (s_DebugExtended)
{
DoDebugPanel();
}
EndPanel();
}
void DoFacePanel()
{
EditorGUI.indentLevel += 1;
if (m_Material.HasProperty(ShaderUtilities.ID_FaceTex))
{
DoColor("_FaceColor", "Color");
DoTexture2D("_FaceTex", "Texture", true);
}
else
{
DoColor("_Color", "Color");
DoSlider("_DiffusePower", "Diffuse Power");
}
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoDebugPanel()
{
EditorGUI.indentLevel += 1;
DoTexture2D("_MainTex", "Font Atlas");
if (m_Material.HasProperty(ShaderUtilities.ID_VertexOffsetX))
{
if (m_Material.HasProperty(ShaderUtilities.ID_Padding))
{
EditorGUILayout.Space();
DoFloat("_Padding", "Padding");
}
EditorGUILayout.Space();
DoFloat("_VertexOffsetX", "Offset X");
DoFloat("_VertexOffsetY", "Offset Y");
}
if (m_Material.HasProperty(ShaderUtilities.ID_MaskSoftnessX))
{
EditorGUILayout.Space();
DoFloat("_MaskSoftnessX", "Softness X");
DoFloat("_MaskSoftnessY", "Softness Y");
DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels);
}
if (m_Material.HasProperty(ShaderUtilities.ID_StencilID))
{
EditorGUILayout.Space();
DoFloat("_Stencil", "Stencil ID");
DoFloat("_StencilComp", "Stencil Comp");
}
if (m_Material.HasProperty(ShaderUtilities.ShaderTag_CullMode))
{
EditorGUILayout.Space();
DoPopup("_CullMode", "Cull Mode", s_CullingTypeLabels);
}
EditorGUILayout.Space();
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 806de5a9211448c8b65c8435ebb48dd4
timeCreated: 1469998850
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,47 @@
using UnityEditor;
using UnityEngine;
using System.IO;
namespace TMPro.EditorUtilities
{
public static class TMP_ColorGradientAssetMenu
{
[MenuItem("Assets/Create/TextMeshPro/Color Gradient", false, 220)]
internal static void CreateColorGradient(MenuCommand context)
{
string filePath;
if (Selection.assetGUIDs.Length == 0)
filePath = "Assets/New TMP Color Gradient.asset";
else
filePath = AssetDatabase.GUIDToAssetPath(Selection.assetGUIDs[0]);
if (Directory.Exists(filePath))
{
filePath += "/New TMP Color Gradient.asset";
}
else
{
filePath = Path.GetDirectoryName(filePath) + "/New TMP Color Gradient.asset";
}
filePath = AssetDatabase.GenerateUniqueAssetPath(filePath);
// Create new Color Gradient Asset.
TMP_ColorGradient colorGradient = ScriptableObject.CreateInstance<TMP_ColorGradient>();
// Create Asset
AssetDatabase.CreateAsset(colorGradient, filePath);
//EditorUtility.SetDirty(colorGradient);
AssetDatabase.SaveAssets();
AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(colorGradient));
EditorUtility.FocusProjectWindow();
EditorGUIUtility.PingObject(colorGradient);
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: d9647b571c5e44729b71d756b3d55317
timeCreated: 1468187791
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,146 @@
using UnityEngine;
using UnityEditor;
using System.Collections;
namespace TMPro.EditorUtilities
{
[CustomEditor(typeof(TMP_ColorGradient))]
public class TMP_ColorGradientEditor : Editor
{
SerializedProperty m_ColorMode;
SerializedProperty m_TopLeftColor;
SerializedProperty m_TopRightColor;
SerializedProperty m_BottomLeftColor;
SerializedProperty m_BottomRightColor;
void OnEnable()
{
m_ColorMode = serializedObject.FindProperty("colorMode");
m_TopLeftColor = serializedObject.FindProperty("topLeft");
m_TopRightColor = serializedObject.FindProperty("topRight");
m_BottomLeftColor = serializedObject.FindProperty("bottomLeft");
m_BottomRightColor = serializedObject.FindProperty("bottomRight");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(m_ColorMode, new GUIContent("Color Mode"));
if (EditorGUI.EndChangeCheck())
{
switch ((ColorMode)m_ColorMode.enumValueIndex)
{
case ColorMode.Single:
m_TopRightColor.colorValue = m_TopLeftColor.colorValue;
m_BottomLeftColor.colorValue = m_TopLeftColor.colorValue;
m_BottomRightColor.colorValue = m_TopLeftColor.colorValue;
break;
case ColorMode.HorizontalGradient:
m_BottomLeftColor.colorValue = m_TopLeftColor.colorValue;
m_BottomRightColor.colorValue = m_TopRightColor.colorValue;
break;
case ColorMode.VerticalGradient:
m_TopRightColor.colorValue = m_TopLeftColor.colorValue;
m_BottomRightColor.colorValue = m_BottomLeftColor.colorValue;
break;
}
}
Rect rect;
switch ((ColorMode)m_ColorMode.enumValueIndex)
{
case ColorMode.Single:
EditorGUI.BeginChangeCheck();
rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2));
EditorGUI.PrefixLabel(rect, new GUIContent("Colors"));
rect.x += EditorGUIUtility.labelWidth;
rect.width = (rect.width - EditorGUIUtility.labelWidth) / (EditorGUIUtility.wideMode ? 1f : 2f);
TMP_EditorUtility.DrawColorProperty(rect, m_TopLeftColor);
if (EditorGUI.EndChangeCheck())
{
m_TopRightColor.colorValue = m_TopLeftColor.colorValue;
m_BottomLeftColor.colorValue = m_TopLeftColor.colorValue;
m_BottomRightColor.colorValue = m_TopLeftColor.colorValue;
}
break;
case ColorMode.HorizontalGradient:
rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2));
EditorGUI.PrefixLabel(rect, new GUIContent("Colors"));
rect.x += EditorGUIUtility.labelWidth;
rect.width = (rect.width - EditorGUIUtility.labelWidth) / 2f;
EditorGUI.BeginChangeCheck();
TMP_EditorUtility.DrawColorProperty(rect, m_TopLeftColor);
if (EditorGUI.EndChangeCheck())
{
m_BottomLeftColor.colorValue = m_TopLeftColor.colorValue;
}
rect.x += rect.width;
EditorGUI.BeginChangeCheck();
TMP_EditorUtility.DrawColorProperty(rect, m_TopRightColor);
if (EditorGUI.EndChangeCheck())
{
m_BottomRightColor.colorValue = m_TopRightColor.colorValue;
}
break;
case ColorMode.VerticalGradient:
rect = EditorGUILayout.GetControlRect(false, EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2));
EditorGUI.PrefixLabel(rect, new GUIContent("Colors"));
rect.x += EditorGUIUtility.labelWidth;
rect.width = (rect.width - EditorGUIUtility.labelWidth) / (EditorGUIUtility.wideMode ? 1f : 2f);
rect.height = EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2);
EditorGUI.BeginChangeCheck();
TMP_EditorUtility.DrawColorProperty(rect, m_TopLeftColor);
if (EditorGUI.EndChangeCheck())
{
m_TopRightColor.colorValue = m_TopLeftColor.colorValue;
}
rect = EditorGUILayout.GetControlRect(false, EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2));
rect.x += EditorGUIUtility.labelWidth;
rect.width = (rect.width - EditorGUIUtility.labelWidth) / (EditorGUIUtility.wideMode ? 1f : 2f);
rect.height = EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2);
EditorGUI.BeginChangeCheck();
TMP_EditorUtility.DrawColorProperty(rect, m_BottomLeftColor);
if (EditorGUI.EndChangeCheck())
{
m_BottomRightColor.colorValue = m_BottomLeftColor.colorValue;
}
break;
case ColorMode.FourCornersGradient:
rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2));
EditorGUI.PrefixLabel(rect, new GUIContent("Colors"));
rect.x += EditorGUIUtility.labelWidth;
rect.width = (rect.width - EditorGUIUtility.labelWidth) / 2f;
rect.height = EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2);
TMP_EditorUtility.DrawColorProperty(rect, m_TopLeftColor);
rect.x += rect.width;
TMP_EditorUtility.DrawColorProperty(rect, m_TopRightColor);
rect = EditorGUILayout.GetControlRect(false, EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2));
rect.x += EditorGUIUtility.labelWidth;
rect.width = (rect.width - EditorGUIUtility.labelWidth) / 2f;
rect.height = EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2);
TMP_EditorUtility.DrawColorProperty(rect, m_BottomLeftColor);
rect.x += rect.width;
TMP_EditorUtility.DrawColorProperty(rect, m_BottomRightColor);
break;
}
if (serializedObject.ApplyModifiedProperties())
TMPro_EventManager.ON_COLOR_GRADIENT_PROPERTY_CHANGED(target as TMP_ColorGradient);
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: fcc60c1d6bb544d9b712b652f418ff3a
timeCreated: 1468400050
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,60 @@
using UnityEngine;
using UnityEditor;
using UnityEditor.UI;
using UnityEngine.UI;
namespace TMPro.EditorUtilities
{
[CustomEditor(typeof(TMP_Dropdown), true)]
[CanEditMultipleObjects]
public class DropdownEditor : SelectableEditor
{
SerializedProperty m_Template;
SerializedProperty m_CaptionText;
SerializedProperty m_CaptionImage;
SerializedProperty m_Placeholder;
SerializedProperty m_ItemText;
SerializedProperty m_ItemImage;
SerializedProperty m_OnSelectionChanged;
SerializedProperty m_Value;
SerializedProperty m_MultiSelect;
SerializedProperty m_AlphaFadeSpeed;
SerializedProperty m_Options;
protected override void OnEnable()
{
base.OnEnable();
m_Template = serializedObject.FindProperty("m_Template");
m_CaptionText = serializedObject.FindProperty("m_CaptionText");
m_CaptionImage = serializedObject.FindProperty("m_CaptionImage");
m_Placeholder = serializedObject.FindProperty("m_Placeholder");
m_ItemText = serializedObject.FindProperty("m_ItemText");
m_ItemImage = serializedObject.FindProperty("m_ItemImage");
m_OnSelectionChanged = serializedObject.FindProperty("m_OnValueChanged");
m_Value = serializedObject.FindProperty("m_Value");
m_MultiSelect = serializedObject.FindProperty("m_MultiSelect");
m_AlphaFadeSpeed = serializedObject.FindProperty("m_AlphaFadeSpeed");
m_Options = serializedObject.FindProperty("m_Options");
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
EditorGUILayout.Space();
serializedObject.Update();
EditorGUILayout.PropertyField(m_Template);
EditorGUILayout.PropertyField(m_CaptionText);
EditorGUILayout.PropertyField(m_CaptionImage);
EditorGUILayout.PropertyField(m_Placeholder);
EditorGUILayout.PropertyField(m_ItemText);
EditorGUILayout.PropertyField(m_ItemImage);
EditorGUILayout.PropertyField(m_Value);
EditorGUILayout.PropertyField(m_MultiSelect);
EditorGUILayout.PropertyField(m_AlphaFadeSpeed);
EditorGUILayout.PropertyField(m_Options);
EditorGUILayout.PropertyField(m_OnSelectionChanged);
serializedObject.ApplyModifiedProperties();
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 6dbcf248c987476181a37f01a1814975
timeCreated: 1446377461
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,96 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace TMPro.EditorUtilities
{
/// <summary>
/// Simple implementation of coroutine working in the Unity Editor.
/// </summary>
public class TMP_EditorCoroutine
{
//private static Dictionary<int, EditorCoroutine> s_ActiveCoroutines;
readonly IEnumerator coroutine;
/// <summary>
/// Constructor
/// </summary>
/// <param name="routine"></param>
TMP_EditorCoroutine(IEnumerator routine)
{
this.coroutine = routine;
}
/// <summary>
/// Starts a new EditorCoroutine.
/// </summary>
/// <param name="newCoroutine">Coroutine</param>
/// <returns>new EditorCoroutine</returns>
public static TMP_EditorCoroutine StartCoroutine(IEnumerator routine)
{
TMP_EditorCoroutine coroutine = new TMP_EditorCoroutine(routine);
coroutine.Start();
// Add coroutine to tracking list
//if (s_ActiveCoroutines == null)
// s_ActiveCoroutines = new Dictionary<int, EditorCoroutine>();
// Add new instance of editor coroutine to dictionary.
//s_ActiveCoroutines.Add(coroutine.GetHashCode(), coroutine);
return coroutine;
}
/// <summary>
/// Clear delegate list
/// </summary>
//public static void StopAllEditorCoroutines()
//{
// EditorApplication.update = null;
//}
/// <summary>
/// Register callback for editor updates
/// </summary>
void Start()
{
EditorApplication.update += EditorUpdate;
}
/// <summary>
/// Unregister callback for editor updates.
/// </summary>
public void Stop()
{
if (EditorApplication.update != null)
EditorApplication.update -= EditorUpdate;
//s_ActiveCoroutines.Remove(this.GetHashCode());
}
/// <summary>
/// Delegate function called on editor updates.
/// </summary>
void EditorUpdate()
{
// Stop editor coroutine if it does not continue.
if (coroutine.MoveNext() == false)
Stop();
// Process the different types of EditorCoroutines.
if (coroutine.Current != null)
{
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 27a0335dab59ec542aadd6636a5b4ebd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,202 @@
using UnityEngine;
using UnityEditor;
namespace TMPro.EditorUtilities
{
[CustomEditor(typeof(TextMeshPro), true), CanEditMultipleObjects]
public class TMP_EditorPanel : TMP_BaseEditorPanel
{
static readonly GUIContent k_SortingLayerLabel = new GUIContent("Sorting Layer", "Name of the Renderer's sorting layer.");
static readonly GUIContent k_OrderInLayerLabel = new GUIContent("Order in Layer", "Renderer's order within a sorting layer.");
static readonly GUIContent k_OrthographicLabel = new GUIContent("Orthographic Mode", "Should be enabled when using an orthographic camera. Instructs the shader to not perform any perspective correction.");
static readonly GUIContent k_VolumetricLabel = new GUIContent("Volumetric Setup", "Use cubes rather than quads to render the text. Allows for volumetric rendering when combined with a compatible shader.");
private static string[] k_SortingLayerNames;
bool IsPreset;
SerializedProperty m_IsVolumetricTextProp;
SerializedProperty m_IsOrthographicProp;
Object[] m_Renderers;
SerializedObject m_RendererSerializedObject;
SerializedProperty m_RendererSortingLayerProp;
SerializedProperty m_RendererSortingLayerIDProp;
SerializedProperty m_RendererSortingOrderProp;
SerializedProperty m_TextSortingLayerProp;
SerializedProperty m_TextSortingLayerIDProp;
SerializedProperty m_TextSortingOrderProp;
protected override void OnEnable()
{
base.OnEnable();
// Determine if the inspected object is a Preset
IsPreset = (int)(target as Component).gameObject.hideFlags == 93;
m_IsOrthographicProp = serializedObject.FindProperty("m_isOrthographic");
m_IsVolumetricTextProp = serializedObject.FindProperty("m_isVolumetricText");
m_Renderers = new Object[targets.Length];
for (int i = 0; i < m_Renderers.Length; i++)
m_Renderers[i] = (targets[i] as TextMeshPro)?.GetComponent<Renderer>();
m_RendererSerializedObject = new SerializedObject(m_Renderers);
m_RendererSortingLayerProp = m_RendererSerializedObject.FindProperty("m_SortingLayer");
m_RendererSortingLayerIDProp = m_RendererSerializedObject.FindProperty("m_SortingLayerID");
m_RendererSortingOrderProp = m_RendererSerializedObject.FindProperty("m_SortingOrder");
m_TextSortingLayerProp = serializedObject.FindProperty("_SortingLayer");
m_TextSortingLayerIDProp = serializedObject.FindProperty("_SortingLayerID");
m_TextSortingOrderProp = serializedObject.FindProperty("_SortingOrder");
// Populate Sorting Layer Names
k_SortingLayerNames = SortingLayerHelper.sortingLayerNames;
}
protected override void DrawExtraSettings()
{
Rect rect = EditorGUILayout.GetControlRect(false, 24);
if (GUI.Button(rect, new GUIContent("<b>Extra Settings</b>"), TMP_UIStyleManager.sectionHeader))
Foldout.extraSettings = !Foldout.extraSettings;
GUI.Label(rect, (Foldout.extraSettings ? "" : k_UiStateLabel[1]), TMP_UIStyleManager.rightLabel);
if (Foldout.extraSettings)
{
DrawMargins();
DrawSortingLayer();
DrawGeometrySorting();
DrawIsTextObjectScaleStatic();
DrawOrthographicMode();
DrawRichText();
DrawParsing();
DrawEmojiFallbackSupport();
DrawSpriteAsset();
DrawStyleSheet();
DrawFontFeatures();
DrawPadding();
}
}
private void DrawSortingLayer()
{
m_RendererSerializedObject.Update();
Rect rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight);
// Special handling for Presets where the sorting layer, id and order is serialized with the text object instead of on the MeshRenderer.
SerializedProperty sortingLayerProp = IsPreset ? m_TextSortingLayerProp : m_RendererSortingLayerProp;
SerializedProperty sortingLayerIDProp = IsPreset ? m_TextSortingLayerIDProp : m_RendererSortingLayerIDProp;
EditorGUI.BeginProperty(rect, k_SortingLayerLabel, sortingLayerIDProp);
EditorGUI.BeginChangeCheck();
int currentLayerIndex = SortingLayerHelper.GetSortingLayerIndexFromSortingLayerID(sortingLayerIDProp.intValue);
int newLayerIndex = EditorGUI.Popup(rect, k_SortingLayerLabel, currentLayerIndex, k_SortingLayerNames);
if (EditorGUI.EndChangeCheck())
{
sortingLayerIDProp.intValue = SortingLayer.NameToID(k_SortingLayerNames[newLayerIndex]);
sortingLayerProp.intValue = SortingLayer.GetLayerValueFromName(k_SortingLayerNames[newLayerIndex]);
m_HavePropertiesChanged = true;
// Sync Sorting Layer ID change on potential sub text object.
TextMeshPro textComponent = m_TextComponent as TextMeshPro;
textComponent.UpdateSubMeshSortingLayerID(sortingLayerIDProp.intValue);
}
EditorGUI.EndProperty();
// Sorting Order
SerializedProperty sortingOrderLayerProp = IsPreset ? m_TextSortingOrderProp : m_RendererSortingOrderProp;
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(sortingOrderLayerProp, k_OrderInLayerLabel);
if (EditorGUI.EndChangeCheck())
{
m_HavePropertiesChanged = true;
TextMeshPro textComponent = m_TextComponent as TextMeshPro;
textComponent.UpdateSubMeshSortingOrder(sortingOrderLayerProp.intValue);
}
m_RendererSerializedObject.ApplyModifiedProperties();
EditorGUILayout.Space();
}
private void DrawOrthographicMode()
{
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(m_IsOrthographicProp, k_OrthographicLabel);
if (EditorGUI.EndChangeCheck())
m_HavePropertiesChanged = true;
}
protected void DrawVolumetricSetup()
{
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(m_IsVolumetricTextProp, k_VolumetricLabel);
if (EditorGUI.EndChangeCheck())
{
m_HavePropertiesChanged = true;
m_TextComponent.textInfo.ResetVertexLayout(m_IsVolumetricTextProp.boolValue);
}
EditorGUILayout.Space();
}
// Method to handle multi object selection
protected override bool IsMixSelectionTypes()
{
GameObject[] objects = Selection.gameObjects;
if (objects.Length > 1)
{
for (int i = 0; i < objects.Length; i++)
{
if (objects[i].GetComponent<TextMeshPro>() == null)
return true;
}
}
return false;
}
protected override void OnUndoRedo()
{
int undoEventId = Undo.GetCurrentGroup();
int lastUndoEventId = s_EventId;
if (undoEventId != lastUndoEventId)
{
for (int i = 0; i < targets.Length; i++)
{
//Debug.Log("Undo & Redo Performed detected in Editor Panel. Event ID:" + Undo.GetCurrentGroup());
TMPro_EventManager.ON_TEXTMESHPRO_PROPERTY_CHANGED(true, targets[i] as TextMeshPro);
s_EventId = undoEventId;
}
}
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 34f6695d37a94370a3697f6b068f5d5e
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,127 @@
using UnityEngine;
using UnityEngine.UI;
using UnityEditor;
namespace TMPro.EditorUtilities
{
[CustomEditor(typeof(TextMeshProUGUI), true), CanEditMultipleObjects]
public class TMP_EditorPanelUI : TMP_BaseEditorPanel
{
static readonly GUIContent k_RaycastTargetLabel = new GUIContent("Raycast Target", "Whether the text blocks raycasts from the Graphic Raycaster.");
static readonly GUIContent k_MaskableLabel = new GUIContent("Maskable", "Determines if the text object will be affected by UI Mask.");
SerializedProperty m_RaycastTargetProp;
private SerializedProperty m_MaskableProp;
protected override void OnEnable()
{
base.OnEnable();
m_RaycastTargetProp = serializedObject.FindProperty("m_RaycastTarget");
m_MaskableProp = serializedObject.FindProperty("m_Maskable");
}
protected override void DrawExtraSettings()
{
Rect rect = EditorGUILayout.GetControlRect(false, 24);
if (GUI.Button(rect, new GUIContent("<b>Extra Settings</b>"), TMP_UIStyleManager.sectionHeader))
Foldout.extraSettings = !Foldout.extraSettings;
GUI.Label(rect, (Foldout.extraSettings ? k_UiStateLabel[0] : k_UiStateLabel[1]), TMP_UIStyleManager.rightLabel);
if (Foldout.extraSettings)
{
DrawMargins();
DrawGeometrySorting();
DrawIsTextObjectScaleStatic();
DrawRichText();
DrawRaycastTarget();
DrawMaskable();
DrawParsing();
DrawEmojiFallbackSupport();
DrawSpriteAsset();
DrawStyleSheet();
DrawFontFeatures();
DrawPadding();
}
}
protected void DrawRaycastTarget()
{
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(m_RaycastTargetProp, k_RaycastTargetLabel);
if (EditorGUI.EndChangeCheck())
{
// Change needs to propagate to the child sub objects.
Graphic[] graphicComponents = m_TextComponent.GetComponentsInChildren<Graphic>();
for (int i = 1; i < graphicComponents.Length; i++)
graphicComponents[i].raycastTarget = m_RaycastTargetProp.boolValue;
m_HavePropertiesChanged = true;
}
}
protected void DrawMaskable()
{
if (m_MaskableProp == null)
return;
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(m_MaskableProp, k_MaskableLabel);
if (EditorGUI.EndChangeCheck())
{
m_TextComponent.maskable = m_MaskableProp.boolValue;
// Change needs to propagate to the child sub objects.
MaskableGraphic[] maskableGraphics = m_TextComponent.GetComponentsInChildren<MaskableGraphic>();
for (int i = 1; i < maskableGraphics.Length; i++)
maskableGraphics[i].maskable = m_MaskableProp.boolValue;
m_HavePropertiesChanged = true;
}
}
// Method to handle multi object selection
protected override bool IsMixSelectionTypes()
{
GameObject[] objects = Selection.gameObjects;
if (objects.Length > 1)
{
for (int i = 0; i < objects.Length; i++)
{
if (objects[i].GetComponent<TextMeshProUGUI>() == null)
return true;
}
}
return false;
}
protected override void OnUndoRedo()
{
int undoEventId = Undo.GetCurrentGroup();
int lastUndoEventId = s_EventId;
if (undoEventId != lastUndoEventId)
{
for (int i = 0; i < targets.Length; i++)
{
//Debug.Log("Undo & Redo Performed detected in Editor Panel. Event ID:" + Undo.GetCurrentGroup());
TMPro_EventManager.ON_TEXTMESHPRO_UGUI_PROPERTY_CHANGED(true, targets[i] as TextMeshProUGUI);
s_EventId = undoEventId;
}
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 21c0044a7f964773be90d197a78e4703
timeCreated: 1443571501
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,295 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEditor;
using UnityEditor.TextCore.LowLevel;
namespace TMPro
{
static class EditorEventCallbacks
{
[InitializeOnLoadMethod]
internal static void InitializeFontAssetResourceChangeCallBacks()
{
TMP_FontAsset.RegisterResourceForUpdate += TMP_EditorResourceManager.RegisterResourceForUpdate;
TMP_FontAsset.RegisterResourceForReimport += TMP_EditorResourceManager.RegisterResourceForReimport;
TMP_FontAsset.OnFontAssetTextureChanged += TMP_EditorResourceManager.AddTextureToAsset;
TMP_FontAsset.SetAtlasTextureIsReadable += FontEngineEditorUtilities.SetAtlasTextureIsReadable;
TMP_FontAsset.GetSourceFontRef += TMP_EditorResourceManager.GetSourceFontRef;
TMP_FontAsset.SetSourceFontGUID += TMP_EditorResourceManager.SetSourceFontGUID;
// Callback to handle clearing dynamic font asset data when closing the Editor
EditorApplication.quitting += () =>
{
// Find all font assets in the project
string searchPattern = "t:TMP_FontAsset";
string[] fontAssetGUIDs = AssetDatabase.FindAssets(searchPattern);
for (int i = 0; i < fontAssetGUIDs.Length; i++)
{
string fontAssetPath = AssetDatabase.GUIDToAssetPath(fontAssetGUIDs[i]);
TMP_FontAsset fontAsset = AssetDatabase.LoadAssetAtPath<TMP_FontAsset>(fontAssetPath);
if (fontAsset != null && (fontAsset.atlasPopulationMode == AtlasPopulationMode.Dynamic || fontAsset.atlasPopulationMode == AtlasPopulationMode.DynamicOS) && fontAsset.clearDynamicDataOnBuild && fontAsset.atlasTexture.width > 1)
{
Debug.Log("Clearing [" + fontAsset.name + "] dynamic font asset data.");
fontAsset.ClearCharacterAndGlyphTablesInternal();
}
}
};
}
}
internal class TMP_EditorResourceManager
{
private static TMP_EditorResourceManager s_Instance;
private readonly List<Object> m_ObjectUpdateQueue = new List<Object>();
private HashSet<int> m_ObjectUpdateQueueLookup = new HashSet<int>();
private readonly List<Object> m_ObjectReImportQueue = new List<Object>();
private HashSet<int> m_ObjectReImportQueueLookup = new HashSet<int>();
private readonly List<TMP_FontAsset> m_FontAssetDefinitionRefreshQueue = new List<TMP_FontAsset>();
private HashSet<int> m_FontAssetDefinitionRefreshQueueLookup = new HashSet<int>();
/// <summary>
/// Get a singleton instance of the manager.
/// </summary>
internal static TMP_EditorResourceManager instance
{
get
{
if (s_Instance == null)
s_Instance = new TMP_EditorResourceManager();
return s_Instance;
}
}
/// <summary>
/// Register to receive rendering callbacks.
/// </summary>
private TMP_EditorResourceManager()
{
// Register to the appropriate callback for the given render pipeline.
if (RenderPipelineManager.currentPipeline == null)
Camera.onPostRender += OnCameraPostRender;
else
{
#if UNITY_2023_3_OR_NEWER
RenderPipelineManager.endContextRendering += OnEndOfFrame;
#else
RenderPipelineManager.endFrameRendering += OnEndOfFrame;
#endif
}
Canvas.willRenderCanvases += OnPreRenderCanvases;
}
void OnCameraPostRender(Camera cam)
{
// Exclude the PreRenderCamera
if (cam.cameraType != CameraType.SceneView)
return;
DoPostRenderUpdates();
}
void OnPreRenderCanvases()
{
DoPreRenderUpdates();
}
#if UNITY_2023_3_OR_NEWER
void OnEndOfFrame(ScriptableRenderContext renderContext, List<Camera> cameras)
{
DoPostRenderUpdates();
}
#else
void OnEndOfFrame(ScriptableRenderContext renderContext, Camera[] cameras)
{
DoPostRenderUpdates();
}
#endif
/// <summary>
/// Register resource for re-import.
/// </summary>
/// <param name="obj"></param>
internal static void RegisterResourceForReimport(Object obj)
{
// Return if referenced object is not a persistent asset
if (!EditorUtility.IsPersistent(obj))
return;
instance.InternalRegisterResourceForReimport(obj);
}
private void InternalRegisterResourceForReimport(Object obj)
{
int id = obj.GetInstanceID();
if (m_ObjectReImportQueueLookup.Contains(id))
return;
m_ObjectReImportQueueLookup.Add(id);
m_ObjectReImportQueue.Add(obj);
}
/// <summary>
/// Register resource to be updated.
/// </summary>
/// <param name="obj"></param>
internal static void RegisterResourceForUpdate(Object obj)
{
// Return if referenced object is not a persistent asset
if (!EditorUtility.IsPersistent(obj))
return;
instance.InternalRegisterResourceForUpdate(obj);
}
private void InternalRegisterResourceForUpdate(Object obj)
{
int id = obj.GetInstanceID();
if (m_ObjectUpdateQueueLookup.Contains(id))
return;
m_ObjectUpdateQueueLookup.Add(id);
m_ObjectUpdateQueue.Add(obj);
}
/// <summary>
///
/// </summary>
/// <param name="fontAsset"></param>
internal static void RegisterFontAssetForDefinitionRefresh(TMP_FontAsset fontAsset)
{
instance.InternalRegisterFontAssetForDefinitionRefresh(fontAsset);
}
private void InternalRegisterFontAssetForDefinitionRefresh(TMP_FontAsset fontAsset)
{
int id = fontAsset.GetInstanceID();
if (m_FontAssetDefinitionRefreshQueueLookup.Contains(id))
return;
m_FontAssetDefinitionRefreshQueueLookup.Add(id);
m_FontAssetDefinitionRefreshQueue.Add(fontAsset);
}
/// <summary>
/// Add texture as sub asset to the referenced object.
/// </summary>
/// <param name="tex">The texture to be added as sub object.</param>
/// <param name="obj">The object to which this texture sub object will be added.</param>
internal static void AddTextureToAsset(Texture tex, Object obj)
{
// Return if referenced object is not a persistent asset
if (!EditorUtility.IsPersistent(obj))
return;
if (tex != null)
AssetDatabase.AddObjectToAsset(tex, obj);
RegisterResourceForReimport(obj);
}
/// <summary>
///
/// </summary>
/// <param name="guid"></param>
/// <returns></returns>
internal static Font GetSourceFontRef(string guid)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
return AssetDatabase.LoadAssetAtPath<Font>(path);
}
/// <summary>
///
/// </summary>
/// <param name="font"></param>
/// <returns></returns>
internal static string SetSourceFontGUID(Font font)
{
return AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(font));
}
void DoPostRenderUpdates()
{
// Handle objects that need updating
int objUpdateCount = m_ObjectUpdateQueue.Count;
for (int i = 0; i < objUpdateCount; i++)
{
EditorUtilities.TMP_PropertyDrawerUtilities.s_RefreshGlyphProxyLookup = true;
#if TEXTCORE_FONT_ENGINE_1_5_OR_NEWER
UnityEditor.TextCore.Text.TextCorePropertyDrawerUtilities.s_RefreshGlyphProxyLookup = true;
#endif
Object obj = m_ObjectUpdateQueue[i];
if (obj != null)
{
//EditorUtility.SetDirty(obj);
}
}
if (objUpdateCount > 0)
{
//Debug.Log("Saving assets");
//AssetDatabase.SaveAssets();
m_ObjectUpdateQueue.Clear();
m_ObjectUpdateQueueLookup.Clear();
}
// Handle objects that need re-importing
int objReImportCount = m_ObjectReImportQueue.Count;
for (int i = 0; i < objReImportCount; i++)
{
Object obj = m_ObjectReImportQueue[i];
if (obj != null)
{
string assetPath = AssetDatabase.GetAssetPath(obj);
// Exclude Assets not located in the project
if (assetPath.StartsWith("Assets/", System.StringComparison.OrdinalIgnoreCase))
AssetDatabase.ImportAsset(assetPath);
}
}
if (objReImportCount > 0)
{
m_ObjectReImportQueue.Clear();
m_ObjectReImportQueueLookup.Clear();
}
}
void DoPreRenderUpdates()
{
// Handle Font Asset Definition Refresh
for (int i = 0; i < m_FontAssetDefinitionRefreshQueue.Count; i++)
{
TMP_FontAsset fontAsset = m_FontAssetDefinitionRefreshQueue[i];
if (fontAsset != null)
{
fontAsset.ReadFontAssetDefinition();
TMPro_EventManager.ON_FONT_PROPERTY_CHANGED(true, fontAsset);
}
}
if (m_FontAssetDefinitionRefreshQueue.Count > 0)
{
m_FontAssetDefinitionRefreshQueue.Clear();
m_FontAssetDefinitionRefreshQueueLookup.Clear();
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6b259c4003a802847b9ada90744e34c5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,437 @@
using UnityEngine;
using UnityEditor;
using System.Text;
using System.IO;
using System.Collections;
using System.Collections.Generic;
namespace TMPro.EditorUtilities
{
public static class TMP_EditorUtility
{
/// <summary>
/// Returns the relative path of the package.
/// </summary>
public static string packageRelativePath
{
get
{
if (string.IsNullOrEmpty(m_PackagePath))
m_PackagePath = GetPackageRelativePath();
return m_PackagePath;
}
}
[SerializeField]
private static string m_PackagePath;
/// <summary>
/// Returns the fully qualified path of the package.
/// </summary>
public static string packageFullPath
{
get
{
if (string.IsNullOrEmpty(m_PackageFullPath))
m_PackageFullPath = GetPackageFullPath();
return m_PackageFullPath;
}
}
[SerializeField]
private static string m_PackageFullPath;
// Static Fields Related to locating the TextMesh Pro Asset
private static string folderPath = "Not Found";
private static EditorWindow Gameview;
private static bool isInitialized = false;
private static void GetGameview()
{
System.Reflection.Assembly assembly = typeof(UnityEditor.EditorWindow).Assembly;
System.Type type = assembly.GetType("UnityEditor.GameView");
Gameview = EditorWindow.GetWindow(type);
}
internal static void RepaintAll()
{
if (isInitialized == false)
{
GetGameview();
isInitialized = true;
}
SceneView.RepaintAll();
Gameview.Repaint();
}
/// <summary>
/// Create and return a new asset in a smart location based on the current selection and then select it.
/// </summary>
/// <param name="name">
/// Name of the new asset. Do not include the .asset extension.
/// </param>
/// <returns>
/// The new asset.
/// </returns>
internal static T CreateAsset<T>(string name) where T : ScriptableObject
{
string path = AssetDatabase.GetAssetPath(Selection.activeObject);
if (path.Length == 0)
{
// no asset selected, place in asset root
path = "Assets/" + name + ".asset";
}
else if (Directory.Exists(path))
{
// place in currently selected directory
path += "/" + name + ".asset";
}
else {
// place in current selection's containing directory
path = Path.GetDirectoryName(path) + "/" + name + ".asset";
}
T asset = ScriptableObject.CreateInstance<T>();
AssetDatabase.CreateAsset(asset, AssetDatabase.GenerateUniqueAssetPath(path));
EditorUtility.FocusProjectWindow();
Selection.activeObject = asset;
return asset;
}
// Function used to find all materials which reference a font atlas so we can update all their references.
internal static Material[] FindMaterialReferences(TMP_FontAsset fontAsset)
{
List<Material> refs = new List<Material>();
Material mat = fontAsset.material;
refs.Add(mat);
// Get materials matching the search pattern.
string searchPattern = "t:Material" + " " + fontAsset.name.Split(new char[] { ' ' })[0];
string[] materialAssetGUIDs = AssetDatabase.FindAssets(searchPattern);
for (int i = 0; i < materialAssetGUIDs.Length; i++)
{
string materialPath = AssetDatabase.GUIDToAssetPath(materialAssetGUIDs[i]);
Material targetMaterial = AssetDatabase.LoadAssetAtPath<Material>(materialPath);
if (targetMaterial.HasProperty(ShaderUtilities.ID_MainTex) && targetMaterial.GetTexture(ShaderUtilities.ID_MainTex) != null && mat.GetTexture(ShaderUtilities.ID_MainTex) != null && targetMaterial.GetTexture(ShaderUtilities.ID_MainTex).GetInstanceID() == mat.GetTexture(ShaderUtilities.ID_MainTex).GetInstanceID())
{
if (!refs.Contains(targetMaterial))
refs.Add(targetMaterial);
}
else
{
// TODO: Find a more efficient method to unload resources.
//Resources.UnloadAsset(targetMaterial.GetTexture(ShaderUtilities.ID_MainTex));
}
}
return refs.ToArray();
}
// Function used to find the Font Asset which matches the given Material Preset and Font Atlas Texture.
internal static TMP_FontAsset FindMatchingFontAsset(Material mat)
{
if (mat.GetTexture(ShaderUtilities.ID_MainTex) == null) return null;
// Find the dependent assets of this material.
string[] dependentAssets = AssetDatabase.GetDependencies(AssetDatabase.GetAssetPath(mat), false);
for (int i = 0; i < dependentAssets.Length; i++)
{
TMP_FontAsset fontAsset = AssetDatabase.LoadAssetAtPath<TMP_FontAsset>(dependentAssets[i]);
if (fontAsset != null)
return fontAsset;
}
return null;
}
private static string GetPackageRelativePath()
{
// Check for potential UPM package
string packagePath = Path.GetFullPath("Packages/com.unity.ugui");
if (Directory.Exists(packagePath))
{
return "Packages/com.unity.ugui";
}
packagePath = Path.GetFullPath("Assets/..");
if (Directory.Exists(packagePath))
{
// Search default location for development package
if (Directory.Exists(packagePath + "/Assets/Packages/com.unity.ugui/Editor Resources"))
{
return "Assets/Packages/com.unity.ugui";
}
// Search for potential alternative locations in the user project
string[] matchingPaths = Directory.GetDirectories(packagePath, "TextMesh Pro", SearchOption.AllDirectories);
packagePath = ValidateLocation(matchingPaths, packagePath);
if (packagePath != null) return packagePath;
}
return null;
}
private static string GetPackageFullPath()
{
// Check for potential UPM package
string packagePath = Path.GetFullPath("Packages/com.unity.ugui");
if (Directory.Exists(packagePath))
{
return packagePath;
}
packagePath = Path.GetFullPath("Assets/..");
if (Directory.Exists(packagePath))
{
// Search default location for development package
if (Directory.Exists(packagePath + "/Assets/Packages/com.unity.ugui/Editor Resources"))
{
return packagePath + "/Assets/Packages/com.unity.ugui";
}
// Search for potential alternative locations in the user project
string[] matchingPaths = Directory.GetDirectories(packagePath, "TextMesh Pro", SearchOption.AllDirectories);
string path = ValidateLocation(matchingPaths, packagePath);
if (path != null) return packagePath + path;
}
return null;
}
/// <summary>
/// Method to validate the location of the asset folder by making sure the GUISkins folder exists.
/// </summary>
/// <param name="paths"></param>
/// <returns></returns>
private static string ValidateLocation(string[] paths, string projectPath)
{
for (int i = 0; i < paths.Length; i++)
{
// Check if any of the matching directories contain a GUISkins directory.
if (Directory.Exists(paths[i] + "/Editor Resources"))
{
folderPath = paths[i].Replace(projectPath, "");
folderPath = folderPath.TrimStart('\\', '/');
return folderPath;
}
}
return null;
}
/// <summary>
/// Function which returns a string containing a sequence of Decimal character ranges.
/// </summary>
/// <param name="characterSet"></param>
/// <returns></returns>
internal static string GetDecimalCharacterSequence(int[] characterSet)
{
if (characterSet == null || characterSet.Length == 0)
return string.Empty;
string characterSequence = string.Empty;
int count = characterSet.Length;
int first = characterSet[0];
int last = first;
for (int i = 1; i < count; i++)
{
if (characterSet[i - 1] + 1 == characterSet[i])
{
last = characterSet[i];
}
else
{
if (first == last)
characterSequence += first + ",";
else
characterSequence += first + "-" + last + ",";
first = last = characterSet[i];
}
}
// handle the final group
if (first == last)
characterSequence += first;
else
characterSequence += first + "-" + last;
return characterSequence;
}
/// <summary>
/// Function which returns a string containing a sequence of Unicode (Hex) character ranges.
/// </summary>
/// <param name="characterSet"></param>
/// <returns></returns>
internal static string GetUnicodeCharacterSequence(int[] characterSet)
{
if (characterSet == null || characterSet.Length == 0)
return string.Empty;
string characterSequence = string.Empty;
int count = characterSet.Length;
int first = characterSet[0];
int last = first;
for (int i = 1; i < count; i++)
{
if (characterSet[i - 1] + 1 == characterSet[i])
{
last = characterSet[i];
}
else
{
if (first == last)
characterSequence += first.ToString("X2") + ",";
else
characterSequence += first.ToString("X2") + "-" + last.ToString("X2") + ",";
first = last = characterSet[i];
}
}
// handle the final group
if (first == last)
characterSequence += first.ToString("X2");
else
characterSequence += first.ToString("X2") + "-" + last.ToString("X2");
return characterSequence;
}
/// <summary>
///
/// </summary>
/// <param name="rect"></param>
/// <param name="thickness"></param>
/// <param name="color"></param>
internal static void DrawBox(Rect rect, float thickness, Color color)
{
EditorGUI.DrawRect(new Rect(rect.x - thickness, rect.y + thickness, rect.width + thickness * 2, thickness), color);
EditorGUI.DrawRect(new Rect(rect.x - thickness, rect.y + thickness, thickness, rect.height - thickness * 2), color);
EditorGUI.DrawRect(new Rect(rect.x - thickness, rect.y + rect.height - thickness * 2, rect.width + thickness * 2, thickness), color);
EditorGUI.DrawRect(new Rect(rect.x + rect.width, rect.y + thickness, thickness, rect.height - thickness * 2), color);
}
/// <summary>
/// Function to return the horizontal alignment grid value.
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
internal static int GetHorizontalAlignmentGridValue(int value)
{
if ((value & 0x1) == 0x1)
return 0;
else if ((value & 0x2) == 0x2)
return 1;
else if ((value & 0x4) == 0x4)
return 2;
else if ((value & 0x8) == 0x8)
return 3;
else if ((value & 0x10) == 0x10)
return 4;
else if ((value & 0x20) == 0x20)
return 5;
return 0;
}
/// <summary>
/// Function to return the vertical alignment grid value.
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
internal static int GetVerticalAlignmentGridValue(int value)
{
if ((value & 0x100) == 0x100)
return 0;
if ((value & 0x200) == 0x200)
return 1;
if ((value & 0x400) == 0x400)
return 2;
if ((value & 0x800) == 0x800)
return 3;
if ((value & 0x1000) == 0x1000)
return 4;
if ((value & 0x2000) == 0x2000)
return 5;
return 0;
}
internal static void DrawColorProperty(Rect rect, SerializedProperty property)
{
int oldIndent = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
if (EditorGUIUtility.wideMode)
{
EditorGUI.PropertyField(new Rect(rect.x, rect.y, 50f, rect.height), property, GUIContent.none);
rect.x += 50f;
rect.width = Mathf.Min(100f, rect.width - 55f);
}
else
{
rect.height /= 2f;
rect.width = Mathf.Min(100f, rect.width - 5f);
EditorGUI.PropertyField(rect, property, GUIContent.none);
rect.y += rect.height;
}
EditorGUI.BeginChangeCheck();
string colorString = EditorGUI.TextField(rect, string.Format("#{0}", ColorUtility.ToHtmlStringRGBA(property.colorValue)));
if (EditorGUI.EndChangeCheck())
{
Color color;
if (ColorUtility.TryParseHtmlString(colorString, out color))
{
property.colorValue = color;
}
}
EditorGUI.indentLevel = oldIndent;
}
internal static bool EditorToggle(Rect position, bool value, GUIContent content, GUIStyle style)
{
var id = GUIUtility.GetControlID(content, FocusType.Keyboard, position);
var evt = Event.current;
// Toggle selected toggle on space or return key
if (GUIUtility.keyboardControl == id && evt.type == EventType.KeyDown && (evt.keyCode == KeyCode.Space || evt.keyCode == KeyCode.Return || evt.keyCode == KeyCode.KeypadEnter))
{
value = !value;
evt.Use();
GUI.changed = true;
}
if (evt.type == EventType.MouseDown && position.Contains(Event.current.mousePosition))
{
GUIUtility.keyboardControl = id;
EditorGUIUtility.editingTextField = false;
HandleUtility.Repaint();
}
return GUI.Toggle(position, id, value, content, style);
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 2300e75732d74890b38a8ff257a3ae15
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 96b44f7d98314b139324a8a87eb66067
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,238 @@
using System.IO;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.TextCore;
using UnityEngine.TextCore.LowLevel;
using UnityEditor;
using Object = UnityEngine.Object;
namespace TMPro
{
static class TMP_FontAsset_CreationMenu
{
[MenuItem("Assets/Create/TextMeshPro/Font Asset/Font Asset Variant", false, 200)]
static void CreateFontAssetVariant()
{
Object target = Selection.activeObject;
// Make sure the selection is a font file
if (target == null || target.GetType() != typeof(TMP_FontAsset))
{
Debug.LogWarning("A Font file must first be selected in order to create a Font Asset.");
return;
}
// Make sure TMP Essential Resources have been imported in the user project.
if (TMP_Settings.instance == null)
{
Debug.Log("Unable to create font asset. Please import the TMP Essential Resources.");
return;
}
TMP_FontAsset sourceFontAsset = (TMP_FontAsset)target;
string sourceFontFilePath = AssetDatabase.GetAssetPath(target);
string folderPath = Path.GetDirectoryName(sourceFontFilePath);
string assetName = Path.GetFileNameWithoutExtension(sourceFontFilePath);
string newAssetFilePathWithName = AssetDatabase.GenerateUniqueAssetPath(folderPath + "/" + assetName + " - Variant.asset");
// Set Texture and Material reference to the source font asset.
TMP_FontAsset fontAsset = ScriptableObject.Instantiate<TMP_FontAsset>(sourceFontAsset);
AssetDatabase.CreateAsset(fontAsset, newAssetFilePathWithName);
fontAsset.atlasPopulationMode = AtlasPopulationMode.Static;
// Initialize array for the font atlas textures.
fontAsset.atlasTextures = sourceFontAsset.atlasTextures;
fontAsset.material = sourceFontAsset.material;
// Not sure if this is still necessary in newer versions of Unity.
EditorUtility.SetDirty(fontAsset);
AssetDatabase.SaveAssets();
}
[MenuItem("Assets/Create/TextMeshPro/Font Asset/SDF #%F12", false, 100)]
//[MenuItem("Assets/Create/TextMeshPro/Font Asset", false, 100)]
static void CreateFontAssetSDF()
{
CreateFontAsset(GlyphRenderMode.SDFAA);
}
[MenuItem("Assets/Create/TextMeshPro/Font Asset/Bitmap", false, 105)]
static void CreateFontAssetBitmap()
{
CreateFontAsset(GlyphRenderMode.SMOOTH);
}
#if TEXTCORE_FONT_ENGINE_1_5_OR_NEWER
[MenuItem("Assets/Create/TextMeshPro/Font Asset/Color", false, 110)]
static void CreateFontAssetColor()
{
CreateFontAsset(GlyphRenderMode.COLOR);
}
#endif
static void CreateFontAsset(GlyphRenderMode renderMode)
{
Object[] targets = Selection.objects;
if (targets == null)
{
Debug.LogWarning("A Font file must first be selected in order to create a Font Asset.");
return;
}
// Make sure TMP Essential Resources have been imported in the user project.
if (TMP_Settings.instance == null)
{
Debug.Log("Unable to create font asset. Please import the TMP Essential Resources.");
// Show Window to Import TMP Essential Resources
return;
}
for (int i = 0; i < targets.Length; i++)
{
Object target = targets[i];
// Make sure the selection is a font file
if (target == null || target.GetType() != typeof(Font))
{
Debug.LogWarning("Selected Object [" + target.name + "] is not a Font file. A Font file must be selected in order to create a Font Asset.", target);
continue;
}
CreateFontAssetFromSelectedObject(target, renderMode);
}
}
static void CreateFontAssetFromSelectedObject(Object target, GlyphRenderMode renderMode)
{
Font font = (Font)target;
string sourceFontFilePath = AssetDatabase.GetAssetPath(target);
string folderPath = Path.GetDirectoryName(sourceFontFilePath);
string assetName = Path.GetFileNameWithoutExtension(sourceFontFilePath);
string newAssetFilePathWithName;
;
switch (renderMode)
{
case GlyphRenderMode.SMOOTH:
newAssetFilePathWithName = AssetDatabase.GenerateUniqueAssetPath(folderPath + "/" + assetName + " Bitmap.asset");
break;
#if TEXTCORE_FONT_ENGINE_1_5_OR_NEWER
case GlyphRenderMode.COLOR:
newAssetFilePathWithName = AssetDatabase.GenerateUniqueAssetPath(folderPath + "/" + assetName + " Color.asset");
break;
#endif
case GlyphRenderMode.SDFAA:
default:
newAssetFilePathWithName = AssetDatabase.GenerateUniqueAssetPath(folderPath + "/" + assetName + " SDF.asset");
break;
}
// Initialize FontEngine
FontEngine.InitializeFontEngine();
// Load Font Face
if (FontEngine.LoadFontFace(font, 90) != FontEngineError.Success)
{
Debug.LogWarning("Unable to load font face for [" + font.name + "]. Make sure \"Include Font Data\" is enabled in the Font Import Settings.", font);
return;
}
// Create new Font Asset
TMP_FontAsset fontAsset = ScriptableObject.CreateInstance<TMP_FontAsset>();
AssetDatabase.CreateAsset(fontAsset, newAssetFilePathWithName);
fontAsset.version = "1.1.0";
fontAsset.faceInfo = FontEngine.GetFaceInfo();
// Set font reference and GUID
fontAsset.sourceFontFile = font;
fontAsset.m_SourceFontFileGUID = AssetDatabase.AssetPathToGUID(sourceFontFilePath);
fontAsset.m_SourceFontFile_EditorRef = font;
fontAsset.atlasPopulationMode = AtlasPopulationMode.Dynamic;
fontAsset.clearDynamicDataOnBuild = TMP_Settings.clearDynamicDataOnBuild;
// Get all font features
//fontAsset.ImportFontFeatures();
// Default atlas resolution is 1024 x 1024.
fontAsset.atlasTextures = new Texture2D[1];
int atlasWidth = fontAsset.atlasWidth = 1024;
int atlasHeight = fontAsset.atlasHeight = 1024;
int atlasPadding = fontAsset.atlasPadding = 9;
Texture2D texture;
Material mat;
Shader shader;
int packingModifier;
switch (renderMode)
{
case GlyphRenderMode.SMOOTH:
fontAsset.atlasRenderMode = GlyphRenderMode.SMOOTH;
texture = new Texture2D(1, 1, TextureFormat.Alpha8, false);
shader = Shader.Find("TextMeshPro/Bitmap");
packingModifier = 0;
mat = new Material(shader);
break;
#if TEXTCORE_FONT_ENGINE_1_5_OR_NEWER
case GlyphRenderMode.COLOR:
fontAsset.atlasRenderMode = GlyphRenderMode.COLOR;
texture = new Texture2D(1, 1, TextureFormat.RGBA32, false);
shader = Shader.Find("TextMeshPro/Sprite");
packingModifier = 0;
mat = new Material(shader);
break;
#endif
case GlyphRenderMode.SDFAA:
default:
fontAsset.atlasRenderMode = GlyphRenderMode.SDFAA;
texture = new Texture2D(1, 1, TextureFormat.Alpha8, false);
shader = Shader.Find("TextMeshPro/Distance Field");
packingModifier = 1;
mat = new Material(shader);
mat.SetFloat(ShaderUtilities.ID_GradientScale, atlasPadding + packingModifier);
mat.SetFloat(ShaderUtilities.ID_WeightNormal, fontAsset.normalStyle);
mat.SetFloat(ShaderUtilities.ID_WeightBold, fontAsset.boldStyle);
break;
}
texture.name = assetName + " Atlas";
mat.name = texture.name + " Material";
fontAsset.atlasTextures[0] = texture;
AssetDatabase.AddObjectToAsset(texture, fontAsset);
fontAsset.freeGlyphRects = new List<GlyphRect>() { new GlyphRect(0, 0, atlasWidth - packingModifier, atlasHeight - packingModifier) };
fontAsset.usedGlyphRects = new List<GlyphRect>();
mat.SetTexture(ShaderUtilities.ID_MainTex, texture);
mat.SetFloat(ShaderUtilities.ID_TextureWidth, atlasWidth);
mat.SetFloat(ShaderUtilities.ID_TextureHeight, atlasHeight);
fontAsset.material = mat;
AssetDatabase.AddObjectToAsset(mat, fontAsset);
// Add Font Asset Creation Settings
fontAsset.creationSettings = new FontAssetCreationSettings(fontAsset.m_SourceFontFileGUID, (int)fontAsset.faceInfo.pointSize, 0, atlasPadding, 0, 1024, 1024, 7, string.Empty, (int)renderMode);
// Not sure if this is still necessary in newer versions of Unity.
//EditorUtility.SetDirty(fontAsset);
AssetDatabase.SaveAssets();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7496af95dfe67cf429ac65edaaf99106
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,300 @@
using UnityEngine;
using UnityEngine.UI;
using UnityEditor;
using UnityEditor.UI;
using UnityEditor.AnimatedValues;
namespace TMPro.EditorUtilities
{
[CanEditMultipleObjects]
[CustomEditor(typeof(TMP_InputField), true)]
public class TMP_InputFieldEditor : SelectableEditor
{
private struct m_foldout
{ // Track Inspector foldout panel states, globally.
public static bool textInput = true;
public static bool fontSettings = true;
public static bool extraSettings = true;
//public static bool shadowSetting = false;
//public static bool materialEditor = true;
}
SerializedProperty m_TextViewport;
SerializedProperty m_TextComponent;
SerializedProperty m_Text;
SerializedProperty m_ContentType;
SerializedProperty m_LineType;
SerializedProperty m_LineLimit;
SerializedProperty m_InputType;
SerializedProperty m_CharacterValidation;
SerializedProperty m_InputValidator;
SerializedProperty m_RegexValue;
SerializedProperty m_KeyboardType;
SerializedProperty m_CharacterLimit;
SerializedProperty m_CaretBlinkRate;
SerializedProperty m_CaretWidth;
SerializedProperty m_CaretColor;
SerializedProperty m_CustomCaretColor;
SerializedProperty m_SelectionColor;
SerializedProperty m_HideMobileKeyboard;
SerializedProperty m_HideMobileInput;
SerializedProperty m_Placeholder;
SerializedProperty m_VerticalScrollbar;
SerializedProperty m_ScrollbarScrollSensitivity;
SerializedProperty m_OnValueChanged;
SerializedProperty m_OnEndEdit;
SerializedProperty m_OnSelect;
SerializedProperty m_OnDeselect;
SerializedProperty m_ReadOnly;
SerializedProperty m_RichText;
SerializedProperty m_RichTextEditingAllowed;
SerializedProperty m_ResetOnDeActivation;
SerializedProperty m_KeepTextSelectionVisible;
SerializedProperty m_RestoreOriginalTextOnEscape;
SerializedProperty m_ShouldActivateOnSelect;
SerializedProperty m_OnFocusSelectAll;
SerializedProperty m_GlobalPointSize;
SerializedProperty m_GlobalFontAsset;
AnimBool m_CustomColor;
//TMP_InputValidator m_ValidationScript;
protected override void OnEnable()
{
base.OnEnable();
m_TextViewport = serializedObject.FindProperty("m_TextViewport");
m_TextComponent = serializedObject.FindProperty("m_TextComponent");
m_Text = serializedObject.FindProperty("m_Text");
m_ContentType = serializedObject.FindProperty("m_ContentType");
m_LineType = serializedObject.FindProperty("m_LineType");
m_LineLimit = serializedObject.FindProperty("m_LineLimit");
m_InputType = serializedObject.FindProperty("m_InputType");
m_CharacterValidation = serializedObject.FindProperty("m_CharacterValidation");
m_InputValidator = serializedObject.FindProperty("m_InputValidator");
m_RegexValue = serializedObject.FindProperty("m_RegexValue");
m_KeyboardType = serializedObject.FindProperty("m_KeyboardType");
m_CharacterLimit = serializedObject.FindProperty("m_CharacterLimit");
m_CaretBlinkRate = serializedObject.FindProperty("m_CaretBlinkRate");
m_CaretWidth = serializedObject.FindProperty("m_CaretWidth");
m_CaretColor = serializedObject.FindProperty("m_CaretColor");
m_CustomCaretColor = serializedObject.FindProperty("m_CustomCaretColor");
m_SelectionColor = serializedObject.FindProperty("m_SelectionColor");
m_HideMobileKeyboard = serializedObject.FindProperty("m_HideSoftKeyboard");
m_HideMobileInput = serializedObject.FindProperty("m_HideMobileInput");
m_Placeholder = serializedObject.FindProperty("m_Placeholder");
m_VerticalScrollbar = serializedObject.FindProperty("m_VerticalScrollbar");
m_ScrollbarScrollSensitivity = serializedObject.FindProperty("m_ScrollSensitivity");
m_OnValueChanged = serializedObject.FindProperty("m_OnValueChanged");
m_OnEndEdit = serializedObject.FindProperty("m_OnEndEdit");
m_OnSelect = serializedObject.FindProperty("m_OnSelect");
m_OnDeselect = serializedObject.FindProperty("m_OnDeselect");
m_ReadOnly = serializedObject.FindProperty("m_ReadOnly");
m_RichText = serializedObject.FindProperty("m_RichText");
m_RichTextEditingAllowed = serializedObject.FindProperty("m_isRichTextEditingAllowed");
m_ResetOnDeActivation = serializedObject.FindProperty("m_ResetOnDeActivation");
m_KeepTextSelectionVisible = serializedObject.FindProperty("m_KeepTextSelectionVisible");
m_RestoreOriginalTextOnEscape = serializedObject.FindProperty("m_RestoreOriginalTextOnEscape");
m_OnFocusSelectAll = serializedObject.FindProperty("m_OnFocusSelectAll");
m_ShouldActivateOnSelect = serializedObject.FindProperty("m_ShouldActivateOnSelect");
m_GlobalPointSize = serializedObject.FindProperty("m_GlobalPointSize");
m_GlobalFontAsset = serializedObject.FindProperty("m_GlobalFontAsset");
m_CustomColor = new AnimBool(m_CustomCaretColor.boolValue);
m_CustomColor.valueChanged.AddListener(Repaint);
}
protected override void OnDisable()
{
base.OnDisable();
m_CustomColor.valueChanged.RemoveListener(Repaint);
}
public override void OnInspectorGUI()
{
serializedObject.Update();
base.OnInspectorGUI();
EditorGUILayout.Space();
EditorGUILayout.PropertyField(m_TextViewport);
EditorGUILayout.PropertyField(m_TextComponent);
TextMeshProUGUI text = null;
if (m_TextComponent != null && m_TextComponent.objectReferenceValue != null)
{
text = m_TextComponent.objectReferenceValue as TextMeshProUGUI;
//if (text.supportRichText)
//{
// EditorGUILayout.HelpBox("Using Rich Text with input is unsupported.", MessageType.Warning);
//}
}
EditorGUI.BeginDisabledGroup(m_TextComponent == null || m_TextComponent.objectReferenceValue == null);
// TEXT INPUT BOX
EditorGUILayout.PropertyField(m_Text);
// INPUT FIELD SETTINGS
#region INPUT FIELD SETTINGS
m_foldout.fontSettings = EditorGUILayout.Foldout(m_foldout.fontSettings, "Input Field Settings", true, TMP_UIStyleManager.boldFoldout);
if (m_foldout.fontSettings)
{
EditorGUI.indentLevel++;
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(m_GlobalFontAsset, new GUIContent("Font Asset", "Set the Font Asset for both Placeholder and Input Field text object."));
if (EditorGUI.EndChangeCheck())
{
TMP_InputField inputField = target as TMP_InputField;
inputField.SetGlobalFontAsset(m_GlobalFontAsset.objectReferenceValue as TMP_FontAsset);
}
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(m_GlobalPointSize, new GUIContent("Point Size", "Set the point size of both Placeholder and Input Field text object."));
if (EditorGUI.EndChangeCheck())
{
TMP_InputField inputField = target as TMP_InputField;
inputField.SetGlobalPointSize(m_GlobalPointSize.floatValue);
}
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(m_CharacterLimit);
EditorGUILayout.Space();
EditorGUILayout.PropertyField(m_ContentType);
if (!m_ContentType.hasMultipleDifferentValues)
{
EditorGUI.indentLevel++;
if (m_ContentType.enumValueIndex == (int)TMP_InputField.ContentType.Standard ||
m_ContentType.enumValueIndex == (int)TMP_InputField.ContentType.Autocorrected ||
m_ContentType.enumValueIndex == (int)TMP_InputField.ContentType.Custom)
{
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(m_LineType);
if (EditorGUI.EndChangeCheck())
{
if (text != null)
{
if (m_LineType.enumValueIndex == (int)TMP_InputField.LineType.SingleLine)
text.textWrappingMode = TextWrappingModes.PreserveWhitespaceNoWrap;
else
{
text.textWrappingMode = TextWrappingModes.Normal;
}
}
}
if (m_LineType.enumValueIndex != (int)TMP_InputField.LineType.SingleLine)
{
EditorGUILayout.PropertyField(m_LineLimit);
}
}
if (m_ContentType.enumValueIndex == (int)TMP_InputField.ContentType.Custom)
{
EditorGUILayout.PropertyField(m_InputType);
EditorGUILayout.PropertyField(m_KeyboardType);
EditorGUILayout.PropertyField(m_CharacterValidation);
if (m_CharacterValidation.enumValueIndex == (int)TMP_InputField.CharacterValidation.Regex)
{
EditorGUILayout.PropertyField(m_RegexValue);
}
else if (m_CharacterValidation.enumValueIndex == (int)TMP_InputField.CharacterValidation.CustomValidator)
{
EditorGUILayout.PropertyField(m_InputValidator);
}
}
EditorGUI.indentLevel--;
}
EditorGUILayout.Space();
EditorGUILayout.PropertyField(m_Placeholder);
EditorGUILayout.PropertyField(m_VerticalScrollbar);
if (m_VerticalScrollbar.objectReferenceValue != null)
EditorGUILayout.PropertyField(m_ScrollbarScrollSensitivity);
EditorGUILayout.PropertyField(m_CaretBlinkRate);
EditorGUILayout.PropertyField(m_CaretWidth);
EditorGUILayout.PropertyField(m_CustomCaretColor);
m_CustomColor.target = m_CustomCaretColor.boolValue;
if (EditorGUILayout.BeginFadeGroup(m_CustomColor.faded))
{
EditorGUILayout.PropertyField(m_CaretColor);
}
EditorGUILayout.EndFadeGroup();
EditorGUILayout.PropertyField(m_SelectionColor);
EditorGUI.indentLevel--;
}
#endregion
// CONTROL SETTINGS
#region CONTROL SETTINGS
m_foldout.extraSettings = EditorGUILayout.Foldout(m_foldout.extraSettings, "Control Settings", true, TMP_UIStyleManager.boldFoldout);
if (m_foldout.extraSettings)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_OnFocusSelectAll, new GUIContent("OnFocus - Select All", "Should all the text be selected when the Input Field is selected?"));
EditorGUILayout.PropertyField(m_ResetOnDeActivation, new GUIContent("Reset On Deactivation", "Should the Text and Caret position be reset when Input Field looses focus and is Deactivated?"));
EditorGUI.indentLevel++;
GUI.enabled = !m_ResetOnDeActivation.boolValue;
EditorGUILayout.PropertyField(m_KeepTextSelectionVisible, new GUIContent("Keep Text Selection Visible", "Should the text selection remain visible when the input field looses focus and is deactivated?"));
GUI.enabled = true;
EditorGUI.indentLevel--;
EditorGUILayout.PropertyField(m_RestoreOriginalTextOnEscape, new GUIContent("Restore On ESC Key", "Should the original text be restored when pressing ESC? (Property not applicable for HoloLens)"));
EditorGUILayout.PropertyField(m_ShouldActivateOnSelect, new GUIContent("Should Activate On Select", "Determines if the Input Field will be activated when selected."));
EditorGUILayout.PropertyField(m_HideMobileKeyboard, new GUIContent("Hide Soft Keyboard", "Controls the visibility of the mobile virtual keyboard."));
EditorGUI.BeginDisabledGroup(m_HideMobileKeyboard.boolValue);
EditorGUILayout.PropertyField(m_HideMobileInput, new GUIContent("Hide Mobile Input", "Controls the visibility of the editable text field above the mobile virtual keyboard."));
EditorGUI.EndDisabledGroup();
EditorGUILayout.PropertyField(m_ReadOnly);
EditorGUILayout.PropertyField(m_RichText);
EditorGUILayout.PropertyField(m_RichTextEditingAllowed, new GUIContent("Allow Rich Text Editing"));
EditorGUI.indentLevel--;
}
#endregion
EditorGUILayout.Space();
EditorGUILayout.PropertyField(m_OnValueChanged);
EditorGUILayout.PropertyField(m_OnEndEdit);
EditorGUILayout.PropertyField(m_OnSelect);
EditorGUILayout.PropertyField(m_OnDeselect);
EditorGUI.EndDisabledGroup();
serializedObject.ApplyModifiedProperties();
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: aa160f27c3fe4052a5850e21108811b6
timeCreated: 1457861621
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,282 @@
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
internal class TMP_MarkupTagUpdateUtility
{
struct MarkupTagDescriptor
{
public string name;
public string tag;
public string description;
public MarkupTagDescriptor(string name, string tag, string description)
{
this.name = name;
this.tag = tag;
this.description = description;
}
public MarkupTagDescriptor(string name)
{
this.name = name;
this.tag = null;
this.description = null;
}
public static MarkupTagDescriptor linefeed = new MarkupTagDescriptor("\n");
}
private static MarkupTagDescriptor[] m_MarkupTags =
{
new MarkupTagDescriptor("BOLD", "b", "// <b>"),
new MarkupTagDescriptor("SLASH_BOLD", "/b", "// </b>"),
new MarkupTagDescriptor("ITALIC", "i", "// <i>"),
new MarkupTagDescriptor("SLASH_ITALIC", "/i", "// </i>"),
new MarkupTagDescriptor("UNDERLINE", "u", "// <u>"),
new MarkupTagDescriptor("SLASH_UNDERLINE", "/u", "// </u>"),
new MarkupTagDescriptor("STRIKETHROUGH", "s", "// <s>"),
new MarkupTagDescriptor("SLASH_STRIKETHROUGH", "/s", "// </s>"),
new MarkupTagDescriptor("SUBSCRIPT", "sub", "// <sub>"),
new MarkupTagDescriptor("SLASH_SUBSCRIPT", "/sub", "// </sub>"),
new MarkupTagDescriptor("SUPERSCRIPT", "sup", "// <sup>"),
new MarkupTagDescriptor("SLASH_SUPERSCRIPT", "/sup", "// </sup>"),
new MarkupTagDescriptor("MARK", "mark", "// <mark>"),
new MarkupTagDescriptor("SLASH_MARK", "/mark", "// </mark>"),
MarkupTagDescriptor.linefeed,
new MarkupTagDescriptor("COLOR", "color", "// <color>"),
new MarkupTagDescriptor("SLASH_COLOR", "/color", "// </color>"),
new MarkupTagDescriptor("ALPHA", "alpha", "// <alpha>"),
new MarkupTagDescriptor("SLASH_ALPHA", "/alpha", "// </alpha>"),
MarkupTagDescriptor.linefeed,
new MarkupTagDescriptor("FONT", "font", "// <font=\"Name of Font Asset\"> or <font family=\"Arial\" style=\"Regular\">" ),
new MarkupTagDescriptor("SLASH_FONT", "/font", "// </font>"),
new MarkupTagDescriptor("MATERIAL", "material", "// <material=\"Name of Material Preset\"> or as attribute <font=\"Name of font asset\" material=\"Name of material\">"),
new MarkupTagDescriptor("SLASH_MATERIAL", "/material", "// </material>"),
new MarkupTagDescriptor("SIZE", "size", "// <size>"),
new MarkupTagDescriptor("SLASH_SIZE", "/size", "// </size>"),
new MarkupTagDescriptor("FONT_WEIGHT", "font-weight", "// <font-weight>"),
new MarkupTagDescriptor("SLASH_FONT_WEIGHT", "/font-weight", "// </font-weight>"),
new MarkupTagDescriptor("SCALE", "scale", "// <scale>"),
new MarkupTagDescriptor("SLASH_SCALE", "/scale", "// </scale>"),
MarkupTagDescriptor.linefeed,
new MarkupTagDescriptor("SPRITE", "sprite", "// <sprite>"),
new MarkupTagDescriptor("STYLE", "style", "// <style>"),
new MarkupTagDescriptor("SLASH_STYLE", "/style", "// </style>"),
new MarkupTagDescriptor("GRADIENT", "gradient", "// <gradient>"),
new MarkupTagDescriptor("SLASH_GRADIENT", "/gradient", "// </gradient>"),
MarkupTagDescriptor.linefeed,
new MarkupTagDescriptor("A", "a", "// <a>"),
new MarkupTagDescriptor("SLASH_A", "/a", "// </a>"),
new MarkupTagDescriptor("LINK", "link", "// <link>"),
new MarkupTagDescriptor("SLASH_LINK", "/link", "// </link>"),
MarkupTagDescriptor.linefeed,
new MarkupTagDescriptor("POSITION", "pos", "// <pos>"),
new MarkupTagDescriptor("SLASH_POSITION", "/pos", "// </pos>"),
new MarkupTagDescriptor("VERTICAL_OFFSET", "voffset","// <voffset>"),
new MarkupTagDescriptor("SLASH_VERTICAL_OFFSET", "/voffset", "// </voffset>"),
new MarkupTagDescriptor("ROTATE", "rotate", "// <rotate>"),
new MarkupTagDescriptor("SLASH_ROTATE", "/rotate", "// </rotate>"),
new MarkupTagDescriptor("TRANSFORM", "transform","// <transform=\"position, rotation, scale\">"),
new MarkupTagDescriptor("SLASH_TRANSFORM", "/transform", "// </transform>"),
new MarkupTagDescriptor("SPACE", "space", "// <space>"),
new MarkupTagDescriptor("SLASH_SPACE", "/space", "// </space>"),
new MarkupTagDescriptor("CHARACTER_SPACE", "cspace", "// <cspace>"),
new MarkupTagDescriptor("SLASH_CHARACTER_SPACE", "/cspace", "// </cspace>"),
new MarkupTagDescriptor("MONOSPACE", "mspace", "// <mspace>"),
new MarkupTagDescriptor("SLASH_MONOSPACE", "/mspace", "// </mspace>"),
new MarkupTagDescriptor("CHARACTER_SPACING", "character-spacing", "// <character-spacing>"),
new MarkupTagDescriptor("SLASH_CHARACTER_SPACING", "/character-spacing", "// </character-spacing>"),
MarkupTagDescriptor.linefeed,
new MarkupTagDescriptor("ALIGN", "align", "// <align>"),
new MarkupTagDescriptor("SLASH_ALIGN", "/align", "// </align>"),
new MarkupTagDescriptor("WIDTH", "width", "// <width>"),
new MarkupTagDescriptor("SLASH_WIDTH", "/width", "// </width>"),
new MarkupTagDescriptor("MARGIN", "margin", "// <margin>"),
new MarkupTagDescriptor("SLASH_MARGIN", "/margin", "// </margin>"),
new MarkupTagDescriptor("MARGIN_LEFT", "margin-left", "// <margin-left>"),
new MarkupTagDescriptor("MARGIN_RIGHT", "margin-right", "// <margin-right>"),
new MarkupTagDescriptor("INDENT", "indent", "// <indent>"),
new MarkupTagDescriptor("SLASH_INDENT", "/indent", "// </indent>"),
new MarkupTagDescriptor("LINE_INDENT", "line-indent", "// <line-indent>"),
new MarkupTagDescriptor("SLASH_LINE_INDENT", "/line-indent", "// </line-indent>"),
new MarkupTagDescriptor("LINE_HEIGHT", "line-height", "// <line-height>"),
new MarkupTagDescriptor("SLASH_LINE_HEIGHT", "/line-height", "// </line-height>"),
MarkupTagDescriptor.linefeed,
new MarkupTagDescriptor("NO_BREAK", "nobr", "// <nobr>"),
new MarkupTagDescriptor("SLASH_NO_BREAK", "/nobr", "// </nobr>"),
new MarkupTagDescriptor("NO_PARSE", "noparse","// <noparse>"),
new MarkupTagDescriptor("SLASH_NO_PARSE", "/noparse", "// </noparse>"),
new MarkupTagDescriptor("PAGE", "page", "// <page>"),
new MarkupTagDescriptor("SLASH_PAGE", "/page", "// </page>"),
MarkupTagDescriptor.linefeed,
new MarkupTagDescriptor("ACTION", "action", "// <action>"),
new MarkupTagDescriptor("SLASH_ACTION", "/action", "// </action>"),
MarkupTagDescriptor.linefeed,
new MarkupTagDescriptor("CLASS", "class", "// <class>"),
new MarkupTagDescriptor("TABLE", "table", "// <table>"),
new MarkupTagDescriptor("SLASH_TABLE", "/table", "// </table>"),
new MarkupTagDescriptor("TH", "th", "// <th>"),
new MarkupTagDescriptor("SLASH_TH", "/th", "// </th>"),
new MarkupTagDescriptor("TR", "tr", "// <tr>"),
new MarkupTagDescriptor("SLASH_TR", "/tr", "// </tr>"),
new MarkupTagDescriptor("TD", "td", "// <td>"),
new MarkupTagDescriptor("SLASH_TD", "/td", "// </td>"),
MarkupTagDescriptor.linefeed,
new MarkupTagDescriptor("// Text Styles"),
new MarkupTagDescriptor("LOWERCASE", "lowercase", "// <lowercase>"),
new MarkupTagDescriptor("SLASH_LOWERCASE", "/lowercase", "// </lowercase>"),
new MarkupTagDescriptor("ALLCAPS", "allcaps", "// <allcaps>"),
new MarkupTagDescriptor("SLASH_ALLCAPS", "/allcaps", "// </allcaps>"),
new MarkupTagDescriptor("UPPERCASE", "uppercase", "// <uppercase>"),
new MarkupTagDescriptor("SLASH_UPPERCASE", "/uppercase", "// </uppercase>"),
new MarkupTagDescriptor("SMALLCAPS", "smallcaps", "// <smallcaps>"),
new MarkupTagDescriptor("SLASH_SMALLCAPS", "/smallcaps", "// </smallcaps>"),
new MarkupTagDescriptor("CAPITALIZE", "capitalize", "// <capitalize>"),
new MarkupTagDescriptor("SLASH_CAPITALIZE", "/capitalize", "// </capitalize>"),
MarkupTagDescriptor.linefeed,
new MarkupTagDescriptor("// Font Features"),
new MarkupTagDescriptor("LIGA", "liga", "// <liga>"),
new MarkupTagDescriptor("SLASH_LIGA", "/liga", "// </liga>"),
new MarkupTagDescriptor("FRAC", "frac", "// <frac>"),
new MarkupTagDescriptor("SLASH_FRAC", "/frac", "// </frac>"),
MarkupTagDescriptor.linefeed,
new MarkupTagDescriptor("// Attributes"),
new MarkupTagDescriptor("NAME", "name", "// <sprite name=\"Name of Sprite\">"),
new MarkupTagDescriptor("INDEX", "index", "// <sprite index=7>"),
new MarkupTagDescriptor("TINT", "tint", "// <tint=bool>"),
new MarkupTagDescriptor("ANIM", "anim", "// <anim=\"first frame, last frame, frame rate\">"),
new MarkupTagDescriptor("HREF", "href", "// <a href=\"url\">text to be displayed.</a>"),
new MarkupTagDescriptor("ANGLE", "angle", "// <i angle=\"40\">Italic Slant Angle</i>"),
new MarkupTagDescriptor("FAMILY", "family", "// <font family=\"Arial\">"),
MarkupTagDescriptor.linefeed,
new MarkupTagDescriptor("// Named Colors"),
new MarkupTagDescriptor("RED", "red",""),
new MarkupTagDescriptor("GREEN", "green", ""),
new MarkupTagDescriptor("BLUE", "blue", ""),
new MarkupTagDescriptor("WHITE", "white", ""),
new MarkupTagDescriptor("BLACK", "black", ""),
new MarkupTagDescriptor("CYAN", "cyna", ""),
new MarkupTagDescriptor("MAGENTA", "magenta", ""),
new MarkupTagDescriptor("YELLOW", "yellow", ""),
new MarkupTagDescriptor("ORANGE", "orange", ""),
new MarkupTagDescriptor("PURPLE", "purple", ""),
MarkupTagDescriptor.linefeed,
new MarkupTagDescriptor("// Unicode Characters"),
new MarkupTagDescriptor("BR", "br", "// <br> Line Feed (LF) \\u0A"),
new MarkupTagDescriptor("ZWSP", "zwsp", "// <zwsp> Zero Width Space \\u200B"),
new MarkupTagDescriptor("NBSP", "nbsp", "// <nbsp> Non Breaking Space \\u00A0"),
new MarkupTagDescriptor("SHY", "shy", "// <shy> Soft Hyphen \\u00AD"),
new MarkupTagDescriptor("ZWJ", "zwj", "// <zwj> Zero Width Joiner \\u200D"),
new MarkupTagDescriptor("WJ", "wj", "// <wj> Word Joiner \\u2060"),
MarkupTagDescriptor.linefeed,
new MarkupTagDescriptor("// Alignment"),
new MarkupTagDescriptor("LEFT", "left", "// <align=left>"),
new MarkupTagDescriptor("RIGHT", "right", "// <align=right>"),
new MarkupTagDescriptor("CENTER", "center", "// <align=center>"),
new MarkupTagDescriptor("JUSTIFIED", "justified", "// <align=justified>"),
new MarkupTagDescriptor("FLUSH", "flush", "// <align=flush>"),
MarkupTagDescriptor.linefeed,
new MarkupTagDescriptor("// Prefix and Unit suffix"),
new MarkupTagDescriptor("NONE", "none", ""),
new MarkupTagDescriptor("PLUS", "+", ""),
new MarkupTagDescriptor("MINUS", "-", ""),
new MarkupTagDescriptor("PX", "px", ""),
new MarkupTagDescriptor("PLUS_PX", "+px", ""),
new MarkupTagDescriptor("MINUS_PX", "-px", ""),
new MarkupTagDescriptor("EM", "em", ""),
new MarkupTagDescriptor("PLUS_EM", "+em", ""),
new MarkupTagDescriptor("MINUS_EM", "-em", ""),
new MarkupTagDescriptor("PCT", "pct", ""),
new MarkupTagDescriptor("PLUS_PCT", "+pct", ""),
new MarkupTagDescriptor("MINUS_PCT", "-pct", ""),
new MarkupTagDescriptor("PERCENTAGE", "%", ""),
new MarkupTagDescriptor("PLUS_PERCENTAGE", "+%", ""),
new MarkupTagDescriptor("MINUS_PERCENTAGE", "-%", ""),
new MarkupTagDescriptor("HASH", "#", "// #"),
MarkupTagDescriptor.linefeed,
new MarkupTagDescriptor("TRUE", "true", ""),
new MarkupTagDescriptor("FALSE", "false", ""),
MarkupTagDescriptor.linefeed,
new MarkupTagDescriptor("INVALID", "invalid", ""),
MarkupTagDescriptor.linefeed,
new MarkupTagDescriptor("NORMAL", "normal", "// <style=\"Normal\">"),
new MarkupTagDescriptor("DEFAULT", "default", "// <font=\"Default\">"),
};
[MenuItem("Window/TextMeshPro/Internal/Update Markup Tag Hash Codes", false, 2200, true)]
static void UpdateMarkupTagHashCodes()
{
Dictionary<int, MarkupTagDescriptor> markupHashCodes = new Dictionary<int, MarkupTagDescriptor>();
string output = string.Empty;
for (int i = 0; i < m_MarkupTags.Length; i++)
{
MarkupTagDescriptor descriptor = m_MarkupTags[i];
int hashCode = descriptor.tag == null ? 0 : GetHashCodeCaseInSensitive(descriptor.tag);
if (descriptor.name == "\n")
output += "\n";
else if (hashCode == 0)
output += descriptor.name + "\n";
else
{
output += descriptor.name + " = " + hashCode + ",\t" + descriptor.description + "\n";
if (markupHashCodes.ContainsKey(hashCode) == false)
markupHashCodes.Add(hashCode, descriptor);
else
Debug.Log("[" + descriptor.name + "] with HashCode [" + hashCode + "] collides with [" + markupHashCodes[hashCode].name + "].");
}
}
Debug.Log(output);
}
/// <summary>
/// Table used to convert character to uppercase.
/// </summary>
const string k_lookupStringU = "-------------------------------- !-#$%&-()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[-]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~-";
/// <summary>
/// Get uppercase version of this ASCII character.
/// </summary>
public static char ToUpperFast(char c)
{
if (c > k_lookupStringU.Length - 1)
return c;
return k_lookupStringU[c];
}
public static int GetHashCodeCaseInSensitive(string s)
{
int hashCode = 5381;
for (int i = 0; i < s.Length; i++)
hashCode = (hashCode << 5) + hashCode ^ ToUpperFast(s[i]);
return hashCode;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 225b67dcce9247b4c806e435b34695d2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 68eedd4e5b33b37429c02c4add0036fe
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,35 @@
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using System.IO;
namespace TMPro
{
public class TMP_PostBuildProcessHandler
{
[PostProcessBuildAttribute(10000)]
public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject)
{
if (target == BuildTarget.iOS)
{
// Try loading the TMP Settings
TMP_Settings settings = Resources.Load<TMP_Settings>("TMP Settings");
if (settings == null || TMP_Settings.enableEmojiSupport == false)
return;
string file = Path.Combine(pathToBuiltProject, "Trampoline", "Classes/UI/Keyboard.mm");
if (!File.Exists(file))
{
file = Path.Combine(pathToBuiltProject, "Classes/UI/Keyboard.mm");
}
string content = File.ReadAllText(file);
content = content.Replace("FILTER_EMOJIS_IOS_KEYBOARD 1", "FILTER_EMOJIS_IOS_KEYBOARD 0");
File.WriteAllText(file, content);
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 6fdea2af3daa40fe8f88e5e9cfc17abb
timeCreated: 1479886230
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,30 @@
using UnityEngine;
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
namespace TMPro
{
public class TMP_PreBuildProcessor : IPreprocessBuildWithReport
{
public int callbackOrder { get { return 0; } }
public void OnPreprocessBuild(BuildReport report)
{
// Find all font assets in the project
string searchPattern = "t:TMP_FontAsset";
string[] fontAssetGUIDs = AssetDatabase.FindAssets(searchPattern);
for (int i = 0; i < fontAssetGUIDs.Length; i++)
{
string fontAssetPath = AssetDatabase.GUIDToAssetPath(fontAssetGUIDs[i]);
TMP_FontAsset fontAsset = AssetDatabase.LoadAssetAtPath<TMP_FontAsset>(fontAssetPath);
if (fontAsset != null && (fontAsset.atlasPopulationMode == AtlasPopulationMode.Dynamic || fontAsset.atlasPopulationMode == AtlasPopulationMode.DynamicOS) && fontAsset.clearDynamicDataOnBuild && fontAsset.atlasTexture.width != 0)
{
fontAsset.ClearCharacterAndGlyphTablesInternal();
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bf8befe3c500aa84b9ce3860a226cf41
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,43 @@
#if !UNITY_2018_3_OR_NEWER
using UnityEditor;
namespace TMPro
{
public static class TMP_ProjectTextSettings
{
// Open Project Text Settings
[MenuItem("Edit/Project Settings/TextMeshPro Settings", false, 309)]
public static void SelectProjectTextSettings()
{
TMP_Settings textSettings = TMP_Settings.instance;
if (textSettings)
{
Selection.activeObject = textSettings;
// TODO: Do we want to ping the Project Text Settings asset in the Project Inspector
EditorUtility.FocusProjectWindow();
EditorGUIUtility.PingObject(textSettings);
}
else
TMPro_EventManager.RESOURCE_LOAD_EVENT.Add(ON_RESOURCES_LOADED);
}
// Event received when TMP resources have been loaded.
static void ON_RESOURCES_LOADED()
{
TMPro_EventManager.RESOURCE_LOAD_EVENT.Remove(ON_RESOURCES_LOADED);
TMP_Settings textSettings = TMP_Settings.instance;
Selection.activeObject = textSettings;
// TODO: Do we want to ping the Project Text Settings asset in the Project Inspector
EditorUtility.FocusProjectWindow();
EditorGUIUtility.PingObject(textSettings);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0e751e877ed14d71a6b8e63ac54949cf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,112 @@
using System.Collections;
using UnityEditor;
using UnityEngine;
namespace TMPro.EditorUtilities
{
/*
[InitializeOnLoad]
class EssentialResourcesManager
{
private const string s_TMPShaderIncludeGUID = "407bc68d299748449bbf7f48ee690f8d";
const string k_EssentialResourcesShaderVersionCheckKey = "TMP.EssentialResources.ShaderVersionCheck";
static EssentialResourcesManager()
{
bool shaderSearched = SessionState.GetBool(k_EssentialResourcesShaderVersionCheckKey, false);
if (!EditorApplication.isPlayingOrWillChangePlaymode && !shaderSearched)
CheckShaderVersions();
}
static void CheckShaderVersions()
{
// Get path to TMP shader include file.
string assetPath = AssetDatabase.GUIDToAssetPath(s_TMPShaderIncludeGUID);
if (string.IsNullOrEmpty(assetPath))
return;
AssetImporter importer = AssetImporter.GetAtPath(assetPath);
if (importer != null && string.IsNullOrEmpty(importer.userData))
{
// Show Shader Import Window
TMP_EditorCoroutine.StartCoroutine(ShowShaderPackageImporterWindow());
}
SessionState.SetBool(k_EssentialResourcesShaderVersionCheckKey, true);
}
static IEnumerator ShowShaderPackageImporterWindow()
{
yield return new WaitForSeconds(5.0f);
TMP_ShaderPackageImporterWindow.ShowPackageImporterWindow();
}
}
*/
/*
//[InitializeOnLoad]
class TMP_ResourcesLoader
{
/// <summary>
/// Function to pre-load the TMP Resources
/// </summary>
public static void LoadTextMeshProResources()
{
//TMP_Settings.LoadDefaultSettings();
//TMP_StyleSheet.LoadDefaultStyleSheet();
}
static TMP_ResourcesLoader()
{
//Debug.Log("Loading TMP Resources...");
// Get current targetted platform
//string Settings = PlayerSettings.GetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone);
//TMPro.TMP_Settings.LoadDefaultSettings();
//TMPro.TMP_StyleSheet.LoadDefaultStyleSheet();
}
//[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
//static void OnBeforeSceneLoaded()
//{
//Debug.Log("Before scene is loaded.");
// //TMPro.TMP_Settings.LoadDefaultSettings();
// //TMPro.TMP_StyleSheet.LoadDefaultStyleSheet();
// //ShaderVariantCollection collection = new ShaderVariantCollection();
// //Shader s0 = Shader.Find("TextMeshPro/Mobile/Distance Field");
// //ShaderVariantCollection.ShaderVariant tmp_Variant = new ShaderVariantCollection.ShaderVariant(s0, UnityEngine.Rendering.PassType.Normal, string.Empty);
// //collection.Add(tmp_Variant);
// //collection.WarmUp();
//}
}
//static class TMP_ProjectSettings
//{
// [InitializeOnLoadMethod]
// static void SetProjectDefineSymbols()
// {
// string currentBuildSettings = PlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup);
// //Check for and inject TMP_INSTALLED
// if (!currentBuildSettings.Contains("TMP_PRESENT"))
// {
// PlayerSettings.SetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup, currentBuildSettings + ";TMP_PRESENT");
// }
// }
//}
*/
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 7241c7dc25374fc1a6ab3ef9da79c363
timeCreated: 1465441092
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,789 @@
using UnityEngine;
using UnityEditor;
namespace TMPro.EditorUtilities
{
public class TMP_SDFShaderGUI : TMP_BaseShaderGUI
{
static ShaderFeature s_OutlineFeature, s_UnderlayFeature, s_BevelFeature, s_GlowFeature, s_MaskFeature;
static bool s_Face = true, s_Outline = true, s_Outline2 = true, s_Outline3 = true, s_Underlay = true, s_Lighting = true, s_Glow, s_Bevel, s_Light, s_Bump, s_Env;
static string[]
s_FaceUVSpeedName = { "_FaceUVSpeed" },
s_FaceUvSpeedNames = { "_FaceUVSpeedX", "_FaceUVSpeedY" },
s_OutlineUvSpeedNames = { "_OutlineUVSpeedX", "_OutlineUVSpeedY" },
s_OutlineUvSpeedName = { "_OutlineUVSpeed" };
static TMP_SDFShaderGUI()
{
s_OutlineFeature = new ShaderFeature()
{
undoLabel = "Outline",
keywords = new[] { "OUTLINE_ON" }
};
s_UnderlayFeature = new ShaderFeature()
{
undoLabel = "Underlay",
keywords = new[] { "UNDERLAY_ON", "UNDERLAY_INNER" },
label = new GUIContent("Underlay Type"),
keywordLabels = new[]
{
new GUIContent("None"), new GUIContent("Normal"), new GUIContent("Inner")
}
};
s_BevelFeature = new ShaderFeature()
{
undoLabel = "Bevel",
keywords = new[] { "BEVEL_ON" }
};
s_GlowFeature = new ShaderFeature()
{
undoLabel = "Glow",
keywords = new[] { "GLOW_ON" }
};
s_MaskFeature = new ShaderFeature()
{
undoLabel = "Mask",
keywords = new[] { "MASK_HARD", "MASK_SOFT" },
label = new GUIContent("Mask"),
keywordLabels = new[]
{
new GUIContent("Mask Off"), new GUIContent("Mask Hard"), new GUIContent("Mask Soft")
}
};
}
protected override void DoGUI()
{
bool isSRPMaterial = m_Material.HasProperty(ShaderUtilities.ID_IsoPerimeter);
s_Face = BeginPanel("Face", s_Face);
if (s_Face)
{
DoFacePanel();
}
EndPanel();
// Outline panels
if (isSRPMaterial)
{
DoOutlinePanels();
}
else
{
s_Outline = m_Material.HasProperty(ShaderUtilities.ID_OutlineTex) ? BeginPanel("Outline", s_Outline) : BeginPanel("Outline", s_OutlineFeature, s_Outline);
if (s_Outline)
{
DoOutlinePanel();
}
EndPanel();
if (m_Material.HasProperty(ShaderUtilities.ID_Outline2Color))
{
s_Outline2 = BeginPanel("Outline 2", s_OutlineFeature, s_Outline2);
if (s_Outline2)
{
DoOutline2Panel();
}
EndPanel();
}
}
// Underlay panel
if (m_Material.HasProperty(ShaderUtilities.ID_UnderlayColor))
{
if (isSRPMaterial)
{
s_Underlay = BeginPanel("Underlay", s_Underlay);
if (s_Underlay)
{
DoUnderlayPanel();
}
EndPanel();
}
else
{
s_Underlay = BeginPanel("Underlay", s_UnderlayFeature, s_Underlay);
if (s_Underlay)
{
DoUnderlayPanel();
}
EndPanel();
}
}
// Lighting panel
if (m_Material.HasProperty("_SpecularColor"))
{
if (isSRPMaterial)
DrawLightingPanelSRP();
else
DrawLightingPanelLegacy();
}
else if (m_Material.HasProperty("_SpecColor"))
{
s_Bevel = BeginPanel("Bevel", s_Bevel);
if (s_Bevel)
{
DoBevelPanel();
}
EndPanel();
s_Light = BeginPanel("Surface Lighting", s_Light);
if (s_Light)
{
DoSurfaceLightingPanel();
}
EndPanel();
s_Bump = BeginPanel("Bump Map", s_Bump);
if (s_Bump)
{
DoBumpMapPanel();
}
EndPanel();
s_Env = BeginPanel("Environment Map", s_Env);
if (s_Env)
{
DoEnvMapPanel();
}
EndPanel();
}
if (m_Material.HasProperty(ShaderUtilities.ID_GlowColor))
{
s_Glow = BeginPanel("Glow", s_GlowFeature, s_Glow);
if (s_Glow)
{
DoGlowPanel();
}
EndPanel();
}
s_DebugExtended = BeginPanel("Debug Settings", s_DebugExtended);
if (s_DebugExtended)
{
if (isSRPMaterial)
DoDebugPanelSRP();
else
DoDebugPanel();
}
EndPanel();
EditorGUILayout.Space();
EditorGUILayout.Space();
if (isSRPMaterial)
{
m_Editor.RenderQueueField();
m_Editor.EnableInstancingField();
m_Editor.DoubleSidedGIField();
m_Editor.EmissionEnabledProperty();
}
}
private void DrawLightingPanelSRP()
{
s_Lighting = BeginPanel("Lighting", s_Lighting);
if (s_Lighting)
{
s_Bevel = BeginPanel("Bevel", s_Bevel);
if (s_Bevel)
{
DoBevelPanelSRP();
}
EndPanel();
s_Light = BeginPanel("Local Lighting", s_Light);
if (s_Light)
{
DoLocalLightingPanel();
}
EndPanel();
}
EndPanel();
}
private void DrawLightingPanelLegacy()
{
s_Lighting = BeginPanel("Lighting", s_BevelFeature, s_Lighting);
if (s_Lighting)
{
s_Bevel = BeginPanel("Bevel", s_Bevel);
if (s_Bevel)
{
DoBevelPanel();
}
EndPanel();
s_Light = BeginPanel("Local Lighting", s_Light);
if (s_Light)
{
DoLocalLightingPanel();
}
EndPanel();
s_Bump = BeginPanel("Bump Map", s_Bump);
if (s_Bump)
{
DoBumpMapPanel();
}
EndPanel();
s_Env = BeginPanel("Environment Map", s_Env);
if (s_Env)
{
DoEnvMapPanel();
}
EndPanel();
}
EndPanel();
}
void DoFacePanel()
{
EditorGUI.indentLevel += 1;
DoColor("_FaceColor", "Color");
if (m_Material.HasProperty(ShaderUtilities.ID_FaceTex))
{
if (m_Material.HasProperty("_FaceUVSpeedX"))
{
DoTexture2D("_FaceTex", "Texture", true, s_FaceUvSpeedNames);
}
else if (m_Material.HasProperty("_FaceUVSpeed"))
{
DoTexture2D("_FaceTex", "Texture", true, s_FaceUVSpeedName);
}
else
{
DoTexture2D("_FaceTex", "Texture", true);
}
}
if (m_Material.HasProperty("_Softness"))
{
DoSlider("_Softness", "X", new Vector2(0, 1), "Softness");
}
if (m_Material.HasProperty("_OutlineSoftness"))
{
DoSlider("_OutlineSoftness", "Softness");
}
if (m_Material.HasProperty(ShaderUtilities.ID_FaceDilate))
{
DoSlider("_FaceDilate", "Dilate");
if (m_Material.HasProperty(ShaderUtilities.ID_Shininess))
{
DoSlider("_FaceShininess", "Gloss");
}
}
if (m_Material.HasProperty(ShaderUtilities.ID_IsoPerimeter))
{
DoSlider("_IsoPerimeter", "X", new Vector2(-1, 1), "Dilate");
}
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoOutlinePanel()
{
EditorGUI.indentLevel += 1;
DoColor("_OutlineColor", "Color");
if (m_Material.HasProperty(ShaderUtilities.ID_OutlineTex))
{
if (m_Material.HasProperty("_OutlineUVSpeedX"))
{
DoTexture2D("_OutlineTex", "Texture", true, s_OutlineUvSpeedNames);
}
else if (m_Material.HasProperty("_OutlineUVSpeed"))
{
DoTexture2D("_OutlineTex", "Texture", true, s_OutlineUvSpeedName);
}
else
{
DoTexture2D("_OutlineTex", "Texture", true);
}
}
DoSlider("_OutlineWidth", "Thickness");
if (m_Material.HasProperty("_OutlineShininess"))
{
DoSlider("_OutlineShininess", "Gloss");
}
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoOutlinePanel(int outlineID, string propertyField, string label)
{
EditorGUI.indentLevel += 1;
DoColor("_OutlineColor" + outlineID, label);
if (outlineID != 3)
DoOffset("_OutlineOffset" + outlineID, "Offset");
else
{
if (m_Material.GetFloat(ShaderUtilities.ID_OutlineMode) == 0)
DoOffset("_OutlineOffset" + outlineID, "Offset");
}
DoSlider("_Softness", propertyField, new Vector2(0, 1), "Softness");
DoSlider("_IsoPerimeter", propertyField, new Vector2(-1, 1), "Dilate");
if (outlineID == 3)
{
DoToggle("_OutlineMode", "Outline Mode");
}
if (m_Material.HasProperty("_OutlineShininess"))
{
//DoSlider("_OutlineShininess", "Gloss");
}
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoOutlinePanelWithTexture(int outlineID, string propertyField, string label)
{
EditorGUI.indentLevel += 1;
DoColor("_OutlineColor" + outlineID, label);
if (m_Material.HasProperty(ShaderUtilities.ID_OutlineTex))
{
if (m_Material.HasProperty("_OutlineUVSpeedX"))
{
DoTexture2D("_OutlineTex", "Texture", true, s_OutlineUvSpeedNames);
}
else if (m_Material.HasProperty("_OutlineUVSpeed"))
{
DoTexture2D("_OutlineTex", "Texture", true, s_OutlineUvSpeedName);
}
else
{
DoTexture2D("_OutlineTex", "Texture", true);
}
}
DoOffset("_OutlineOffset" + outlineID, "Offset");
DoSlider("_Softness", propertyField, new Vector2(0, 1), "Softness");
DoSlider("_IsoPerimeter", propertyField, new Vector2(-1, 1), "Dilate");
if (m_Material.HasProperty("_OutlineShininess"))
{
//DoSlider("_OutlineShininess", "Gloss");
}
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoOutline2Panel()
{
EditorGUI.indentLevel += 1;
DoColor("_Outline2Color", "Color");
//if (m_Material.HasProperty(ShaderUtilities.ID_OutlineTex))
//{
// if (m_Material.HasProperty("_OutlineUVSpeedX"))
// {
// DoTexture2D("_OutlineTex", "Texture", true, s_OutlineUvSpeedNames);
// }
// else
// {
// DoTexture2D("_OutlineTex", "Texture", true);
// }
//}
DoSlider("_Outline2Width", "Thickness");
//if (m_Material.HasProperty("_OutlineShininess"))
//{
// DoSlider("_OutlineShininess", "Gloss");
//}
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoOutlinePanels()
{
s_Outline = BeginPanel("Outline 1", s_Outline);
if (s_Outline)
DoOutlinePanelWithTexture(1, "Y", "Color");
EndPanel();
s_Outline2 = BeginPanel("Outline 2", s_Outline2);
if (s_Outline2)
DoOutlinePanel(2, "Z", "Color");
EndPanel();
s_Outline3 = BeginPanel("Outline 3", s_Outline3);
if (s_Outline3)
DoOutlinePanel(3, "W", "Color");
EndPanel();
}
void DoUnderlayPanel()
{
EditorGUI.indentLevel += 1;
if (m_Material.HasProperty(ShaderUtilities.ID_IsoPerimeter))
{
DoColor("_UnderlayColor", "Color");
DoSlider("_UnderlayOffset", "X", new Vector2(-1, 1), "Offset X");
DoSlider("_UnderlayOffset", "Y", new Vector2(-1, 1), "Offset Y");
DoSlider("_UnderlayDilate", new Vector2(-1, 1), "Dilate");
DoSlider("_UnderlaySoftness", new Vector2(0, 1), "Softness");
}
else
{
s_UnderlayFeature.DoPopup(m_Editor, m_Material);
DoColor("_UnderlayColor", "Color");
DoSlider("_UnderlayOffsetX", "Offset X");
DoSlider("_UnderlayOffsetY", "Offset Y");
DoSlider("_UnderlayDilate", "Dilate");
DoSlider("_UnderlaySoftness", "Softness");
}
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
static GUIContent[] s_BevelTypeLabels =
{
new GUIContent("Outer Bevel"),
new GUIContent("Inner Bevel")
};
void DoBevelPanel()
{
EditorGUI.indentLevel += 1;
DoPopup("_ShaderFlags", "Type", s_BevelTypeLabels);
DoSlider("_Bevel", "Amount");
DoSlider("_BevelOffset", "Offset");
DoSlider("_BevelWidth", "Width");
DoSlider("_BevelRoundness", "Roundness");
DoSlider("_BevelClamp", "Clamp");
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoBevelPanelSRP()
{
EditorGUI.indentLevel += 1;
DoPopup("_BevelType", "Type", s_BevelTypeLabels);
DoSlider("_BevelAmount", "Amount");
DoSlider("_BevelOffset", "Offset");
DoSlider("_BevelWidth", "Width");
DoSlider("_BevelRoundness", "Roundness");
DoSlider("_BevelClamp", "Clamp");
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoLocalLightingPanel()
{
EditorGUI.indentLevel += 1;
DoSlider("_LightAngle", "Light Angle");
DoColor("_SpecularColor", "Specular Color");
DoSlider("_SpecularPower", "Specular Power");
DoSlider("_Reflectivity", "Reflectivity Power");
DoSlider("_Diffuse", "Diffuse Shadow");
DoSlider("_Ambient", "Ambient Shadow");
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoSurfaceLightingPanel()
{
EditorGUI.indentLevel += 1;
DoColor("_SpecColor", "Specular Color");
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoBumpMapPanel()
{
EditorGUI.indentLevel += 1;
DoTexture2D("_BumpMap", "Texture");
DoSlider("_BumpFace", "Face");
DoSlider("_BumpOutline", "Outline");
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoEnvMapPanel()
{
EditorGUI.indentLevel += 1;
DoColor("_ReflectFaceColor", "Face Color");
DoColor("_ReflectOutlineColor", "Outline Color");
DoCubeMap("_Cube", "Texture");
DoVector3("_EnvMatrixRotation", "Rotation");
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoGlowPanel()
{
EditorGUI.indentLevel += 1;
DoColor("_GlowColor", "Color");
DoSlider("_GlowOffset", "Offset");
DoSlider("_GlowInner", "Inner");
DoSlider("_GlowOuter", "Outer");
DoSlider("_GlowPower", "Power");
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoDebugPanel()
{
EditorGUI.indentLevel += 1;
DoTexture2D("_MainTex", "Font Atlas");
DoFloat("_GradientScale", "Gradient Scale");
DoFloat("_TextureWidth", "Texture Width");
DoFloat("_TextureHeight", "Texture Height");
EditorGUILayout.Space();
DoFloat("_ScaleX", "Scale X");
DoFloat("_ScaleY", "Scale Y");
if (m_Material.HasProperty(ShaderUtilities.ID_Sharpness))
DoSlider("_Sharpness", "Sharpness");
DoSlider("_PerspectiveFilter", "Perspective Filter");
EditorGUILayout.Space();
DoFloat("_VertexOffsetX", "Offset X");
DoFloat("_VertexOffsetY", "Offset Y");
if (m_Material.HasProperty(ShaderUtilities.ID_MaskCoord))
{
EditorGUILayout.Space();
s_MaskFeature.ReadState(m_Material);
s_MaskFeature.DoPopup(m_Editor, m_Material);
if (s_MaskFeature.Active)
{
DoMaskSubgroup();
}
EditorGUILayout.Space();
DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels);
}
else if (m_Material.HasProperty("_MaskTex"))
{
DoMaskTexSubgroup();
}
else if (m_Material.HasProperty(ShaderUtilities.ID_MaskSoftnessX))
{
EditorGUILayout.Space();
DoFloat("_MaskSoftnessX", "Softness X");
DoFloat("_MaskSoftnessY", "Softness Y");
DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels);
}
if (m_Material.HasProperty(ShaderUtilities.ID_StencilID))
{
EditorGUILayout.Space();
DoFloat("_Stencil", "Stencil ID");
DoFloat("_StencilComp", "Stencil Comp");
}
EditorGUILayout.Space();
EditorGUI.BeginChangeCheck();
bool useRatios = EditorGUILayout.Toggle("Use Ratios", !m_Material.IsKeywordEnabled("RATIOS_OFF"));
if (EditorGUI.EndChangeCheck())
{
m_Editor.RegisterPropertyChangeUndo("Use Ratios");
if (useRatios)
{
m_Material.DisableKeyword("RATIOS_OFF");
}
else
{
m_Material.EnableKeyword("RATIOS_OFF");
}
}
if (m_Material.HasProperty(ShaderUtilities.ShaderTag_CullMode))
{
EditorGUILayout.Space();
DoPopup("_CullMode", "Cull Mode", s_CullingTypeLabels);
}
EditorGUILayout.Space();
EditorGUI.BeginDisabledGroup(true);
DoFloat("_ScaleRatioA", "Scale Ratio A");
DoFloat("_ScaleRatioB", "Scale Ratio B");
DoFloat("_ScaleRatioC", "Scale Ratio C");
EditorGUI.EndDisabledGroup();
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoDebugPanelSRP()
{
EditorGUI.indentLevel += 1;
DoTexture2D("_MainTex", "Font Atlas");
DoFloat("_GradientScale", "Gradient Scale");
//DoFloat("_TextureWidth", "Texture Width");
//DoFloat("_TextureHeight", "Texture Height");
EditorGUILayout.Space();
/*
DoFloat("_ScaleX", "Scale X");
DoFloat("_ScaleY", "Scale Y");
if (m_Material.HasProperty(ShaderUtilities.ID_Sharpness))
DoSlider("_Sharpness", "Sharpness");
DoSlider("_PerspectiveFilter", "Perspective Filter");
EditorGUILayout.Space();
DoFloat("_VertexOffsetX", "Offset X");
DoFloat("_VertexOffsetY", "Offset Y");
if (m_Material.HasProperty(ShaderUtilities.ID_MaskCoord))
{
EditorGUILayout.Space();
s_MaskFeature.ReadState(m_Material);
s_MaskFeature.DoPopup(m_Editor, m_Material);
if (s_MaskFeature.Active)
{
DoMaskSubgroup();
}
EditorGUILayout.Space();
DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels);
}
else if (m_Material.HasProperty("_MaskTex"))
{
DoMaskTexSubgroup();
}
else if (m_Material.HasProperty(ShaderUtilities.ID_MaskSoftnessX))
{
EditorGUILayout.Space();
DoFloat("_MaskSoftnessX", "Softness X");
DoFloat("_MaskSoftnessY", "Softness Y");
DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels);
}
if (m_Material.HasProperty(ShaderUtilities.ID_StencilID))
{
EditorGUILayout.Space();
DoFloat("_Stencil", "Stencil ID");
DoFloat("_StencilComp", "Stencil Comp");
}
EditorGUILayout.Space();
EditorGUI.BeginChangeCheck();
bool useRatios = EditorGUILayout.Toggle("Use Ratios", !m_Material.IsKeywordEnabled("RATIOS_OFF"));
if (EditorGUI.EndChangeCheck())
{
m_Editor.RegisterPropertyChangeUndo("Use Ratios");
if (useRatios)
{
m_Material.DisableKeyword("RATIOS_OFF");
}
else
{
m_Material.EnableKeyword("RATIOS_OFF");
}
}
*/
if (m_Material.HasProperty(ShaderUtilities.ShaderTag_CullMode))
{
EditorGUILayout.Space();
DoPopup("_CullMode", "Cull Mode", s_CullingTypeLabels);
}
EditorGUILayout.Space();
/*
EditorGUI.BeginDisabledGroup(true);
DoFloat("_ScaleRatioA", "Scale Ratio A");
DoFloat("_ScaleRatioB", "Scale Ratio B");
DoFloat("_ScaleRatioC", "Scale Ratio C");
EditorGUI.EndDisabledGroup();
*/
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
void DoMaskSubgroup()
{
DoVector("_MaskCoord", "Mask Bounds", s_XywhVectorLabels);
if (Selection.activeGameObject != null)
{
Renderer renderer = Selection.activeGameObject.GetComponent<Renderer>();
if (renderer != null)
{
Rect rect = EditorGUILayout.GetControlRect();
rect.x += EditorGUIUtility.labelWidth;
rect.width -= EditorGUIUtility.labelWidth;
if (GUI.Button(rect, "Match Renderer Bounds"))
{
FindProperty("_MaskCoord", m_Properties).vectorValue = new Vector4(
0,
0,
Mathf.Round(renderer.bounds.extents.x * 1000) / 1000,
Mathf.Round(renderer.bounds.extents.y * 1000) / 1000
);
}
}
}
if (s_MaskFeature.State == 1)
{
DoFloat("_MaskSoftnessX", "Softness X");
DoFloat("_MaskSoftnessY", "Softness Y");
}
}
void DoMaskTexSubgroup()
{
EditorGUILayout.Space();
DoTexture2D("_MaskTex", "Mask Texture");
DoToggle("_MaskInverse", "Inverse Mask");
DoColor("_MaskEdgeColor", "Edge Color");
DoSlider("_MaskEdgeSoftness", "Edge Softness");
DoSlider("_MaskWipeControl", "Wipe Position");
DoFloat("_MaskSoftnessX", "Softness X");
DoFloat("_MaskSoftnessY", "Softness Y");
DoVector("_ClipRect", "Clip Rect", s_LbrtVectorLabels);
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 8413ca0e506d42a1a4bd9769f204ad16
timeCreated: 1469844718
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,15 @@
using UnityEngine;
using UnityEngine.TextCore.LowLevel;
namespace TMPro
{
class TMP_SerializedPropertyHolder : ScriptableObject
{
public TMP_FontAsset fontAsset;
public uint firstCharacter;
public uint secondCharacter;
public GlyphPairAdjustmentRecord glyphPairAdjustmentRecord = new GlyphPairAdjustmentRecord(new GlyphAdjustmentRecord(), new GlyphAdjustmentRecord());
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9c4a050f089abb04ebd4125e419f4548
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,491 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
#pragma warning disable 0414 // Disabled a few warnings for not yet implemented features.
namespace TMPro.EditorUtilities
{
[CustomEditor(typeof(TMP_Settings))]
public class TMP_SettingsEditor : Editor
{
internal class Styles
{
public static readonly GUIContent defaultFontAssetLabel = new GUIContent("Default Font Asset", "The Font Asset that will be assigned by default to newly created text objects when no Font Asset is specified.");
public static readonly GUIContent defaultFontAssetPathLabel = new GUIContent("Path: Resources/", "The relative path to a Resources folder where the Font Assets and Material Presets are located.\nExample \"Fonts & Materials/\"");
public static readonly GUIContent fallbackFontAssetsLabel = new GUIContent("Fallback Font Assets", "The Font Assets that will be searched to locate and replace missing characters from a given Font Asset.");
public static readonly GUIContent fallbackFontAssetsListLabel = new GUIContent("Font Asset List", "The Font Assets that will be searched to locate and replace missing characters from a given Font Asset.");
public static readonly GUIContent fallbackMaterialSettingsLabel = new GUIContent("Fallback Material Settings");
public static readonly GUIContent matchMaterialPresetLabel = new GUIContent("Match Material Presets");
public static readonly GUIContent hideSubTextObjectsPresetLabel = new GUIContent("Hide Sub Text Objects", "Determines if sub text objects will be hidden in the scene hierarchy. Property change will only take effect after entering or existing play mode.");
public static readonly GUIContent containerDefaultSettingsLabel = new GUIContent("Text Container Default Settings");
public static readonly GUIContent textMeshProLabel = new GUIContent("TextMeshPro");
public static readonly GUIContent textMeshProUiLabel = new GUIContent("TextMeshPro UI");
public static readonly GUIContent enableRaycastTarget = new GUIContent("Enable Raycast Target");
public static readonly GUIContent autoSizeContainerLabel = new GUIContent("Auto Size Text Container", "Set the size of the text container to match the text.");
public static readonly GUIContent isTextObjectScaleStaticLabel = new GUIContent("Is Object Scale Static", "Disables calling InternalUpdate() when enabled. This can improve performance when text object scale is static.");
public static readonly GUIContent textComponentDefaultSettingsLabel = new GUIContent("Text Component Default Settings");
public static readonly GUIContent defaultFontSize = new GUIContent("Default Font Size");
public static readonly GUIContent autoSizeRatioLabel = new GUIContent("Text Auto Size Ratios");
public static readonly GUIContent minLabel = new GUIContent("Min");
public static readonly GUIContent maxLabel = new GUIContent("Max");
public static readonly GUIContent textWrappingModeLabel = new GUIContent("Text Wrapping Mode");
public static readonly GUIContent kerningLabel = new GUIContent("Kerning");
public static readonly GUIContent fontFeaturesLabel = new GUIContent("Font Features", "Font features that should be set by default on the text component.");
public static readonly GUIContent extraPaddingLabel = new GUIContent("Extra Padding");
public static readonly GUIContent tintAllSpritesLabel = new GUIContent("Tint All Sprites");
public static readonly GUIContent parseEscapeCharactersLabel = new GUIContent("Parse Escape Sequence");
public static readonly GUIContent dynamicFontSystemSettingsLabel = new GUIContent("Dynamic Font System Settings");
public static readonly GUIContent getFontFeaturesAtRuntime = new GUIContent("Get Font Features at Runtime", "Determines if OpenType font features should be retrieved from source font files as new characters and glyphs are added to font assets.");
public static readonly GUIContent dynamicAtlasTextureGroup = new GUIContent("Dynamic Atlas Texture Group");
public static readonly GUIContent missingGlyphLabel = new GUIContent("Missing Character Unicode", "The character to be displayed when the requested character is not found in any font asset or fallbacks.");
public static readonly GUIContent clearDynamicDataOnBuildLabel = new GUIContent("Clear Dynamic Data On Build", "Determines if the \"Clear Dynamic Data on Build\" property will be set to true or false on newly created dynamic font assets.");
public static readonly GUIContent disableWarningsLabel = new GUIContent("Disable warnings", "Disable warning messages in the Console.");
public static readonly GUIContent defaultSpriteAssetLabel = new GUIContent("Default Sprite Asset", "The Sprite Asset that will be assigned by default when using the <sprite> tag when no Sprite Asset is specified.");
public static readonly GUIContent missingSpriteCharacterUnicodeLabel = new GUIContent("Missing Sprite Unicode", "The unicode value for the sprite character to be displayed when the requested sprite character is not found in any sprite assets or fallbacks.");
public static readonly GUIContent enableEmojiSupportLabel = new GUIContent("iOS Emoji Support", "Enables Emoji support for Touch Screen Keyboards on target devices.");
//public static readonly GUIContent spriteRelativeScale = new GUIContent("Relative Scaling", "Determines if the sprites will be scaled relative to the primary font asset assigned to the text object or relative to the current font asset.");
public static readonly GUIContent emojifallbackTextAssetsListLabel = new GUIContent("Fallback Emoji Text Assets", "The Text Assets that will be searched to display characters defined as Emojis in the Unicode.");
public static readonly GUIContent spriteAssetsPathLabel = new GUIContent("Path: Resources/", "The relative path to a Resources folder where the Sprite Assets are located.\nExample \"Sprite Assets/\"");
public static readonly GUIContent defaultStyleSheetLabel = new GUIContent("Default Style Sheet", "The Style Sheet that will be used for all text objects in this project.");
public static readonly GUIContent styleSheetResourcePathLabel = new GUIContent("Path: Resources/", "The relative path to a Resources folder where the Style Sheets are located.\nExample \"Style Sheets/\"");
public static readonly GUIContent colorGradientPresetsLabel = new GUIContent("Color Gradient Presets", "The relative path to a Resources folder where the Color Gradient Presets are located.\nExample \"Color Gradient Presets/\"");
public static readonly GUIContent colorGradientsPathLabel = new GUIContent("Path: Resources/", "The relative path to a Resources folder where the Color Gradient Presets are located.\nExample \"Color Gradient Presets/\"");
public static readonly GUIContent lineBreakingLabel = new GUIContent("Line Breaking for Asian languages", "The text assets that contain the Leading and Following characters which define the rules for line breaking with Asian languages.");
public static readonly GUIContent koreanSpecificRules = new GUIContent("Korean Language Options");
}
SerializedProperty m_PropFontAsset;
SerializedProperty m_PropDefaultFontAssetPath;
SerializedProperty m_PropDefaultFontSize;
SerializedProperty m_PropDefaultAutoSizeMinRatio;
SerializedProperty m_PropDefaultAutoSizeMaxRatio;
SerializedProperty m_PropDefaultTextMeshProTextContainerSize;
SerializedProperty m_PropDefaultTextMeshProUITextContainerSize;
SerializedProperty m_PropAutoSizeTextContainer;
SerializedProperty m_PropEnableRaycastTarget;
SerializedProperty m_PropIsTextObjectScaleStatic;
SerializedProperty m_PropSpriteAsset;
SerializedProperty m_PropMissingSpriteCharacterUnicode;
//SerializedProperty m_PropSpriteRelativeScaling;
SerializedProperty m_PropEnableEmojiSupport;
SerializedProperty m_PropSpriteAssetPath;
ReorderableList m_EmojiFallbackTextAssetList;
SerializedProperty m_PropStyleSheet;
SerializedProperty m_PropStyleSheetsResourcePath;
ReorderableList m_GlobalFallbackFontAssetList;
SerializedProperty m_PropColorGradientPresetsPath;
SerializedProperty m_PropMatchMaterialPreset;
SerializedProperty m_PropHideSubTextObjects;
SerializedProperty m_PropTextWrappingMode;
SerializedProperty m_PropFontFeatures;
SerializedProperty m_PropExtraPadding;
SerializedProperty m_PropTintAllSprites;
SerializedProperty m_PropParseEscapeCharacters;
SerializedProperty m_PropMissingGlyphCharacter;
SerializedProperty m_PropClearDynamicDataOnBuild;
//SerializedProperty m_DynamicAtlasTextureManager;
SerializedProperty m_GetFontFeaturesAtRuntime;
SerializedProperty m_PropWarningsDisabled;
SerializedProperty m_PropLeadingCharacters;
SerializedProperty m_PropFollowingCharacters;
SerializedProperty m_PropUseModernHangulLineBreakingRules;
private const string k_UndoRedo = "UndoRedoPerformed";
private bool m_IsFallbackGlyphCacheDirty;
private static readonly string[] k_FontFeatures = new string[] { "kern", "liga", "mark", "mkmk" };
public void OnEnable()
{
if (target == null)
return;
m_PropFontAsset = serializedObject.FindProperty("m_defaultFontAsset");
m_PropDefaultFontAssetPath = serializedObject.FindProperty("m_defaultFontAssetPath");
m_PropDefaultFontSize = serializedObject.FindProperty("m_defaultFontSize");
m_PropDefaultAutoSizeMinRatio = serializedObject.FindProperty("m_defaultAutoSizeMinRatio");
m_PropDefaultAutoSizeMaxRatio = serializedObject.FindProperty("m_defaultAutoSizeMaxRatio");
m_PropDefaultTextMeshProTextContainerSize = serializedObject.FindProperty("m_defaultTextMeshProTextContainerSize");
m_PropDefaultTextMeshProUITextContainerSize = serializedObject.FindProperty("m_defaultTextMeshProUITextContainerSize");
m_PropAutoSizeTextContainer = serializedObject.FindProperty("m_autoSizeTextContainer");
m_PropEnableRaycastTarget = serializedObject.FindProperty("m_EnableRaycastTarget");
m_PropIsTextObjectScaleStatic = serializedObject.FindProperty("m_IsTextObjectScaleStatic");
m_PropSpriteAsset = serializedObject.FindProperty("m_defaultSpriteAsset");
m_PropMissingSpriteCharacterUnicode = serializedObject.FindProperty("m_MissingCharacterSpriteUnicode");
//m_PropSpriteRelativeScaling = serializedObject.FindProperty("m_SpriteRelativeScaling");
m_PropEnableEmojiSupport = serializedObject.FindProperty("m_enableEmojiSupport");
m_PropSpriteAssetPath = serializedObject.FindProperty("m_defaultSpriteAssetPath");
m_PropStyleSheet = serializedObject.FindProperty("m_defaultStyleSheet");
m_PropStyleSheetsResourcePath = serializedObject.FindProperty("m_StyleSheetsResourcePath");
m_PropColorGradientPresetsPath = serializedObject.FindProperty("m_defaultColorGradientPresetsPath");
// Global Fallback ReorderableList
m_GlobalFallbackFontAssetList = new ReorderableList(serializedObject, serializedObject.FindProperty("m_fallbackFontAssets"), true, true, true, true);
m_GlobalFallbackFontAssetList.drawHeaderCallback = rect =>
{
EditorGUI.LabelField(rect, Styles.fallbackFontAssetsListLabel);
};
m_GlobalFallbackFontAssetList.drawElementCallback = (rect, index, isActive, isFocused) =>
{
var element = m_GlobalFallbackFontAssetList.serializedProperty.GetArrayElementAtIndex(index);
rect.y += 2;
EditorGUI.PropertyField(new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight), element, GUIContent.none);
};
m_GlobalFallbackFontAssetList.onChangedCallback = itemList =>
{
m_IsFallbackGlyphCacheDirty = true;
};
// Emoji Fallback ReorderableList
m_EmojiFallbackTextAssetList = new ReorderableList(serializedObject, serializedObject.FindProperty("m_EmojiFallbackTextAssets"), true, true, true, true);
m_EmojiFallbackTextAssetList.drawHeaderCallback = rect =>
{
EditorGUI.LabelField(rect, "Text Asset List");
};
m_EmojiFallbackTextAssetList.drawElementCallback = (rect, index, isActive, isFocused) =>
{
var element = m_EmojiFallbackTextAssetList.serializedProperty.GetArrayElementAtIndex(index);
rect.y += 2;
EditorGUI.PropertyField(new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight), element, GUIContent.none);
};
m_EmojiFallbackTextAssetList.onChangedCallback = itemList =>
{
m_IsFallbackGlyphCacheDirty = true;
};
m_PropMatchMaterialPreset = serializedObject.FindProperty("m_matchMaterialPreset");
m_PropHideSubTextObjects = serializedObject.FindProperty("m_HideSubTextObjects");
m_PropTextWrappingMode = serializedObject.FindProperty("m_TextWrappingMode");
m_PropFontFeatures = serializedObject.FindProperty("m_ActiveFontFeatures");
m_PropExtraPadding = serializedObject.FindProperty("m_enableExtraPadding");
m_PropTintAllSprites = serializedObject.FindProperty("m_enableTintAllSprites");
m_PropParseEscapeCharacters = serializedObject.FindProperty("m_enableParseEscapeCharacters");
m_PropMissingGlyphCharacter = serializedObject.FindProperty("m_missingGlyphCharacter");
m_PropClearDynamicDataOnBuild = serializedObject.FindProperty("m_ClearDynamicDataOnBuild");
m_PropWarningsDisabled = serializedObject.FindProperty("m_warningsDisabled");
//m_DynamicAtlasTextureManager = serializedObject.FindProperty("m_DynamicAtlasTextureGroup");
m_GetFontFeaturesAtRuntime = serializedObject.FindProperty("m_GetFontFeaturesAtRuntime");
m_PropLeadingCharacters = serializedObject.FindProperty("m_leadingCharacters");
m_PropFollowingCharacters = serializedObject.FindProperty("m_followingCharacters");
m_PropUseModernHangulLineBreakingRules = serializedObject.FindProperty("m_UseModernHangulLineBreakingRules");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
string evt_cmd = Event.current.commandName;
m_IsFallbackGlyphCacheDirty = false;
float labelWidth = EditorGUIUtility.labelWidth;
float fieldWidth = EditorGUIUtility.fieldWidth;
// TextMeshPro Font Info Panel
EditorGUI.indentLevel = 0;
// FONT ASSET
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
GUILayout.Label(Styles.defaultFontAssetLabel, EditorStyles.boldLabel);
EditorGUI.indentLevel = 1;
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(m_PropFontAsset, Styles.defaultFontAssetLabel);
if (EditorGUI.EndChangeCheck())
m_IsFallbackGlyphCacheDirty = true;
EditorGUILayout.PropertyField(m_PropDefaultFontAssetPath, Styles.defaultFontAssetPathLabel);
EditorGUI.indentLevel = 0;
EditorGUILayout.Space();
EditorGUILayout.EndVertical();
// FALLBACK FONT ASSETs
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
GUILayout.Label(Styles.fallbackFontAssetsLabel, EditorStyles.boldLabel);
EditorGUI.BeginChangeCheck();
m_GlobalFallbackFontAssetList.DoLayoutList();
if (EditorGUI.EndChangeCheck())
m_IsFallbackGlyphCacheDirty = true;
GUILayout.Label(Styles.fallbackMaterialSettingsLabel, EditorStyles.boldLabel);
EditorGUI.indentLevel = 1;
EditorGUILayout.PropertyField(m_PropMatchMaterialPreset, Styles.matchMaterialPresetLabel);
EditorGUILayout.PropertyField(m_PropHideSubTextObjects, Styles.hideSubTextObjectsPresetLabel);
EditorGUI.indentLevel = 0;
EditorGUILayout.Space();
EditorGUILayout.EndVertical();
// MISSING GLYPHS
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
GUILayout.Label(Styles.dynamicFontSystemSettingsLabel, EditorStyles.boldLabel);
EditorGUI.indentLevel = 1;
EditorGUILayout.PropertyField(m_PropMissingGlyphCharacter, Styles.missingGlyphLabel);
EditorGUILayout.PropertyField(m_PropWarningsDisabled, Styles.disableWarningsLabel);
EditorGUILayout.Space();
EditorGUILayout.PropertyField(m_GetFontFeaturesAtRuntime, Styles.getFontFeaturesAtRuntime);
EditorGUILayout.PropertyField(m_PropClearDynamicDataOnBuild, Styles.clearDynamicDataOnBuildLabel);
//EditorGUILayout.PropertyField(m_DynamicAtlasTextureManager, Styles.dynamicAtlasTextureManager);
EditorGUI.indentLevel = 0;
EditorGUILayout.Space();
EditorGUILayout.EndVertical();
// TEXT OBJECT DEFAULT PROPERTIES
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
GUILayout.Label(Styles.containerDefaultSettingsLabel, EditorStyles.boldLabel);
EditorGUI.indentLevel = 1;
EditorGUILayout.PropertyField(m_PropDefaultTextMeshProTextContainerSize, Styles.textMeshProLabel);
EditorGUILayout.PropertyField(m_PropDefaultTextMeshProUITextContainerSize, Styles.textMeshProUiLabel);
EditorGUILayout.PropertyField(m_PropEnableRaycastTarget, Styles.enableRaycastTarget);
EditorGUILayout.PropertyField(m_PropAutoSizeTextContainer, Styles.autoSizeContainerLabel);
EditorGUILayout.PropertyField(m_PropIsTextObjectScaleStatic, Styles.isTextObjectScaleStaticLabel);
EditorGUI.indentLevel = 0;
EditorGUILayout.Space();
GUILayout.Label(Styles.textComponentDefaultSettingsLabel, EditorStyles.boldLabel);
EditorGUI.indentLevel = 1;
EditorGUILayout.PropertyField(m_PropDefaultFontSize, Styles.defaultFontSize);
EditorGUILayout.BeginHorizontal();
{
EditorGUILayout.PrefixLabel(Styles.autoSizeRatioLabel);
EditorGUIUtility.labelWidth = 32;
EditorGUIUtility.fieldWidth = 10;
EditorGUI.indentLevel = 0;
EditorGUILayout.PropertyField(m_PropDefaultAutoSizeMinRatio, Styles.minLabel);
EditorGUILayout.PropertyField(m_PropDefaultAutoSizeMaxRatio, Styles.maxLabel);
EditorGUI.indentLevel = 1;
}
EditorGUILayout.EndHorizontal();
EditorGUIUtility.labelWidth = labelWidth;
EditorGUIUtility.fieldWidth = fieldWidth;
EditorGUILayout.PropertyField(m_PropTextWrappingMode, Styles.textWrappingModeLabel);
DrawFontFeatures();
EditorGUILayout.PropertyField(m_PropExtraPadding, Styles.extraPaddingLabel);
EditorGUILayout.PropertyField(m_PropTintAllSprites, Styles.tintAllSpritesLabel);
EditorGUILayout.PropertyField(m_PropParseEscapeCharacters, Styles.parseEscapeCharactersLabel);
EditorGUI.indentLevel = 0;
EditorGUILayout.Space();
EditorGUILayout.EndVertical();
// SPRITE ASSET
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
GUILayout.Label(Styles.defaultSpriteAssetLabel, EditorStyles.boldLabel);
EditorGUI.indentLevel = 1;
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(m_PropSpriteAsset, Styles.defaultSpriteAssetLabel);
if (EditorGUI.EndChangeCheck())
m_IsFallbackGlyphCacheDirty = true;
EditorGUILayout.PropertyField(m_PropMissingSpriteCharacterUnicode, Styles.missingSpriteCharacterUnicodeLabel);
EditorGUILayout.PropertyField(m_PropEnableEmojiSupport, Styles.enableEmojiSupportLabel);
//EditorGUILayout.PropertyField(m_PropSpriteRelativeScaling, Styles.spriteRelativeScale);
EditorGUILayout.PropertyField(m_PropSpriteAssetPath, Styles.spriteAssetsPathLabel);
EditorGUI.indentLevel = 0;
EditorGUILayout.Space();
EditorGUILayout.EndVertical();
// EMOJI FALLBACK TEXT ASSETS
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
GUILayout.Label(Styles.emojifallbackTextAssetsListLabel, EditorStyles.boldLabel);
EditorGUI.BeginChangeCheck();
m_EmojiFallbackTextAssetList.DoLayoutList();
if (EditorGUI.EndChangeCheck())
m_IsFallbackGlyphCacheDirty = true;
EditorGUILayout.Space();
EditorGUILayout.EndVertical();
// STYLE SHEET
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
GUILayout.Label(Styles.defaultStyleSheetLabel, EditorStyles.boldLabel);
EditorGUI.indentLevel = 1;
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(m_PropStyleSheet, Styles.defaultStyleSheetLabel);
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
TMP_StyleSheet styleSheet = m_PropStyleSheet.objectReferenceValue as TMP_StyleSheet;
if (styleSheet != null)
styleSheet.RefreshStyles();
}
EditorGUILayout.PropertyField(m_PropStyleSheetsResourcePath, Styles.styleSheetResourcePathLabel);
EditorGUI.indentLevel = 0;
EditorGUILayout.Space();
EditorGUILayout.EndVertical();
// COLOR GRADIENT PRESETS
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
GUILayout.Label(Styles.colorGradientPresetsLabel, EditorStyles.boldLabel);
EditorGUI.indentLevel = 1;
EditorGUILayout.PropertyField(m_PropColorGradientPresetsPath, Styles.colorGradientsPathLabel);
EditorGUI.indentLevel = 0;
EditorGUILayout.Space();
EditorGUILayout.EndVertical();
// LINE BREAKING RULE
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
GUILayout.Label(Styles.lineBreakingLabel, EditorStyles.boldLabel);
EditorGUI.indentLevel = 1;
EditorGUILayout.PropertyField(m_PropLeadingCharacters);
EditorGUILayout.PropertyField(m_PropFollowingCharacters);
EditorGUILayout.Space();
GUILayout.Label(Styles.koreanSpecificRules, EditorStyles.boldLabel);
EditorGUILayout.PropertyField(m_PropUseModernHangulLineBreakingRules, new GUIContent("Use Modern Line Breaking", "Determines if traditional or modern line breaking rules will be used to control line breaking. Traditional line breaking rules use the Leading and Following Character rules whereas Modern uses spaces for line breaking."));
EditorGUI.indentLevel = 0;
EditorGUILayout.Space();
EditorGUILayout.EndVertical();
if (m_IsFallbackGlyphCacheDirty || evt_cmd == k_UndoRedo)
TMP_ResourceManager.RebuildFontAssetCache();
if (serializedObject.ApplyModifiedProperties() || evt_cmd == k_UndoRedo)
{
EditorUtility.SetDirty(target);
TMPro_EventManager.ON_TMP_SETTINGS_CHANGED();
}
}
void DrawFontFeatures()
{
int srcMask = 0;
int featureCount = m_PropFontFeatures.arraySize;
for (int i = 0; i < featureCount; i++)
{
SerializedProperty activeFeatureProperty = m_PropFontFeatures.GetArrayElementAtIndex(i);
for (int j = 0; j < k_FontFeatures.Length; j++)
{
if (activeFeatureProperty.intValue == k_FontFeatures[j].TagToInt())
{
srcMask |= 0x1 << j;
break;
}
}
}
EditorGUI.BeginChangeCheck();
int mask = EditorGUILayout.MaskField(Styles.fontFeaturesLabel, srcMask, k_FontFeatures);
if (EditorGUI.EndChangeCheck())
{
m_PropFontFeatures.ClearArray();
int writeIndex = 0;
for (int i = 0; i < k_FontFeatures.Length; i++)
{
int bit = 0x1 << i;
if ((mask & bit) == bit)
{
m_PropFontFeatures.InsertArrayElementAtIndex(writeIndex);
SerializedProperty newFeature = m_PropFontFeatures.GetArrayElementAtIndex(writeIndex);
newFeature.intValue = k_FontFeatures[i].TagToInt();
writeIndex += 1;
}
}
}
}
}
class TMP_ResourceImporterProvider : SettingsProvider
{
TMP_PackageResourceImporter m_ResourceImporter;
public TMP_ResourceImporterProvider()
: base("Project/TextMesh Pro", SettingsScope.Project)
{
}
public override void OnGUI(string searchContext)
{
// Lazy creation that supports domain reload
if (m_ResourceImporter == null)
m_ResourceImporter = new TMP_PackageResourceImporter(logErrors: false);
m_ResourceImporter.OnGUI();
}
public override void OnDeactivate()
{
if (m_ResourceImporter != null)
m_ResourceImporter.OnDestroy();
}
static UnityEngine.Object GetTMPSettings()
{
return Resources.Load<TMP_Settings>("TMP Settings");
}
[SettingsProviderGroup]
static SettingsProvider[] CreateTMPSettingsProvider()
{
var providers = new List<SettingsProvider> { new TMP_ResourceImporterProvider() };
if (GetTMPSettings() != null)
{
var provider = new AssetSettingsProvider("Project/TextMesh Pro/Settings", GetTMPSettings);
provider.PopulateSearchKeywordsFromGUIContentProperties<TMP_SettingsEditor.Styles>();
providers.Add(provider);
}
return providers.ToArray();
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 0386b6eb838c47138cd51d1c1b879a35
timeCreated: 1436658550
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,978 @@
using UnityEngine;
using UnityEngine.TextCore;
using UnityEditor;
using UnityEditorInternal;
using System.Collections.Generic;
namespace TMPro.EditorUtilities
{
[CustomEditor(typeof(TMP_SpriteAsset))]
public class TMP_SpriteAssetEditor : Editor
{
struct UI_PanelState
{
public static bool spriteAssetFaceInfoPanel = true;
public static bool spriteAtlasInfoPanel = true;
public static bool fallbackSpriteAssetPanel = true;
public static bool spriteCharacterTablePanel;
public static bool spriteGlyphTablePanel;
}
private static string[] s_UiStateLabel = new string[] { "<i>(Click to collapse)</i> ", "<i>(Click to expand)</i> " };
int m_moveToIndex;
int m_selectedElement = -1;
bool m_isCharacterSelected = false;
bool m_isSpriteSelected = false;
int m_CurrentCharacterPage;
int m_CurrentGlyphPage;
const string k_UndoRedo = "UndoRedoPerformed";
string m_CharacterSearchPattern;
List<int> m_CharacterSearchList;
bool m_IsCharacterSearchDirty;
string m_GlyphSearchPattern;
List<int> m_GlyphSearchList;
bool m_IsGlyphSearchDirty;
SerializedProperty m_FaceInfoProperty;
SerializedProperty m_PointSizeProperty;
SerializedProperty m_ScaleProperty;
SerializedProperty m_LineHeightProperty;
SerializedProperty m_AscentLineProperty;
SerializedProperty m_BaselineProperty;
SerializedProperty m_DescentLineProperty;
SerializedProperty m_spriteAtlas_prop;
SerializedProperty m_material_prop;
SerializedProperty m_SpriteCharacterTableProperty;
SerializedProperty m_SpriteGlyphTableProperty;
ReorderableList m_fallbackSpriteAssetList;
TMP_SpriteAsset m_SpriteAsset;
bool isAssetDirty;
float m_xOffset;
float m_yOffset;
float m_xAdvance;
float m_scale;
public void OnEnable()
{
m_SpriteAsset = target as TMP_SpriteAsset;
m_FaceInfoProperty = serializedObject.FindProperty("m_FaceInfo");
m_PointSizeProperty = m_FaceInfoProperty.FindPropertyRelative("m_PointSize");
m_ScaleProperty = m_FaceInfoProperty.FindPropertyRelative("m_Scale");
m_LineHeightProperty = m_FaceInfoProperty.FindPropertyRelative("m_LineHeight");
m_AscentLineProperty = m_FaceInfoProperty.FindPropertyRelative("m_AscentLine");
m_BaselineProperty = m_FaceInfoProperty.FindPropertyRelative("m_Baseline");
m_DescentLineProperty = m_FaceInfoProperty.FindPropertyRelative("m_DescentLine");
m_spriteAtlas_prop = serializedObject.FindProperty("spriteSheet");
m_material_prop = serializedObject.FindProperty("m_Material");
m_SpriteCharacterTableProperty = serializedObject.FindProperty("m_SpriteCharacterTable");
m_SpriteGlyphTableProperty = serializedObject.FindProperty("m_GlyphTable");
// Fallback TMP Sprite Asset list
m_fallbackSpriteAssetList = new ReorderableList(serializedObject, serializedObject.FindProperty("fallbackSpriteAssets"), true, true, true, true);
m_fallbackSpriteAssetList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) =>
{
var element = m_fallbackSpriteAssetList.serializedProperty.GetArrayElementAtIndex(index);
rect.y += 2;
EditorGUI.PropertyField(new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight), element, GUIContent.none);
};
m_fallbackSpriteAssetList.drawHeaderCallback = rect =>
{
EditorGUI.LabelField(rect, new GUIContent("Fallback Sprite Asset List", "Select the Sprite Assets that will be searched and used as fallback when a given sprite is missing from this sprite asset."));
};
// Clear glyph proxy lookups
TMP_PropertyDrawerUtilities.ClearGlyphProxyLookups();
}
public override void OnInspectorGUI()
{
//Debug.Log("OnInspectorGUI Called.");
Event currentEvent = Event.current;
string evt_cmd = currentEvent.commandName; // Get Current Event CommandName to check for Undo Events
serializedObject.Update();
// TEXTMESHPRO SPRITE INFO PANEL
#region Display Sprite Asset Face Info
Rect rect = EditorGUILayout.GetControlRect(false, 24);
GUI.Label(rect, new GUIContent("<b>Face Info</b> - v" + m_SpriteAsset.version), TMP_UIStyleManager.sectionHeader);
rect.x += rect.width - 132f;
rect.y += 2;
rect.width = 130f;
rect.height = 18f;
if (GUI.Button(rect, new GUIContent("Update Sprite Asset")))
{
TMP_SpriteAssetMenu.UpdateSpriteAsset(m_SpriteAsset);
ResetSelectionNextFrame();
}
EditorGUI.indentLevel = 1;
EditorGUILayout.PropertyField(m_PointSizeProperty);
EditorGUILayout.PropertyField(m_ScaleProperty);
//EditorGUILayout.PropertyField(m_LineHeightProperty);
EditorGUILayout.PropertyField(m_AscentLineProperty);
EditorGUILayout.PropertyField(m_BaselineProperty);
EditorGUILayout.PropertyField(m_DescentLineProperty);
EditorGUILayout.Space();
#endregion
// ATLAS TEXTURE & MATERIAL
#region Display Atlas Texture and Material
rect = EditorGUILayout.GetControlRect(false, 24);
if (GUI.Button(rect, new GUIContent("<b>Atlas & Material</b>"), TMP_UIStyleManager.sectionHeader))
UI_PanelState.spriteAtlasInfoPanel = !UI_PanelState.spriteAtlasInfoPanel;
GUI.Label(rect, (UI_PanelState.spriteAtlasInfoPanel ? "" : s_UiStateLabel[1]), TMP_UIStyleManager.rightLabel);
if (UI_PanelState.spriteAtlasInfoPanel)
{
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(m_spriteAtlas_prop, new GUIContent("Sprite Atlas"));
if (EditorGUI.EndChangeCheck())
{
// Assign the new sprite atlas texture to the current material
Texture2D tex = m_spriteAtlas_prop.objectReferenceValue as Texture2D;
if (tex != null)
{
Material mat = m_material_prop.objectReferenceValue as Material;
if (mat != null)
mat.mainTexture = tex;
}
}
EditorGUILayout.PropertyField(m_material_prop, new GUIContent("Default Material"));
EditorGUILayout.Space();
}
#endregion
// FALLBACK SPRITE ASSETS
#region Display Sprite Fallbacks
rect = EditorGUILayout.GetControlRect(false, 24);
EditorGUI.indentLevel = 0;
if (GUI.Button(rect, new GUIContent("<b>Fallback Sprite Assets</b>", "Select the Sprite Assets that will be searched and used as fallback when a given sprite is missing from this sprite asset."), TMP_UIStyleManager.sectionHeader))
UI_PanelState.fallbackSpriteAssetPanel = !UI_PanelState.fallbackSpriteAssetPanel;
GUI.Label(rect, (UI_PanelState.fallbackSpriteAssetPanel ? "" : s_UiStateLabel[1]), TMP_UIStyleManager.rightLabel);
if (UI_PanelState.fallbackSpriteAssetPanel)
{
m_fallbackSpriteAssetList.DoLayoutList();
EditorGUILayout.Space();
}
#endregion
// SPRITE CHARACTER TABLE
#region Display Sprite Character Table
EditorGUI.indentLevel = 0;
rect = EditorGUILayout.GetControlRect(false, 24);
if (GUI.Button(rect, new GUIContent("<b>Sprite Character Table</b>", "List of sprite characters contained in this sprite asset."), TMP_UIStyleManager.sectionHeader))
UI_PanelState.spriteCharacterTablePanel = !UI_PanelState.spriteCharacterTablePanel;
GUI.Label(rect, (UI_PanelState.spriteCharacterTablePanel ? "" : s_UiStateLabel[1]), TMP_UIStyleManager.rightLabel);
if (UI_PanelState.spriteCharacterTablePanel)
{
int arraySize = m_SpriteCharacterTableProperty.arraySize;
int itemsPerPage = 10;
// Display Glyph Management Tools
EditorGUILayout.BeginVertical(EditorStyles.helpBox, GUILayout.ExpandWidth(true));
{
// Search Bar implementation
#region DISPLAY SEARCH BAR
EditorGUILayout.BeginHorizontal();
{
EditorGUIUtility.labelWidth = 110f;
EditorGUI.BeginChangeCheck();
string searchPattern = EditorGUILayout.TextField("Sprite Search", m_CharacterSearchPattern, "SearchTextField");
if (EditorGUI.EndChangeCheck() || m_IsCharacterSearchDirty)
{
if (string.IsNullOrEmpty(searchPattern) == false)
{
//GUIUtility.keyboardControl = 0;
m_CharacterSearchPattern = searchPattern.ToLower(System.Globalization.CultureInfo.InvariantCulture).Trim();
// Search Glyph Table for potential matches
SearchCharacterTable(m_CharacterSearchPattern, ref m_CharacterSearchList);
}
else
m_CharacterSearchPattern = null;
m_IsCharacterSearchDirty = false;
}
string styleName = string.IsNullOrEmpty(m_CharacterSearchPattern) ? "SearchCancelButtonEmpty" : "SearchCancelButton";
if (GUILayout.Button(GUIContent.none, styleName))
{
GUIUtility.keyboardControl = 0;
m_CharacterSearchPattern = string.Empty;
}
}
EditorGUILayout.EndHorizontal();
#endregion
// Display Page Navigation
if (!string.IsNullOrEmpty(m_CharacterSearchPattern))
arraySize = m_CharacterSearchList.Count;
// Display Page Navigation
DisplayPageNavigation(ref m_CurrentCharacterPage, arraySize, itemsPerPage);
}
EditorGUILayout.EndVertical();
if (arraySize > 0)
{
// Display each SpriteInfo entry using the SpriteInfo property drawer.
for (int i = itemsPerPage * m_CurrentCharacterPage; i < arraySize && i < itemsPerPage * (m_CurrentCharacterPage + 1); i++)
{
// Define the start of the selection region of the element.
Rect elementStartRegion = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true));
int elementIndex = i;
if (!string.IsNullOrEmpty(m_CharacterSearchPattern))
elementIndex = m_CharacterSearchList[i];
SerializedProperty spriteCharacterProperty = m_SpriteCharacterTableProperty.GetArrayElementAtIndex(elementIndex);
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
{
EditorGUI.BeginDisabledGroup(i != m_selectedElement || !m_isCharacterSelected);
{
EditorGUILayout.PropertyField(spriteCharacterProperty);
}
EditorGUI.EndDisabledGroup();
}
EditorGUILayout.EndVertical();
// Define the end of the selection region of the element.
Rect elementEndRegion = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true));
// Check for Item selection
Rect selectionArea = new Rect(elementStartRegion.x, elementStartRegion.y, elementEndRegion.width, elementEndRegion.y - elementStartRegion.y);
if (DoSelectionCheck(selectionArea))
{
if (m_selectedElement == i)
{
m_selectedElement = -1;
m_isCharacterSelected = false;
}
else
{
m_selectedElement = i;
m_isCharacterSelected = true;
m_isSpriteSelected = false;
GUIUtility.keyboardControl = 0;
}
}
// Draw & Handle Section Area
if (m_selectedElement == i && m_isCharacterSelected)
{
// Draw selection highlight
TMP_EditorUtility.DrawBox(selectionArea, 2f, new Color32(40, 192, 255, 255));
// Draw options to MoveUp, MoveDown, Add or Remove Sprites
Rect controlRect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight * 1f);
controlRect.width /= 8;
// Move sprite up.
bool guiEnabled = GUI.enabled;
if (i == 0) { GUI.enabled = false; }
if (GUI.Button(controlRect, "Up"))
{
SwapCharacterElements(i, i - 1);
}
GUI.enabled = guiEnabled;
// Move sprite down.
controlRect.x += controlRect.width;
if (i == arraySize - 1) { GUI.enabled = false; }
if (GUI.Button(controlRect, "Down"))
{
SwapCharacterElements(i, i + 1);
}
GUI.enabled = guiEnabled;
// Move sprite to new index
controlRect.x += controlRect.width * 2;
//if (i == arraySize - 1) { GUI.enabled = false; }
m_moveToIndex = EditorGUI.IntField(controlRect, m_moveToIndex);
controlRect.x -= controlRect.width;
if (GUI.Button(controlRect, "Goto"))
{
MoveCharacterToIndex(i, m_moveToIndex);
}
//controlRect.x += controlRect.width;
GUI.enabled = guiEnabled;
// Add new Sprite
controlRect.x += controlRect.width * 4;
if (GUI.Button(controlRect, "+"))
{
m_SpriteCharacterTableProperty.arraySize += 1;
int index = m_SpriteCharacterTableProperty.arraySize - 1;
SerializedProperty spriteInfo_prop = m_SpriteCharacterTableProperty.GetArrayElementAtIndex(index);
// Copy properties of the selected element
CopyCharacterSerializedProperty(m_SpriteCharacterTableProperty.GetArrayElementAtIndex(elementIndex), ref spriteInfo_prop);
//spriteInfo_prop.FindPropertyRelative("m_Index").intValue = index;
serializedObject.ApplyModifiedProperties();
m_IsCharacterSearchDirty = true;
}
// Delete selected Sprite
controlRect.x += controlRect.width;
if (m_selectedElement == -1) GUI.enabled = false;
if (GUI.Button(controlRect, "-"))
{
m_SpriteCharacterTableProperty.DeleteArrayElementAtIndex(elementIndex);
m_selectedElement = -1;
serializedObject.ApplyModifiedProperties();
m_IsCharacterSearchDirty = true;
return;
}
}
}
}
DisplayPageNavigation(ref m_CurrentCharacterPage, arraySize, itemsPerPage);
EditorGUIUtility.labelWidth = 40f;
EditorGUIUtility.fieldWidth = 20f;
GUILayout.Space(5f);
// GLOBAL TOOLS
#region Global Tools
/*
GUI.enabled = true;
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
rect = EditorGUILayout.GetControlRect(false, 40);
float width = (rect.width - 75f) / 4;
EditorGUI.LabelField(rect, "Global Offsets & Scale", EditorStyles.boldLabel);
rect.x += 70;
bool old_ChangedState = GUI.changed;
GUI.changed = false;
m_xOffset = EditorGUI.FloatField(new Rect(rect.x + 5f + width * 0, rect.y + 20, width - 5f, 18), new GUIContent("OX:"), m_xOffset);
if (GUI.changed) UpdateGlobalProperty("m_HorizontalBearingX", m_xOffset);
m_yOffset = EditorGUI.FloatField(new Rect(rect.x + 5f + width * 1, rect.y + 20, width - 5f, 18), new GUIContent("OY:"), m_yOffset);
if (GUI.changed) UpdateGlobalProperty("m_HorizontalBearingY", m_yOffset);
m_xAdvance = EditorGUI.FloatField(new Rect(rect.x + 5f + width * 2, rect.y + 20, width - 5f, 18), new GUIContent("ADV."), m_xAdvance);
if (GUI.changed) UpdateGlobalProperty("m_HorizontalAdvance", m_xAdvance);
m_scale = EditorGUI.FloatField(new Rect(rect.x + 5f + width * 3, rect.y + 20, width - 5f, 18), new GUIContent("SF."), m_scale);
if (GUI.changed) UpdateGlobalProperty("m_Scale", m_scale);
EditorGUILayout.EndVertical();
GUI.changed = old_ChangedState;
*/
#endregion
}
#endregion
// SPRITE GLYPH TABLE
#region Display Sprite Glyph Table
EditorGUI.indentLevel = 0;
rect = EditorGUILayout.GetControlRect(false, 24);
if (GUI.Button(rect, new GUIContent("<b>Sprite Glyph Table</b>", "A list of the SpriteGlyphs contained in this sprite asset."), TMP_UIStyleManager.sectionHeader))
UI_PanelState.spriteGlyphTablePanel = !UI_PanelState.spriteGlyphTablePanel;
GUI.Label(rect, (UI_PanelState.spriteGlyphTablePanel ? "" : s_UiStateLabel[1]), TMP_UIStyleManager.rightLabel);
if (UI_PanelState.spriteGlyphTablePanel)
{
int arraySize = m_SpriteGlyphTableProperty.arraySize;
int itemsPerPage = 10;
// Display Glyph Management Tools
EditorGUILayout.BeginVertical(EditorStyles.helpBox, GUILayout.ExpandWidth(true));
{
// Search Bar implementation
#region DISPLAY SEARCH BAR
EditorGUILayout.BeginHorizontal();
{
EditorGUIUtility.labelWidth = 110f;
EditorGUI.BeginChangeCheck();
string searchPattern = EditorGUILayout.TextField("Sprite Search", m_GlyphSearchPattern, "SearchTextField");
if (EditorGUI.EndChangeCheck() || m_IsGlyphSearchDirty)
{
if (string.IsNullOrEmpty(searchPattern) == false)
{
//GUIUtility.keyboardControl = 0;
m_GlyphSearchPattern = searchPattern.ToLower(System.Globalization.CultureInfo.InvariantCulture).Trim();
// Search Glyph Table for potential matches
SearchCharacterTable(m_GlyphSearchPattern, ref m_GlyphSearchList);
}
else
m_GlyphSearchPattern = null;
m_IsGlyphSearchDirty = false;
}
string styleName = string.IsNullOrEmpty(m_GlyphSearchPattern) ? "SearchCancelButtonEmpty" : "SearchCancelButton";
if (GUILayout.Button(GUIContent.none, styleName))
{
GUIUtility.keyboardControl = 0;
m_GlyphSearchPattern = string.Empty;
}
}
EditorGUILayout.EndHorizontal();
#endregion
// Display Page Navigation
if (!string.IsNullOrEmpty(m_GlyphSearchPattern))
arraySize = m_GlyphSearchList.Count;
// Display Page Navigation
DisplayPageNavigation(ref m_CurrentGlyphPage, arraySize, itemsPerPage);
}
EditorGUILayout.EndVertical();
if (arraySize > 0)
{
// Display each SpriteInfo entry using the SpriteInfo property drawer.
for (int i = itemsPerPage * m_CurrentGlyphPage; i < arraySize && i < itemsPerPage * (m_CurrentGlyphPage + 1); i++)
{
// Define the start of the selection region of the element.
Rect elementStartRegion = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true));
int elementIndex = i;
if (!string.IsNullOrEmpty(m_GlyphSearchPattern))
elementIndex = m_GlyphSearchList[i];
SerializedProperty spriteGlyphProperty = m_SpriteGlyphTableProperty.GetArrayElementAtIndex(elementIndex);
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
{
EditorGUI.BeginDisabledGroup(i != m_selectedElement || !m_isSpriteSelected);
{
EditorGUILayout.PropertyField(spriteGlyphProperty);
}
EditorGUI.EndDisabledGroup();
}
EditorGUILayout.EndVertical();
// Define the end of the selection region of the element.
Rect elementEndRegion = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true));
// Check for Item selection
Rect selectionArea = new Rect(elementStartRegion.x, elementStartRegion.y, elementEndRegion.width, elementEndRegion.y - elementStartRegion.y);
if (DoSelectionCheck(selectionArea))
{
if (m_selectedElement == i)
{
m_selectedElement = -1;
m_isSpriteSelected = false;
}
else
{
m_selectedElement = i;
m_isCharacterSelected = false;
m_isSpriteSelected = true;
GUIUtility.keyboardControl = 0;
}
}
// Draw & Handle Section Area
if (m_selectedElement == i && m_isSpriteSelected)
{
// Draw selection highlight
TMP_EditorUtility.DrawBox(selectionArea, 2f, new Color32(40, 192, 255, 255));
// Draw options to MoveUp, MoveDown, Add or Remove Sprites
Rect controlRect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight * 1f);
controlRect.width /= 8;
// Move sprite up.
bool guiEnabled = GUI.enabled;
if (i == 0) { GUI.enabled = false; }
if (GUI.Button(controlRect, "Up"))
{
SwapGlyphElements(i, i - 1);
}
GUI.enabled = guiEnabled;
// Move sprite down.
controlRect.x += controlRect.width;
if (i == arraySize - 1) { GUI.enabled = false; }
if (GUI.Button(controlRect, "Down"))
{
SwapGlyphElements(i, i + 1);
}
GUI.enabled = guiEnabled;
// Move sprite to new index
controlRect.x += controlRect.width * 2;
//if (i == arraySize - 1) { GUI.enabled = false; }
m_moveToIndex = EditorGUI.IntField(controlRect, m_moveToIndex);
controlRect.x -= controlRect.width;
if (GUI.Button(controlRect, "Goto"))
{
MoveGlyphToIndex(i, m_moveToIndex);
}
//controlRect.x += controlRect.width;
GUI.enabled = guiEnabled;
// Add new Sprite
controlRect.x += controlRect.width * 4;
if (GUI.Button(controlRect, "+"))
{
m_SpriteGlyphTableProperty.arraySize += 1;
int index = m_SpriteGlyphTableProperty.arraySize - 1;
SerializedProperty newSpriteGlyphProperty = m_SpriteGlyphTableProperty.GetArrayElementAtIndex(index);
// Copy properties of the selected element
CopyGlyphSerializedProperty(m_SpriteGlyphTableProperty.GetArrayElementAtIndex(elementIndex), ref newSpriteGlyphProperty);
newSpriteGlyphProperty.FindPropertyRelative("m_Index").intValue = index;
serializedObject.ApplyModifiedProperties();
m_IsGlyphSearchDirty = true;
//m_SpriteAsset.UpdateLookupTables();
}
// Delete selected Sprite
controlRect.x += controlRect.width;
if (m_selectedElement == -1) GUI.enabled = false;
if (GUI.Button(controlRect, "-"))
{
SerializedProperty selectedSpriteGlyphProperty = m_SpriteGlyphTableProperty.GetArrayElementAtIndex(elementIndex);
int selectedGlyphIndex = selectedSpriteGlyphProperty.FindPropertyRelative("m_Index").intValue;
m_SpriteGlyphTableProperty.DeleteArrayElementAtIndex(elementIndex);
// Remove all Sprite Characters referencing this glyph.
for (int j = 0; j < m_SpriteCharacterTableProperty.arraySize; j++)
{
int glyphIndex = m_SpriteCharacterTableProperty.GetArrayElementAtIndex(j).FindPropertyRelative("m_GlyphIndex").intValue;
if (glyphIndex == selectedGlyphIndex)
{
// Remove character
m_SpriteCharacterTableProperty.DeleteArrayElementAtIndex(j);
}
}
m_selectedElement = -1;
serializedObject.ApplyModifiedProperties();
m_IsGlyphSearchDirty = true;
//m_SpriteAsset.UpdateLookupTables();
return;
}
}
}
}
DisplayPageNavigation(ref m_CurrentGlyphPage, arraySize, itemsPerPage);
EditorGUIUtility.labelWidth = 40f;
EditorGUIUtility.fieldWidth = 20f;
GUILayout.Space(5f);
// GLOBAL TOOLS
#region Global Tools
GUI.enabled = true;
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
EditorGUILayout.LabelField("Global Offsets & Scale", EditorStyles.boldLabel);
bool old_ChangedState = GUI.changed;
GUI.changed = false;
EditorGUILayout.BeginHorizontal();
GUILayout.Space(25f);
m_xOffset = EditorGUILayout.FloatField(new GUIContent("OX:"), m_xOffset);
if (GUI.changed) UpdateGlobalProperty("m_HorizontalBearingX", m_xOffset);
m_yOffset = EditorGUILayout.FloatField(new GUIContent("OY:"), m_yOffset);
if (GUI.changed) UpdateGlobalProperty("m_HorizontalBearingY", m_yOffset);
m_xAdvance = EditorGUILayout.FloatField(new GUIContent("ADV."), m_xAdvance);
if (GUI.changed) UpdateGlobalProperty("m_HorizontalAdvance", m_xAdvance);
m_scale = EditorGUILayout.FloatField(new GUIContent("SF."), m_scale);
if (GUI.changed) UpdateGlobalProperty("m_Scale", m_scale);
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
#endregion
GUI.changed = old_ChangedState;
}
#endregion
if (serializedObject.ApplyModifiedProperties() || evt_cmd == k_UndoRedo || isAssetDirty)
{
if (m_SpriteAsset.m_IsSpriteAssetLookupTablesDirty || evt_cmd == k_UndoRedo)
{
m_SpriteAsset.UpdateLookupTables();
TMP_ResourceManager.RebuildFontAssetCache();
}
TMPro_EventManager.ON_SPRITE_ASSET_PROPERTY_CHANGED(true, m_SpriteAsset);
isAssetDirty = false;
EditorUtility.SetDirty(target);
}
// Clear selection if mouse event was not consumed.
GUI.enabled = true;
if (currentEvent.type == EventType.MouseDown && currentEvent.button == 0)
m_selectedElement = -1;
}
private void ResetSelectionNextFrame()
{
var activeObject = Selection.activeObject;
EditorApplication.delayCall += () =>
{
Selection.activeObject = null;
EditorApplication.delayCall += () =>
{
Selection.activeObject = activeObject;
};
};
}
/// <summary>
///
/// </summary>
/// <param name="arraySize"></param>
/// <param name="itemsPerPage"></param>
void DisplayPageNavigation(ref int currentPage, int arraySize, int itemsPerPage)
{
Rect pagePos = EditorGUILayout.GetControlRect(false, 20);
pagePos.width /= 3;
int shiftMultiplier = Event.current.shift ? 10 : 1; // Page + Shift goes 10 page forward
// Previous Page
GUI.enabled = currentPage > 0;
if (GUI.Button(pagePos, "Previous Page"))
{
currentPage -= 1 * shiftMultiplier;
//m_isNewPage = true;
}
// Page Counter
GUI.enabled = true;
pagePos.x += pagePos.width;
int totalPages = (int)(arraySize / (float)itemsPerPage + 0.999f);
GUI.Label(pagePos, "Page " + (currentPage + 1) + " / " + totalPages, TMP_UIStyleManager.centeredLabel);
// Next Page
pagePos.x += pagePos.width;
GUI.enabled = itemsPerPage * (currentPage + 1) < arraySize;
if (GUI.Button(pagePos, "Next Page"))
{
currentPage += 1 * shiftMultiplier;
//m_isNewPage = true;
}
// Clamp page range
currentPage = Mathf.Clamp(currentPage, 0, arraySize / itemsPerPage);
GUI.enabled = true;
}
/// <summary>
/// Method to update the properties of all sprites
/// </summary>
/// <param name="property"></param>
/// <param name="value"></param>
void UpdateGlobalProperty(string property, float value)
{
int arraySize = m_SpriteGlyphTableProperty.arraySize;
for (int i = 0; i < arraySize; i++)
{
// Get a reference to the sprite glyph.
SerializedProperty spriteGlyphProperty = m_SpriteGlyphTableProperty.GetArrayElementAtIndex(i);
if (property == "m_Scale")
{
spriteGlyphProperty.FindPropertyRelative(property).floatValue = value;
}
else
{
SerializedProperty glyphMetricsProperty = spriteGlyphProperty.FindPropertyRelative("m_Metrics");
glyphMetricsProperty.FindPropertyRelative(property).floatValue = value;
}
}
GUI.changed = false;
}
// Check if any of the Style elements were clicked on.
private bool DoSelectionCheck(Rect selectionArea)
{
Event currentEvent = Event.current;
switch (currentEvent.type)
{
case EventType.MouseDown:
if (selectionArea.Contains(currentEvent.mousePosition) && currentEvent.button == 0)
{
currentEvent.Use();
return true;
}
break;
}
return false;
}
/// <summary>
/// Swap the sprite item at the currently selected array index to another index.
/// </summary>
/// <param name="selectedIndex">Selected index.</param>
/// <param name="newIndex">New index.</param>
void SwapCharacterElements(int selectedIndex, int newIndex)
{
m_SpriteCharacterTableProperty.MoveArrayElement(selectedIndex, newIndex);
m_selectedElement = newIndex;
m_IsCharacterSearchDirty = true;
m_SpriteAsset.m_IsSpriteAssetLookupTablesDirty = true;
}
/// <summary>
/// Move Sprite Element at selected index to another index and reorder sprite list.
/// </summary>
/// <param name="selectedIndex"></param>
/// <param name="newIndex"></param>
void MoveCharacterToIndex(int selectedIndex, int newIndex)
{
int arraySize = m_SpriteCharacterTableProperty.arraySize;
if (newIndex >= arraySize)
newIndex = arraySize - 1;
m_SpriteCharacterTableProperty.MoveArrayElement(selectedIndex, newIndex);
m_selectedElement = newIndex;
m_IsCharacterSearchDirty = true;
m_SpriteAsset.m_IsSpriteAssetLookupTablesDirty = true;
// TODO: Need to handle switching pages if the character or glyph is moved to a different page.
}
/// <summary>
///
/// </summary>
/// <param name="selectedIndex"></param>
/// <param name="newIndex"></param>
void SwapGlyphElements(int selectedIndex, int newIndex)
{
m_SpriteGlyphTableProperty.MoveArrayElement(selectedIndex, newIndex);
m_selectedElement = newIndex;
m_IsGlyphSearchDirty = true;
m_SpriteAsset.m_IsSpriteAssetLookupTablesDirty = true;
}
/// <summary>
/// Move Sprite Element at selected index to another index and reorder sprite list.
/// </summary>
/// <param name="selectedIndex"></param>
/// <param name="newIndex"></param>
void MoveGlyphToIndex(int selectedIndex, int newIndex)
{
int arraySize = m_SpriteGlyphTableProperty.arraySize;
if (newIndex >= arraySize)
newIndex = arraySize - 1;
m_SpriteGlyphTableProperty.MoveArrayElement(selectedIndex, newIndex);
m_selectedElement = newIndex;
m_IsGlyphSearchDirty = true;
m_SpriteAsset.m_IsSpriteAssetLookupTablesDirty = true;
// TODO: Need to handle switching pages if the character or glyph is moved to a different page.
}
/// <summary>
///
/// </summary>
/// <param name="source"></param>
/// <param name="target"></param>
void CopyCharacterSerializedProperty(SerializedProperty source, ref SerializedProperty target)
{
target.FindPropertyRelative("m_Name").stringValue = source.FindPropertyRelative("m_Name").stringValue;
target.FindPropertyRelative("m_Unicode").intValue = source.FindPropertyRelative("m_Unicode").intValue;
target.FindPropertyRelative("m_GlyphIndex").intValue = source.FindPropertyRelative("m_GlyphIndex").intValue;
target.FindPropertyRelative("m_Scale").floatValue = source.FindPropertyRelative("m_Scale").floatValue;
}
void CopyGlyphSerializedProperty(SerializedProperty srcGlyph, ref SerializedProperty dstGlyph)
{
// TODO : Should make a generic function which copies each of the properties.
// Index
dstGlyph.FindPropertyRelative("m_Index").intValue = srcGlyph.FindPropertyRelative("m_Index").intValue;
// GlyphMetrics
SerializedProperty srcGlyphMetrics = srcGlyph.FindPropertyRelative("m_Metrics");
SerializedProperty dstGlyphMetrics = dstGlyph.FindPropertyRelative("m_Metrics");
dstGlyphMetrics.FindPropertyRelative("m_Width").floatValue = srcGlyphMetrics.FindPropertyRelative("m_Width").floatValue;
dstGlyphMetrics.FindPropertyRelative("m_Height").floatValue = srcGlyphMetrics.FindPropertyRelative("m_Height").floatValue;
dstGlyphMetrics.FindPropertyRelative("m_HorizontalBearingX").floatValue = srcGlyphMetrics.FindPropertyRelative("m_HorizontalBearingX").floatValue;
dstGlyphMetrics.FindPropertyRelative("m_HorizontalBearingY").floatValue = srcGlyphMetrics.FindPropertyRelative("m_HorizontalBearingY").floatValue;
dstGlyphMetrics.FindPropertyRelative("m_HorizontalAdvance").floatValue = srcGlyphMetrics.FindPropertyRelative("m_HorizontalAdvance").floatValue;
// GlyphRect
SerializedProperty srcGlyphRect = srcGlyph.FindPropertyRelative("m_GlyphRect");
SerializedProperty dstGlyphRect = dstGlyph.FindPropertyRelative("m_GlyphRect");
dstGlyphRect.FindPropertyRelative("m_X").intValue = srcGlyphRect.FindPropertyRelative("m_X").intValue;
dstGlyphRect.FindPropertyRelative("m_Y").intValue = srcGlyphRect.FindPropertyRelative("m_Y").intValue;
dstGlyphRect.FindPropertyRelative("m_Width").intValue = srcGlyphRect.FindPropertyRelative("m_Width").intValue;
dstGlyphRect.FindPropertyRelative("m_Height").intValue = srcGlyphRect.FindPropertyRelative("m_Height").intValue;
dstGlyph.FindPropertyRelative("m_Scale").floatValue = srcGlyph.FindPropertyRelative("m_Scale").floatValue;
dstGlyph.FindPropertyRelative("m_AtlasIndex").intValue = srcGlyph.FindPropertyRelative("m_AtlasIndex").intValue;
}
/// <summary>
///
/// </summary>
/// <param name="searchPattern"></param>
/// <returns></returns>
void SearchCharacterTable(string searchPattern, ref List<int> searchResults)
{
if (searchResults == null) searchResults = new List<int>();
searchResults.Clear();
int arraySize = m_SpriteCharacterTableProperty.arraySize;
for (int i = 0; i < arraySize; i++)
{
SerializedProperty sourceSprite = m_SpriteCharacterTableProperty.GetArrayElementAtIndex(i);
// Check for potential match against array index
if (i.ToString().Contains(searchPattern))
{
searchResults.Add(i);
continue;
}
// Check for potential match against decimal id
int id = sourceSprite.FindPropertyRelative("m_GlyphIndex").intValue;
if (id.ToString().Contains(searchPattern))
{
searchResults.Add(i);
continue;
}
// Check for potential match against name
string name = sourceSprite.FindPropertyRelative("m_Name").stringValue.ToLower(System.Globalization.CultureInfo.InvariantCulture).Trim();
if (name.Contains(searchPattern))
{
searchResults.Add(i);
continue;
}
}
}
void SearchGlyphTable(string searchPattern, ref List<int> searchResults)
{
if (searchResults == null) searchResults = new List<int>();
searchResults.Clear();
int arraySize = m_SpriteGlyphTableProperty.arraySize;
for (int i = 0; i < arraySize; i++)
{
SerializedProperty sourceSprite = m_SpriteGlyphTableProperty.GetArrayElementAtIndex(i);
// Check for potential match against array index
if (i.ToString().Contains(searchPattern))
{
searchResults.Add(i);
continue;
}
// Check for potential match against decimal id
int id = sourceSprite.FindPropertyRelative("m_GlyphIndex").intValue;
if (id.ToString().Contains(searchPattern))
{
searchResults.Add(i);
continue;
}
// Check for potential match against name
string name = sourceSprite.FindPropertyRelative("m_Name").stringValue.ToLower(System.Globalization.CultureInfo.InvariantCulture).Trim();
if (name.Contains(searchPattern))
{
searchResults.Add(i);
continue;
}
}
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: b09be1f217d34247af54863a2f5587e1
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,276 @@
using System;
using UnityEngine;
using UnityEngine.TextCore;
using UnityEditor;
using System.IO;
using System.Collections.Generic;
using TMPro.EditorUtilities;
using TMPro.SpriteAssetUtilities;
namespace TMPro
{
public class TMP_SpriteAssetImporter : EditorWindow
{
// Create Sprite Asset Editor Window
[MenuItem("Window/TextMeshPro/Sprite Importer", false, 2026)]
public static void ShowFontAtlasCreatorWindow()
{
var window = GetWindow<TMP_SpriteAssetImporter>();
window.titleContent = new GUIContent("Sprite Importer");
window.Focus();
}
Texture2D m_SpriteAtlas;
SpriteAssetImportFormats m_SpriteDataFormat = SpriteAssetImportFormats.TexturePackerJsonArray;
TextAsset m_JsonFile;
string m_CreationFeedback;
TMP_SpriteAsset m_SpriteAsset;
static readonly GUIContent k_ConvertSpriteNameToUnicodeLabel = new GUIContent("Use filenames as Unicodes", "Should sprite filenames be converted and assigned as Unicode code points for each sprite? This conversion assumes the sprite filenames represent valid Unicode code points.");
static bool k_SpriteNameIsUnicodeValue;
/// <summary>
///
/// </summary>
void OnEnable()
{
// Set Editor Window Size
SetEditorWindowSize();
}
/// <summary>
///
/// </summary>
public void OnGUI()
{
DrawEditorPanel();
}
/// <summary>
///
/// </summary>
private void OnDisable()
{
// Clean up sprite asset object that may have been created and not saved.
if (m_SpriteAsset != null && !EditorUtility.IsPersistent(m_SpriteAsset))
DestroyImmediate(m_SpriteAsset);
}
/// <summary>
///
/// </summary>
void DrawEditorPanel()
{
// label
GUILayout.Label("Import Settings", EditorStyles.boldLabel);
EditorGUI.BeginChangeCheck();
// Sprite Texture Selection
m_JsonFile = EditorGUILayout.ObjectField("Sprite Data Source", m_JsonFile, typeof(TextAsset), false) as TextAsset;
m_SpriteDataFormat = (SpriteAssetImportFormats)EditorGUILayout.EnumPopup("Import Format", m_SpriteDataFormat);
k_SpriteNameIsUnicodeValue = EditorGUILayout.Toggle(k_ConvertSpriteNameToUnicodeLabel, k_SpriteNameIsUnicodeValue);
// Sprite Texture Selection
m_SpriteAtlas = EditorGUILayout.ObjectField("Sprite Texture Atlas", m_SpriteAtlas, typeof(Texture2D), false) as Texture2D;
if (EditorGUI.EndChangeCheck())
{
m_CreationFeedback = string.Empty;
}
GUILayout.Space(10);
GUI.enabled = m_JsonFile != null && m_SpriteAtlas != null && m_SpriteDataFormat != SpriteAssetImportFormats.None;
// Create Sprite Asset
if (GUILayout.Button("Create Sprite Asset"))
{
m_CreationFeedback = string.Empty;
// Clean up sprite asset object that may have been previously created.
if (m_SpriteAsset != null && !EditorUtility.IsPersistent(m_SpriteAsset))
DestroyImmediate(m_SpriteAsset);
// Read json data file
if (m_JsonFile != null)
{
switch (m_SpriteDataFormat)
{
case SpriteAssetImportFormats.TexturePackerJsonArray:
TexturePacker_JsonArray.SpriteDataObject jsonData = null;
try
{
jsonData = JsonUtility.FromJson<TexturePacker_JsonArray.SpriteDataObject>(m_JsonFile.text);
}
catch
{
m_CreationFeedback = "The Sprite Data Source file [" + m_JsonFile.name + "] appears to be invalid or incorrectly formatted.";
}
if (jsonData != null && jsonData.frames != null && jsonData.frames.Count > 0)
{
int spriteCount = jsonData.frames.Count;
// Update import results
m_CreationFeedback = "<b>Import Results</b>\n--------------------\n";
m_CreationFeedback += "<color=#C0ffff><b>" + spriteCount + "</b></color> Sprites were imported from file.";
// Create new Sprite Asset
m_SpriteAsset = CreateInstance<TMP_SpriteAsset>();
// Assign sprite sheet / atlas texture to sprite asset
m_SpriteAsset.spriteSheet = m_SpriteAtlas;
List<TMP_SpriteGlyph> spriteGlyphTable = new List<TMP_SpriteGlyph>();
List<TMP_SpriteCharacter> spriteCharacterTable = new List<TMP_SpriteCharacter>();
PopulateSpriteTables(jsonData, spriteCharacterTable, spriteGlyphTable);
m_SpriteAsset.spriteCharacterTable = spriteCharacterTable;
m_SpriteAsset.spriteGlyphTable = spriteGlyphTable;
}
break;
}
}
}
GUI.enabled = true;
// Creation Feedback
GUILayout.Space(5);
GUILayout.BeginVertical(EditorStyles.helpBox, GUILayout.Height(60));
{
EditorGUILayout.TextArea(m_CreationFeedback, TMP_UIStyleManager.label);
}
GUILayout.EndVertical();
GUILayout.Space(5);
GUI.enabled = m_JsonFile != null && m_SpriteAtlas && m_SpriteAsset != null;
if (GUILayout.Button("Save Sprite Asset") && m_JsonFile != null)
{
string filePath = EditorUtility.SaveFilePanel("Save Sprite Asset File", new FileInfo(AssetDatabase.GetAssetPath(m_JsonFile)).DirectoryName, m_JsonFile.name, "asset");
if (filePath.Length == 0)
return;
SaveSpriteAsset(filePath);
}
GUI.enabled = true;
}
/// <summary>
///
/// </summary>
/// <param name="spriteDataObject"></param>
/// <param name="spriteCharacterTable"></param>
/// <param name="spriteGlyphTable"></param>
private static void PopulateSpriteTables(TexturePacker_JsonArray.SpriteDataObject spriteDataObject, List<TMP_SpriteCharacter> spriteCharacterTable, List<TMP_SpriteGlyph> spriteGlyphTable)
{
List<TexturePacker_JsonArray.Frame> importedSprites = spriteDataObject.frames;
float atlasHeight = spriteDataObject.meta.size.h;
for (int i = 0; i < importedSprites.Count; i++)
{
TexturePacker_JsonArray.Frame spriteData = importedSprites[i];
TMP_SpriteGlyph spriteGlyph = new TMP_SpriteGlyph();
spriteGlyph.index = (uint)i;
spriteGlyph.metrics = new GlyphMetrics((int)spriteData.frame.w, (int)spriteData.frame.h, -spriteData.frame.w * spriteData.pivot.x, spriteData.frame.h * spriteData.pivot.y, (int)spriteData.frame.w);
spriteGlyph.glyphRect = new GlyphRect((int)spriteData.frame.x, (int)(atlasHeight - spriteData.frame.h - spriteData.frame.y), (int)spriteData.frame.w, (int)spriteData.frame.h);
spriteGlyph.scale = 1.0f;
spriteGlyphTable.Add(spriteGlyph);
TMP_SpriteCharacter spriteCharacter = new TMP_SpriteCharacter(0xFFFE, spriteGlyph);
// Special handling for .notdef sprite name
string fileNameToLowerInvariant = spriteData.filename.ToLowerInvariant();
if (fileNameToLowerInvariant == ".notdef" || fileNameToLowerInvariant == "notdef")
{
spriteCharacter.name = fileNameToLowerInvariant;
spriteCharacter.unicode = 0;
}
else
{
string spriteName = spriteData.filename.Split('.')[0];
spriteCharacter.name = spriteName;
if (k_SpriteNameIsUnicodeValue)
spriteCharacter.unicode = (uint)TMP_TextUtilities.StringHexToInt(spriteName);
}
spriteCharacter.scale = 1.0f;
spriteCharacterTable.Add(spriteCharacter);
}
}
/// <summary>
///
/// </summary>
/// <param name="filePath"></param>
void SaveSpriteAsset(string filePath)
{
filePath = filePath.Substring(0, filePath.Length - 6); // Trim file extension from filePath.
string dataPath = Application.dataPath;
if (filePath.IndexOf(dataPath, System.StringComparison.InvariantCultureIgnoreCase) == -1)
{
Debug.LogError("You're saving the font asset in a directory outside of this project folder. This is not supported. Please select a directory under \"" + dataPath + "\"");
return;
}
string relativeAssetPath = filePath.Substring(dataPath.Length - 6);
string dirName = Path.GetDirectoryName(relativeAssetPath);
string fileName = Path.GetFileNameWithoutExtension(relativeAssetPath);
string pathNoExt = dirName + "/" + fileName;
// Save Sprite Asset
AssetDatabase.CreateAsset(m_SpriteAsset, pathNoExt + ".asset");
// Set version number
m_SpriteAsset.version = "1.1.0";
// Compute the hash code for the sprite asset.
m_SpriteAsset.hashCode = TMP_TextUtilities.GetSimpleHashCode(m_SpriteAsset.name);
// Add new default material for sprite asset.
AddDefaultMaterial(m_SpriteAsset);
}
/// <summary>
/// Create and add new default material to sprite asset.
/// </summary>
/// <param name="spriteAsset"></param>
static void AddDefaultMaterial(TMP_SpriteAsset spriteAsset)
{
Shader shader = Shader.Find("TextMeshPro/Sprite");
Material material = new Material(shader);
material.SetTexture(ShaderUtilities.ID_MainTex, spriteAsset.spriteSheet);
spriteAsset.material = material;
material.name = spriteAsset.name + " Material";
AssetDatabase.AddObjectToAsset(material, spriteAsset);
}
/// <summary>
/// Limits the minimum size of the editor window.
/// </summary>
void SetEditorWindowSize()
{
EditorWindow editorWindow = this;
Vector2 currentWindowSize = editorWindow.minSize;
editorWindow.minSize = new Vector2(Mathf.Max(230, currentWindowSize.x), Mathf.Max(300, currentWindowSize.y));
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: f1ea944dcf8849ebab391e461b99ccb7
timeCreated: 1480023525
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,463 @@
using UnityEngine;
using UnityEngine.TextCore;
using UnityEngine.U2D;
using UnityEditor;
using System.Linq;
using System.IO;
using System.Collections;
using System.Collections.Generic;
namespace TMPro.EditorUtilities
{
public static class TMP_SpriteAssetMenu
{
// Add a Context Menu to the Sprite Asset Editor Panel to Create and Add a Default Material.
[MenuItem("CONTEXT/TMP_SpriteAsset/Add Default Material", true, 2200)]
static bool AddDefaultMaterialValidate(MenuCommand command)
{
return AssetDatabase.IsOpenForEdit(command.context);
}
[MenuItem("CONTEXT/TMP_SpriteAsset/Add Default Material", false, 2200)]
static void AddDefaultMaterial(MenuCommand command)
{
TMP_SpriteAsset spriteAsset = (TMP_SpriteAsset)command.context;
// Make sure the sprite asset already contains a default material
if (spriteAsset != null && spriteAsset.material == null)
{
// Add new default material for sprite asset.
AddDefaultMaterial(spriteAsset);
}
}
// Add a Context Menu to the Sprite Asset Editor Panel to update existing sprite assets.
[MenuItem("CONTEXT/TMP_SpriteAsset/Update Sprite Asset", true, 2100)]
static bool UpdateSpriteAssetValidate(MenuCommand command)
{
return AssetDatabase.IsOpenForEdit(command.context);
}
[MenuItem("CONTEXT/TMP_SpriteAsset/Update Sprite Asset", false, 2100)]
static void UpdateSpriteAsset(MenuCommand command)
{
TMP_SpriteAsset spriteAsset = (TMP_SpriteAsset)command.context;
if (spriteAsset == null)
return;
UpdateSpriteAsset(spriteAsset);
}
internal static void UpdateSpriteAsset(TMP_SpriteAsset spriteAsset)
{
// Get a list of all the sprites contained in the texture referenced by the sprite asset.
// This only works if the texture is set to sprite mode.
string filePath = AssetDatabase.GetAssetPath(spriteAsset.spriteSheet);
if (string.IsNullOrEmpty(filePath))
return;
// Get all the sprites defined in the sprite sheet texture referenced by this sprite asset.
Sprite[] sprites = AssetDatabase.LoadAllAssetsAtPath(filePath).Select(x => x as Sprite).Where(x => x != null).ToArray();
// Return if sprite sheet texture does not have any sprites defined in it.
if (sprites.Length == 0)
{
Debug.Log("Sprite Asset <color=#FFFF80>[" + spriteAsset.name + "]</color>'s atlas texture does not appear to have any sprites defined in it. Use the Unity Sprite Editor to define sprites for this texture.", spriteAsset.spriteSheet);
return;
}
List<TMP_SpriteGlyph> spriteGlyphTable = spriteAsset.spriteGlyphTable;
// Find available glpyh indexes
uint[] existingGlyphIndexes = spriteGlyphTable.Select(x => x.index).ToArray();
List<uint> availableGlyphIndexes = new List<uint>();
uint lastGlyphIndex = existingGlyphIndexes.Length > 0 ? existingGlyphIndexes.Last() : 0;
int elementIndex = 0;
for (uint i = 0; i < lastGlyphIndex; i++)
{
uint existingGlyphIndex = existingGlyphIndexes[elementIndex];
if (i == existingGlyphIndex)
elementIndex += 1;
else
availableGlyphIndexes.Add(i);
}
// Iterate over sprites contained in the updated sprite sheet to identify new and / or modified sprites.
for (int i = 0; i < sprites.Length; i++)
{
Sprite sprite = sprites[i];
// Check if current sprites is already contained in the sprite glyph table of the sprite asset.
TMP_SpriteGlyph spriteGlyph = spriteGlyphTable.FirstOrDefault(x => x.sprite == sprite);
if (spriteGlyph != null)
{
// update existing sprite glyph
if (spriteGlyph.glyphRect.x != sprite.rect.x || spriteGlyph.glyphRect.y != sprite.rect.y || spriteGlyph.glyphRect.width != sprite.rect.width || spriteGlyph.glyphRect.height != sprite.rect.height)
spriteGlyph.glyphRect = new GlyphRect(sprite.rect);
}
else
{
TMP_SpriteCharacter spriteCharacter;
// Check if this sprite potentially exists under the same name in the sprite character table.
if (spriteAsset.spriteCharacterTable != null && spriteAsset.spriteCharacterTable.Count > 0)
{
spriteCharacter = spriteAsset.spriteCharacterTable.FirstOrDefault(x => x.name == sprite.name);
spriteGlyph = spriteCharacter != null ? spriteGlyphTable[(int)spriteCharacter.glyphIndex] : null;
if (spriteGlyph != null)
{
// Update sprite reference and data
spriteGlyph.sprite = sprite;
if (spriteGlyph.glyphRect.x != sprite.rect.x || spriteGlyph.glyphRect.y != sprite.rect.y || spriteGlyph.glyphRect.width != sprite.rect.width || spriteGlyph.glyphRect.height != sprite.rect.height)
spriteGlyph.glyphRect = new GlyphRect(sprite.rect);
}
}
// Add new Sprite Glyph to the table
spriteGlyph = new TMP_SpriteGlyph();
// Get available glyph index
if (availableGlyphIndexes.Count > 0)
{
spriteGlyph.index = availableGlyphIndexes[0];
availableGlyphIndexes.RemoveAt(0);
}
else
spriteGlyph.index = (uint)spriteGlyphTable.Count;
spriteGlyph.metrics = new GlyphMetrics(sprite.rect.width, sprite.rect.height, -sprite.pivot.x, sprite.rect.height - sprite.pivot.y, sprite.rect.width);
spriteGlyph.glyphRect = new GlyphRect(sprite.rect);
spriteGlyph.scale = 1.0f;
spriteGlyph.sprite = sprite;
spriteGlyphTable.Add(spriteGlyph);
spriteCharacter = new TMP_SpriteCharacter(0xFFFE, spriteGlyph);
// Special handling for .notdef sprite name.
string fileNameToLowerInvariant = sprite.name.ToLowerInvariant();
if (fileNameToLowerInvariant == ".notdef" || fileNameToLowerInvariant == "notdef")
{
spriteCharacter.name = fileNameToLowerInvariant;
spriteCharacter.unicode = 0;
}
else
{
spriteCharacter.unicode = 0xFFFE;
if (!string.IsNullOrEmpty(sprite.name) && sprite.name.Length > 2 && sprite.name[0] == '0' && (sprite.name[1] == 'x' || sprite.name[1] == 'X'))
{
spriteCharacter.unicode = (uint)TMP_TextUtilities.StringHexToInt(sprite.name.Remove(0, 2));
}
spriteCharacter.name = sprite.name;
}
spriteCharacter.scale = 1.0f;
spriteAsset.spriteCharacterTable.Add(spriteCharacter);
}
}
// Update Sprite Character Table to replace unicode 0x0 by 0xFFFE
for (int i = 0; i < spriteAsset.spriteCharacterTable.Count; i++)
{
TMP_SpriteCharacter spriteCharacter = spriteAsset.spriteCharacterTable[i];
if (spriteCharacter.unicode == 0)
spriteCharacter.unicode = 0xFFFE;
}
// Sort glyph table by glyph index
spriteAsset.SortGlyphTable();
spriteAsset.UpdateLookupTables();
TMPro_EventManager.ON_SPRITE_ASSET_PROPERTY_CHANGED(true, spriteAsset);
EditorUtility.SetDirty(spriteAsset);
}
[MenuItem("Assets/Create/TextMeshPro/Sprite Asset", false, 200)]
static void CreateSpriteAsset()
{
Object[] targets = Selection.objects;
if (targets == null)
{
Debug.LogWarning("A Sprite Texture must first be selected in order to create a Sprite Asset.");
return;
}
// Make sure TMP Essential Resources have been imported in the user project.
if (TMP_Settings.instance == null)
{
Debug.Log("Unable to create sprite asset. Please import the TMP Essential Resources.");
// Show Window to Import TMP Essential Resources
return;
}
for (int i = 0; i < targets.Length; i++)
{
Object target = targets[i];
// Make sure the selection is a font file
if (target == null || target.GetType() != typeof(Texture2D))
{
Debug.LogWarning("Selected Object [" + target.name + "] is not a Sprite Texture. A Sprite Texture must be selected in order to create a Sprite Asset.", target);
continue;
}
CreateSpriteAssetFromSelectedObject(target);
}
}
static void CreateSpriteAssetFromSelectedObject(Object target)
{
// Get the path to the selected asset.
string filePathWithName = AssetDatabase.GetAssetPath(target);
string fileNameWithExtension = Path.GetFileName(filePathWithName);
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePathWithName);
string filePath = filePathWithName.Replace(fileNameWithExtension, "");
string uniquePath = AssetDatabase.GenerateUniqueAssetPath(filePath + fileNameWithoutExtension + ".asset");
// Create new Sprite Asset
TMP_SpriteAsset spriteAsset = ScriptableObject.CreateInstance<TMP_SpriteAsset>();
AssetDatabase.CreateAsset(spriteAsset, uniquePath);
spriteAsset.version = "1.1.0";
// Compute the hash code for the sprite asset.
spriteAsset.hashCode = TMP_TextUtilities.GetSimpleHashCode(spriteAsset.name);
List<TMP_SpriteGlyph> spriteGlyphTable = new List<TMP_SpriteGlyph>();
List<TMP_SpriteCharacter> spriteCharacterTable = new List<TMP_SpriteCharacter>();
if (target.GetType() == typeof(Texture2D))
{
Texture2D sourceTex = target as Texture2D;
// Assign new Sprite Sheet texture to the Sprite Asset.
spriteAsset.spriteSheet = sourceTex;
PopulateSpriteTables(sourceTex, ref spriteCharacterTable, ref spriteGlyphTable);
spriteAsset.spriteCharacterTable = spriteCharacterTable;
spriteAsset.spriteGlyphTable = spriteGlyphTable;
// Add new default material for sprite asset.
AddDefaultMaterial(spriteAsset);
}
else if (target.GetType() == typeof(SpriteAtlas))
{
//SpriteAtlas spriteAtlas = target as SpriteAtlas;
//PopulateSpriteTables(spriteAtlas, ref spriteCharacterTable, ref spriteGlyphTable);
//spriteAsset.spriteCharacterTable = spriteCharacterTable;
//spriteAsset.spriteGlyphTable = spriteGlyphTable;
//spriteAsset.spriteSheet = spriteGlyphTable[0].sprite.texture;
//// Add new default material for sprite asset.
//AddDefaultMaterial(spriteAsset);
}
// Update Lookup tables.
spriteAsset.UpdateLookupTables();
// Get the Sprites contained in the Sprite Sheet
EditorUtility.SetDirty(spriteAsset);
//spriteAsset.sprites = sprites;
// Set source texture back to Not Readable.
//texImporter.isReadable = false;
AssetDatabase.SaveAssets();
AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(spriteAsset)); // Re-import font asset to get the new updated version.
//AssetDatabase.Refresh();
}
static void PopulateSpriteTables(Texture source, ref List<TMP_SpriteCharacter> spriteCharacterTable, ref List<TMP_SpriteGlyph> spriteGlyphTable)
{
//Debug.Log("Creating new Sprite Asset.");
string filePath = AssetDatabase.GetAssetPath(source);
// Get all the Sprites sorted by Index
Sprite[] sprites = AssetDatabase.LoadAllAssetsAtPath(filePath).Select(x => x as Sprite).Where(x => x != null).OrderByDescending(x => x.rect.y).ThenBy(x => x.rect.x).ToArray();
for (int i = 0; i < sprites.Length; i++)
{
Sprite sprite = sprites[i];
TMP_SpriteGlyph spriteGlyph = new TMP_SpriteGlyph();
spriteGlyph.index = (uint)i;
spriteGlyph.metrics = new GlyphMetrics(sprite.rect.width, sprite.rect.height, -sprite.pivot.x, sprite.rect.height - sprite.pivot.y, sprite.rect.width);
spriteGlyph.glyphRect = new GlyphRect(sprite.rect);
spriteGlyph.scale = 1.0f;
spriteGlyph.sprite = sprite;
spriteGlyphTable.Add(spriteGlyph);
TMP_SpriteCharacter spriteCharacter = new TMP_SpriteCharacter(0xFFFE, spriteGlyph);
// Special handling for .notdef sprite name.
string fileNameToLowerInvariant = sprite.name.ToLowerInvariant();
if (fileNameToLowerInvariant == ".notdef" || fileNameToLowerInvariant == "notdef")
{
spriteCharacter.unicode = 0;
spriteCharacter.name = fileNameToLowerInvariant;
}
else
{
if (!string.IsNullOrEmpty(sprite.name) && sprite.name.Length > 2 && sprite.name[0] == '0' && (sprite.name[1] == 'x' || sprite.name[1] == 'X'))
{
spriteCharacter.unicode = (uint)TMP_TextUtilities.StringHexToInt(sprite.name.Remove(0, 2));
}
spriteCharacter.name = sprite.name;
}
spriteCharacter.scale = 1.0f;
spriteCharacterTable.Add(spriteCharacter);
}
}
static void PopulateSpriteTables(SpriteAtlas spriteAtlas, ref List<TMP_SpriteCharacter> spriteCharacterTable, ref List<TMP_SpriteGlyph> spriteGlyphTable)
{
// Get number of sprites contained in the sprite atlas.
int spriteCount = spriteAtlas.spriteCount;
Sprite[] sprites = new Sprite[spriteCount];
// Get all the sprites
spriteAtlas.GetSprites(sprites);
for (int i = 0; i < sprites.Length; i++)
{
Sprite sprite = sprites[i];
TMP_SpriteGlyph spriteGlyph = new TMP_SpriteGlyph();
spriteGlyph.index = (uint)i;
spriteGlyph.metrics = new GlyphMetrics(sprite.textureRect.width, sprite.textureRect.height, -sprite.pivot.x, sprite.textureRect.height - sprite.pivot.y, sprite.textureRect.width);
spriteGlyph.glyphRect = new GlyphRect(sprite.textureRect);
spriteGlyph.scale = 1.0f;
spriteGlyph.sprite = sprite;
spriteGlyphTable.Add(spriteGlyph);
TMP_SpriteCharacter spriteCharacter = new TMP_SpriteCharacter(0xFFFE, spriteGlyph);
spriteCharacter.name = sprite.name;
spriteCharacter.scale = 1.0f;
spriteCharacterTable.Add(spriteCharacter);
}
}
/// <summary>
/// Create and add new default material to sprite asset.
/// </summary>
/// <param name="spriteAsset"></param>
static void AddDefaultMaterial(TMP_SpriteAsset spriteAsset)
{
Shader shader = Shader.Find("TextMeshPro/Sprite");
Material material = new Material(shader);
material.SetTexture(ShaderUtilities.ID_MainTex, spriteAsset.spriteSheet);
spriteAsset.material = material;
material.name = spriteAsset.name + " Material";
AssetDatabase.AddObjectToAsset(material, spriteAsset);
}
// Update existing SpriteInfo
static List<TMP_Sprite> UpdateSpriteInfo(TMP_SpriteAsset spriteAsset)
{
//Debug.Log("Updating Sprite Asset.");
string filePath = AssetDatabase.GetAssetPath(spriteAsset.spriteSheet);
// Get all the Sprites sorted Left to Right / Top to Bottom
Sprite[] sprites = AssetDatabase.LoadAllAssetsAtPath(filePath).Select(x => x as Sprite).Where(x => x != null).OrderByDescending(x => x.rect.y).ThenBy(x => x.rect.x).ToArray();
for (int i = 0; i < sprites.Length; i++)
{
Sprite sprite = sprites[i];
// Check if the sprite is already contained in the SpriteInfoList
int index = -1;
if (spriteAsset.spriteInfoList.Count > i && spriteAsset.spriteInfoList[i].sprite != null)
index = spriteAsset.spriteInfoList.FindIndex(item => item.sprite.GetInstanceID() == sprite.GetInstanceID());
// Use existing SpriteInfo if it already exists
TMP_Sprite spriteInfo = index == -1 ? new TMP_Sprite() : spriteAsset.spriteInfoList[index];
Rect spriteRect = sprite.rect;
spriteInfo.x = spriteRect.x;
spriteInfo.y = spriteRect.y;
spriteInfo.width = spriteRect.width;
spriteInfo.height = spriteRect.height;
// Get Sprite Pivot
Vector2 pivot = new Vector2(0 - (sprite.bounds.min.x) / (sprite.bounds.extents.x * 2), 0 - (sprite.bounds.min.y) / (sprite.bounds.extents.y * 2));
// The position of the pivot influences the Offset position.
spriteInfo.pivot = new Vector2(0 - pivot.x * spriteRect.width, spriteRect.height - pivot.y * spriteRect.height);
if (index == -1)
{
// Find the next available index for this Sprite
int[] ids = spriteAsset.spriteInfoList.Select(item => item.id).ToArray();
int id = 0;
for (int j = 0; j < ids.Length; j++ )
{
if (ids[0] != 0) break;
if (j > 0 && (ids[j] - ids[j - 1]) > 1)
{
id = ids[j - 1] + 1;
break;
}
id = j + 1;
}
spriteInfo.sprite = sprite;
spriteInfo.name = sprite.name;
spriteInfo.hashCode = TMP_TextUtilities.GetSimpleHashCode(spriteInfo.name);
spriteInfo.id = id;
spriteInfo.xAdvance = spriteRect.width;
spriteInfo.scale = 1.0f;
spriteInfo.xOffset = spriteInfo.pivot.x;
spriteInfo.yOffset = spriteInfo.pivot.y;
spriteAsset.spriteInfoList.Add(spriteInfo);
// Sort the Sprites by ID
spriteAsset.spriteInfoList = spriteAsset.spriteInfoList.OrderBy(s => s.id).ToList();
}
else
{
spriteAsset.spriteInfoList[index] = spriteInfo;
}
}
return spriteAsset.spriteInfoList;
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 1048a87135154606808bf2030da32d18
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,47 @@
using UnityEngine;
using UnityEditor;
using System.IO;
namespace TMPro.EditorUtilities
{
public static class TMP_StyleAssetMenu
{
[MenuItem("Assets/Create/TextMeshPro/Style Sheet", false, 210)]
internal static void CreateTextMeshProObjectPerform()
{
string filePath;
if (Selection.assetGUIDs.Length == 0)
{
// No asset selected.
filePath = "Assets";
}
else
{
// Get the path of the selected folder or asset.
filePath = AssetDatabase.GUIDToAssetPath(Selection.assetGUIDs[0]);
// Get the file extension of the selected asset as it might need to be removed.
string fileExtension = Path.GetExtension(filePath);
if (fileExtension != "")
{
filePath = Path.GetDirectoryName(filePath);
}
}
string filePathWithName = AssetDatabase.GenerateUniqueAssetPath(filePath + "/Text StyleSheet.asset");
// Create new Style Sheet Asset.
TMP_StyleSheet styleSheet = ScriptableObject.CreateInstance<TMP_StyleSheet>();
AssetDatabase.CreateAsset(styleSheet, filePathWithName);
EditorUtility.SetDirty(styleSheet);
AssetDatabase.SaveAssets();
EditorUtility.FocusProjectWindow();
EditorGUIUtility.PingObject(styleSheet);
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 23a562f2cac6401f9f91251c68a1a794
timeCreated: 1432690168
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,321 @@
using System;
using UnityEngine;
using UnityEditor;
namespace TMPro.EditorUtilities
{
[CustomPropertyDrawer(typeof(TMP_Style))]
public class StyleDrawer : PropertyDrawer
{
public static readonly float height = 95f;
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return height;
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
SerializedProperty nameProperty = property.FindPropertyRelative("m_Name");
SerializedProperty hashCodeProperty = property.FindPropertyRelative("m_HashCode");
SerializedProperty openingDefinitionProperty = property.FindPropertyRelative("m_OpeningDefinition");
SerializedProperty closingDefinitionProperty = property.FindPropertyRelative("m_ClosingDefinition");
SerializedProperty openingDefinitionArray = property.FindPropertyRelative("m_OpeningTagArray");
SerializedProperty closingDefinitionArray = property.FindPropertyRelative("m_ClosingTagArray");
EditorGUIUtility.labelWidth = 86;
position.height = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
float labelHeight = position.height + 2f;
EditorGUI.BeginChangeCheck();
Rect rect0 = new Rect(position.x, position.y, (position.width) / 2 + 5, position.height);
EditorGUI.PropertyField(rect0, nameProperty);
if (EditorGUI.EndChangeCheck())
{
// Recompute HashCode if name has changed.
hashCodeProperty.intValue = TMP_TextUtilities.GetSimpleHashCode(nameProperty.stringValue);
property.serializedObject.ApplyModifiedProperties();
// Dictionary needs to be updated since HashCode has changed.
TMP_StyleSheet styleSheet = property.serializedObject.targetObject as TMP_StyleSheet;
styleSheet.RefreshStyles();
}
// HashCode
Rect rect1 = new Rect(rect0.x + rect0.width + 5, position.y, 65, position.height);
GUI.Label(rect1, "HashCode");
GUI.enabled = false;
rect1.x += 65;
rect1.width = position.width / 2 - 75;
EditorGUI.PropertyField(rect1, hashCodeProperty, GUIContent.none);
GUI.enabled = true;
// Text Tags
EditorGUI.BeginChangeCheck();
// Opening Tags
position.y += labelHeight;
GUI.Label(position, "Opening Tags");
Rect textRect1 = new Rect(110, position.y, position.width - 86, 35);
openingDefinitionProperty.stringValue = EditorGUI.TextArea(textRect1, openingDefinitionProperty.stringValue);
if (EditorGUI.EndChangeCheck())
{
// If any properties have changed, we need to update the Opening and Closing Arrays.
int size = openingDefinitionProperty.stringValue.Length;
// Adjust array size to match new string length.
if (openingDefinitionArray.arraySize != size) openingDefinitionArray.arraySize = size;
for (int i = 0; i < size; i++)
{
SerializedProperty element = openingDefinitionArray.GetArrayElementAtIndex(i);
element.intValue = openingDefinitionProperty.stringValue[i];
}
}
EditorGUI.BeginChangeCheck();
// Closing Tags
position.y += 38;
GUI.Label(position, "Closing Tags");
Rect textRect2 = new Rect(110, position.y, position.width - 86, 35);
closingDefinitionProperty.stringValue = EditorGUI.TextArea(textRect2, closingDefinitionProperty.stringValue);
if (EditorGUI.EndChangeCheck())
{
// If any properties have changed, we need to update the Opening and Closing Arrays.
int size = closingDefinitionProperty.stringValue.Length;
// Adjust array size to match new string length.
if (closingDefinitionArray.arraySize != size) closingDefinitionArray.arraySize = size;
for (int i = 0; i < size; i++)
{
SerializedProperty element = closingDefinitionArray.GetArrayElementAtIndex(i);
element.intValue = closingDefinitionProperty.stringValue[i];
}
}
}
}
[CustomEditor(typeof(TMP_StyleSheet)), CanEditMultipleObjects]
public class TMP_StyleEditor : Editor
{
TMP_StyleSheet m_StyleSheet;
SerializedProperty m_StyleListProp;
int m_SelectedElement = -1;
int m_Page;
bool m_IsStyleSheetDirty;
void OnEnable()
{
m_StyleSheet = target as TMP_StyleSheet;
m_StyleListProp = serializedObject.FindProperty("m_StyleList");
}
public override void OnInspectorGUI()
{
Event currentEvent = Event.current;
serializedObject.Update();
m_IsStyleSheetDirty = false;
int elementCount = m_StyleListProp.arraySize;
int itemsPerPage = (Screen.height - 100) / 110;
if (elementCount > 0)
{
// Display each Style entry using the StyleDrawer PropertyDrawer.
for (int i = itemsPerPage * m_Page; i < elementCount && i < itemsPerPage * (m_Page + 1); i++)
{
// Define the start of the selection region of the element.
Rect elementStartRegion = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true));
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
SerializedProperty styleProperty = m_StyleListProp.GetArrayElementAtIndex(i);
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(styleProperty);
EditorGUILayout.EndVertical();
if (EditorGUI.EndChangeCheck())
{
//
}
// Define the end of the selection region of the element.
Rect elementEndRegion = GUILayoutUtility.GetRect(0f, 0f, GUILayout.ExpandWidth(true));
// Check for Item selection
Rect selectionArea = new Rect(elementStartRegion.x, elementStartRegion.y, elementEndRegion.width, elementEndRegion.y - elementStartRegion.y);
if (DoSelectionCheck(selectionArea))
{
if (m_SelectedElement == i)
{
m_SelectedElement = -1;
}
else
{
m_SelectedElement = i;
GUIUtility.keyboardControl = 0;
}
}
// Handle Selection Highlighting
if (m_SelectedElement == i)
TMP_EditorUtility.DrawBox(selectionArea, 2f, new Color32(40, 192, 255, 255));
}
}
// STYLE LIST MANAGEMENT
Rect rect = EditorGUILayout.GetControlRect(false, 20);
float totalWidth = rect.width;
rect.width = totalWidth * 0.175f;
// Move Style up.
bool guiEnabled = GUI.enabled;
if (m_SelectedElement == -1 || m_SelectedElement == 0) { GUI.enabled = false; }
if (GUI.Button(rect, "Up"))
{
SwapStyleElements(m_SelectedElement, m_SelectedElement - 1);
}
GUI.enabled = guiEnabled;
// Move Style down.
rect.x += rect.width;
if (m_SelectedElement == elementCount - 1) { GUI.enabled = false; }
if (GUI.Button(rect, "Down"))
{
SwapStyleElements(m_SelectedElement, m_SelectedElement + 1);
}
GUI.enabled = guiEnabled;
// Add Style
rect.x += rect.width + totalWidth * 0.3f;
if (GUI.Button(rect, "+"))
{
int index = m_SelectedElement == -1 ? elementCount : m_SelectedElement;
if (index > elementCount)
index = elementCount;
// Copy selected element
m_StyleListProp.InsertArrayElementAtIndex(index);
// Select newly inserted element
m_SelectedElement = index + 1;
serializedObject.ApplyModifiedProperties();
m_StyleSheet.RefreshStyles();
}
// Delete style
rect.x += rect.width;
if (m_SelectedElement == -1 || m_SelectedElement >= elementCount) GUI.enabled = false;
if (GUI.Button(rect, "-"))
{
int index = m_SelectedElement == -1 ? 0 : m_SelectedElement;
m_StyleListProp.DeleteArrayElementAtIndex(index);
m_SelectedElement = -1;
serializedObject.ApplyModifiedProperties();
m_StyleSheet.RefreshStyles();
return;
}
// Return if we can't display any items.
if (itemsPerPage == 0) return;
// DISPLAY PAGE CONTROLS
int shiftMultiplier = currentEvent.shift ? 10 : 1; // Page + Shift goes 10 page forward
Rect pagePos = EditorGUILayout.GetControlRect(false, 20);
pagePos.width = totalWidth * 0.35f;
// Previous Page
if (m_Page > 0) GUI.enabled = true;
else GUI.enabled = false;
if (GUI.Button(pagePos, "Previous"))
m_Page -= 1 * shiftMultiplier;
// PAGE COUNTER
GUI.enabled = true;
pagePos.x += pagePos.width;
pagePos.width = totalWidth * 0.30f;
int totalPages = (int)(elementCount / (float)itemsPerPage + 0.999f);
GUI.Label(pagePos, "Page " + (m_Page + 1) + " / " + totalPages, TMP_UIStyleManager.centeredLabel);
// Next Page
pagePos.x += pagePos.width;
pagePos.width = totalWidth * 0.35f;
if (itemsPerPage * (m_Page + 1) < elementCount) GUI.enabled = true;
else GUI.enabled = false;
if (GUI.Button(pagePos, "Next"))
m_Page += 1 * shiftMultiplier;
// Clamp page range
m_Page = Mathf.Clamp(m_Page, 0, elementCount / itemsPerPage);
if (serializedObject.ApplyModifiedProperties())
{
TMPro_EventManager.ON_TEXT_STYLE_PROPERTY_CHANGED(true);
if (m_IsStyleSheetDirty)
{
m_IsStyleSheetDirty = false;
m_StyleSheet.RefreshStyles();
}
}
// Clear selection if mouse event was not consumed.
GUI.enabled = true;
if (currentEvent.type == EventType.MouseDown && currentEvent.button == 0)
m_SelectedElement = -1;
}
// Check if any of the Style elements were clicked on.
static bool DoSelectionCheck(Rect selectionArea)
{
Event currentEvent = Event.current;
switch (currentEvent.type)
{
case EventType.MouseDown:
if (selectionArea.Contains(currentEvent.mousePosition) && currentEvent.button == 0)
{
currentEvent.Use();
return true;
}
break;
}
return false;
}
void SwapStyleElements(int selectedIndex, int newIndex)
{
m_StyleListProp.MoveArrayElement(selectedIndex, newIndex);
m_SelectedElement = newIndex;
m_IsStyleSheetDirty = true;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 34e2c9b9d9e44953933afe37461f44e6
timeCreated: 1432683777
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,103 @@
using UnityEngine;
using UnityEditor;
using System.Collections;
namespace TMPro.EditorUtilities
{
[CustomEditor(typeof(TMP_SubMeshUI)), CanEditMultipleObjects]
public class TMP_SubMeshUI_Editor : Editor
{
private struct m_foldout
{ // Track Inspector foldout panel states, globally.
//public static bool textInput = true;
public static bool fontSettings = true;
//public static bool extraSettings = false;
//public static bool shadowSetting = false;
//public static bool materialEditor = true;
}
private SerializedProperty fontAsset_prop;
private SerializedProperty spriteAsset_prop;
//private TMP_SubMeshUI m_SubMeshComponent;
//private CanvasRenderer m_canvasRenderer;
private Material m_targetMaterial;
public void OnEnable()
{
fontAsset_prop = serializedObject.FindProperty("m_fontAsset");
spriteAsset_prop = serializedObject.FindProperty("m_spriteAsset");
//m_SubMeshComponent = target as TMP_SubMeshUI;
//m_rectTransform = m_SubMeshComponent.rectTransform;
//m_canvasRenderer = m_SubMeshComponent.canvasRenderer;
// Create new Material Editor if one does not exists
/*
if (m_canvasRenderer != null && m_canvasRenderer.GetMaterial() != null)
{
m_materialEditor = Editor.CreateEditor(m_canvasRenderer.GetMaterial());
m_targetMaterial = m_canvasRenderer.GetMaterial();
}
*/
}
public void OnDisable()
{
// Destroy material editor if one exists
/*
if (m_materialEditor != null)
{
//Debug.Log("Destroying Inline Material Editor.");
DestroyImmediate(m_materialEditor);
}
*/
}
public override void OnInspectorGUI()
{
GUI.enabled = false;
EditorGUILayout.PropertyField(fontAsset_prop);
EditorGUILayout.PropertyField(spriteAsset_prop);
GUI.enabled = true;
EditorGUILayout.Space();
// If a Custom Material Editor exists, we use it.
/*
if (m_canvasRenderer != null && m_canvasRenderer.GetMaterial() != null)
{
Material mat = m_canvasRenderer.GetMaterial();
//Debug.Log(mat + " " + m_targetMaterial);
if (mat != m_targetMaterial)
{
// Destroy previous Material Instance
//Debug.Log("New Material has been assigned.");
m_targetMaterial = mat;
DestroyImmediate(m_materialEditor);
}
if (m_materialEditor == null)
{
m_materialEditor = Editor.CreateEditor(mat);
}
m_materialEditor.DrawHeader();
m_materialEditor.OnInspectorGUI();
}
*/
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 6b01141ed8f74d198965c86f25eb7040
timeCreated: 1452757501
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,71 @@
using UnityEngine;
using UnityEditor;
using System.Collections;
namespace TMPro.EditorUtilities
{
[CustomEditor(typeof(TMP_SubMesh)), CanEditMultipleObjects]
public class TMP_SubMesh_Editor : Editor
{
private struct m_foldout
{ // Track Inspector foldout panel states, globally.
//public static bool textInput = true;
public static bool fontSettings = true;
//public static bool extraSettings = false;
//public static bool shadowSetting = false;
//public static bool materialEditor = true;
}
private SerializedProperty fontAsset_prop;
private SerializedProperty spriteAsset_prop;
private TMP_SubMesh m_SubMeshComponent;
private Renderer m_Renderer;
private string[] m_SortingLayerNames;
public void OnEnable()
{
fontAsset_prop = serializedObject.FindProperty("m_fontAsset");
spriteAsset_prop = serializedObject.FindProperty("m_spriteAsset");
m_SubMeshComponent = target as TMP_SubMesh;
m_Renderer = m_SubMeshComponent.renderer;
m_SortingLayerNames = SortingLayerHelper.sortingLayerNames;
}
public override void OnInspectorGUI()
{
EditorGUI.indentLevel = 0;
GUI.enabled = false;
EditorGUILayout.PropertyField(fontAsset_prop);
EditorGUILayout.PropertyField(spriteAsset_prop);
GUI.enabled = true;
EditorGUI.BeginChangeCheck();
// Look up the layer name using the current layer ID
string oldName = SortingLayer.IDToName(m_Renderer.sortingLayerID);
// Use the name to look up our array index into the names list
int oldLayerIndex = System.Array.IndexOf(m_SortingLayerNames, oldName);
// Show the pop-up for the names
int newLayerIndex = EditorGUILayout.Popup("Sorting Layer", oldLayerIndex, m_SortingLayerNames);
// If the index changes, look up the ID for the new index to store as the new ID
if (newLayerIndex != oldLayerIndex)
m_Renderer.sortingLayerID = SortingLayer.NameToID(m_SortingLayerNames[newLayerIndex]);
// Expose the manual sorting order
int newSortingLayerOrder = EditorGUILayout.IntField("Order in Layer", m_Renderer.sortingOrder);
if (newSortingLayerOrder != m_Renderer.sortingOrder)
m_Renderer.sortingOrder = newSortingLayerOrder;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: dd2fe74169b54bf58fca17288513ef38
timeCreated: 1456189048
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,134 @@
using UnityEngine;
using UnityEditor;
using System.Collections;
namespace TMPro.EditorUtilities
{
public static class TMP_UIStyleManager
{
public static GUIStyle label;
public static GUIStyle textAreaBoxWindow;
public static GUIStyle boldFoldout;
public static GUIStyle panelTitle;
public static GUIStyle sectionHeader;
public static GUIStyle centeredLabel;
public static GUIStyle rightLabel;
public static GUIStyle wrappingTextArea;
public static GUIStyle alignmentButtonLeft;
public static GUIStyle alignmentButtonMid;
public static GUIStyle alignmentButtonRight;
// Alignment Button Textures
public static Texture2D alignLeft;
public static Texture2D alignCenter;
public static Texture2D alignRight;
public static Texture2D alignJustified;
public static Texture2D alignFlush;
public static Texture2D alignGeoCenter;
public static Texture2D alignTop;
public static Texture2D alignMiddle;
public static Texture2D alignBottom;
public static Texture2D alignBaseline;
public static Texture2D alignMidline;
public static Texture2D alignCapline;
public static Texture2D sectionHeaderTexture;
public static GUIContent[] alignContentA;
public static GUIContent[] alignContentB;
static TMP_UIStyleManager()
{
// Find to location of the TextMesh Pro Asset Folder (as users may have moved it)
var tmproAssetFolderPath = TMP_EditorUtility.packageRelativePath;
if (EditorGUIUtility.isProSkin)
{
alignLeft = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignLeft.psd", typeof(Texture2D)) as Texture2D;
alignCenter = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignCenter.psd", typeof(Texture2D)) as Texture2D;
alignRight = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignRight.psd", typeof(Texture2D)) as Texture2D;
alignJustified = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignJustified.psd", typeof(Texture2D)) as Texture2D;
alignFlush = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignFlush.psd", typeof(Texture2D)) as Texture2D;
alignGeoCenter = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignCenterGeo.psd", typeof(Texture2D)) as Texture2D;
alignTop = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignTop.psd", typeof(Texture2D)) as Texture2D;
alignMiddle = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignMiddle.psd", typeof(Texture2D)) as Texture2D;
alignBottom = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignBottom.psd", typeof(Texture2D)) as Texture2D;
alignBaseline = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignBaseLine.psd", typeof(Texture2D)) as Texture2D;
alignMidline = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignMidLine.psd", typeof(Texture2D)) as Texture2D;
alignCapline = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignCapLine.psd", typeof(Texture2D)) as Texture2D;
sectionHeaderTexture = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/SectionHeader_Dark.psd", typeof(Texture2D)) as Texture2D;
}
else
{
alignLeft = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignLeft_Light.psd", typeof(Texture2D)) as Texture2D;
alignCenter = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignCenter_Light.psd", typeof(Texture2D)) as Texture2D;
alignRight = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignRight_Light.psd", typeof(Texture2D)) as Texture2D;
alignJustified = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignJustified_Light.psd", typeof(Texture2D)) as Texture2D;
alignFlush = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignFlush_Light.psd", typeof(Texture2D)) as Texture2D;
alignGeoCenter = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignCenterGeo_Light.psd", typeof(Texture2D)) as Texture2D;
alignTop = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignTop_Light.psd", typeof(Texture2D)) as Texture2D;
alignMiddle = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignMiddle_Light.psd", typeof(Texture2D)) as Texture2D;
alignBottom = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignBottom_Light.psd", typeof(Texture2D)) as Texture2D;
alignBaseline = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignBaseLine_Light.psd", typeof(Texture2D)) as Texture2D;
alignMidline = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignMidLine_Light.psd", typeof(Texture2D)) as Texture2D;
alignCapline = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/btn_AlignCapLine_Light.psd", typeof(Texture2D)) as Texture2D;
sectionHeaderTexture = AssetDatabase.LoadAssetAtPath(tmproAssetFolderPath + "/Editor Resources/Textures/SectionHeader_Light.psd", typeof(Texture2D)) as Texture2D;
}
label = new GUIStyle(EditorStyles.label) { richText = true, wordWrap = true, stretchWidth = true };
textAreaBoxWindow = new GUIStyle(EditorStyles.textArea) { richText = true };
boldFoldout = new GUIStyle(EditorStyles.foldout) { fontStyle = FontStyle.Bold };
panelTitle = new GUIStyle(EditorStyles.label) { fontStyle = FontStyle.Bold };
sectionHeader = new GUIStyle(EditorStyles.label) { fixedHeight = 22, richText = true, border = new RectOffset(9, 9, 0, 0), overflow = new RectOffset(9, 0, 0, 0), padding = new RectOffset(0, 0, 4, 0) };
sectionHeader.normal.background = sectionHeaderTexture;
centeredLabel = new GUIStyle(EditorStyles.label) { alignment = TextAnchor.MiddleCenter};
rightLabel = new GUIStyle(EditorStyles.label) { alignment = TextAnchor.MiddleRight, richText = true };
alignmentButtonLeft = new GUIStyle(EditorStyles.miniButtonLeft);
alignmentButtonLeft.padding.left = 4;
alignmentButtonLeft.padding.right = 4;
alignmentButtonLeft.padding.top = 2;
alignmentButtonLeft.padding.bottom = 2;
alignmentButtonMid = new GUIStyle(EditorStyles.miniButtonMid);
alignmentButtonMid.padding.left = 4;
alignmentButtonMid.padding.right = 4;
alignmentButtonLeft.padding.top = 2;
alignmentButtonLeft.padding.bottom = 2;
alignmentButtonRight = new GUIStyle(EditorStyles.miniButtonRight);
alignmentButtonRight.padding.left = 4;
alignmentButtonRight.padding.right = 4;
alignmentButtonLeft.padding.top = 2;
alignmentButtonLeft.padding.bottom = 2;
wrappingTextArea = new GUIStyle(EditorStyles.textArea);
wrappingTextArea.wordWrap = true;
alignContentA = new []
{
new GUIContent(alignLeft, "Left"),
new GUIContent(alignCenter, "Center"),
new GUIContent(alignRight, "Right"),
new GUIContent(alignJustified, "Justified"),
new GUIContent(alignFlush, "Flush"),
new GUIContent(alignGeoCenter, "Geometry Center")
};
alignContentB = new []
{
new GUIContent(alignTop, "Top"),
new GUIContent(alignMiddle, "Middle"),
new GUIContent(alignBottom, "Bottom"),
new GUIContent(alignBaseline, "Baseline"),
new GUIContent(alignMidline, "Midline"),
new GUIContent(alignCapline, "Capline")
};
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 30a939dce2fd4073955f2f20e659d506
timeCreated: 1426454127
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,493 @@
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Collections;
using UnityEngine.TextCore.LowLevel;
using UnityEngine.TextCore.Text;
namespace TMPro.EditorUtilities
{
public class TMP_ContextMenus : Editor
{
private static Texture m_copiedTexture;
private static Material m_copiedProperties;
private static Material m_copiedAtlasProperties;
// Add a Context Menu to the Texture Editor Panel to allow Copy / Paste of Texture.
#if !TEXTCORE_1_0_OR_NEWER
[MenuItem("CONTEXT/Texture/Copy", false, 2000)]
static void CopyTexture(MenuCommand command)
{
m_copiedTexture = command.context as Texture;
}
// Select the currently assigned material or material preset.
[MenuItem("CONTEXT/Material/Select Material", false, 500)]
static void SelectMaterial(MenuCommand command)
{
Material mat = command.context as Material;
// Select current material
EditorUtility.FocusProjectWindow();
EditorGUIUtility.PingObject(mat);
}
#endif
// Add a Context Menu to allow easy duplication of the Material.
[MenuItem("CONTEXT/Material/Create Material Preset", false)]
static void DuplicateMaterial(MenuCommand command)
{
// Get the type of text object
// If material is not a base material, we get material leaks...
Material source_Mat = (Material)command.context;
if (!EditorUtility.IsPersistent(source_Mat))
{
Debug.LogWarning("Material is an instance and cannot be converted into a persistent asset.");
return;
}
string assetPath = AssetDatabase.GetAssetPath(source_Mat).Split('.')[0];
if (assetPath.IndexOf("Assets/", System.StringComparison.InvariantCultureIgnoreCase) == -1)
{
Debug.LogWarning("Material Preset cannot be created from a material that is located outside the project.");
return;
}
Material duplicate = new Material(source_Mat);
// Need to manually copy the shader keywords
duplicate.shaderKeywords = source_Mat.shaderKeywords;
AssetDatabase.CreateAsset(duplicate, AssetDatabase.GenerateUniqueAssetPath(assetPath + ".mat"));
GameObject[] selectedObjects = Selection.gameObjects;
// Assign new Material Preset to selected text objects.
for (int i = 0; i < selectedObjects.Length; i++)
{
TMP_Text textObject = selectedObjects[i].GetComponent<TMP_Text>();
if (textObject != null)
{
textObject.fontSharedMaterial = duplicate;
}
else
{
TMP_SubMesh subMeshObject = selectedObjects[i].GetComponent<TMP_SubMesh>();
if (subMeshObject != null)
subMeshObject.sharedMaterial = duplicate;
else
{
TMP_SubMeshUI subMeshUIObject = selectedObjects[i].GetComponent<TMP_SubMeshUI>();
if (subMeshUIObject != null)
subMeshUIObject.sharedMaterial = duplicate;
}
}
}
// Ping newly created Material Preset.
EditorUtility.FocusProjectWindow();
EditorGUIUtility.PingObject(duplicate);
}
// COPY MATERIAL PROPERTIES
#if !TEXTCORE_1_0_OR_NEWER
[MenuItem("CONTEXT/Material/Copy Material Properties", false)]
static void CopyMaterialProperties(MenuCommand command)
{
Material mat = null;
if (command.context.GetType() == typeof(Material))
mat = (Material)command.context;
else
{
mat = Selection.activeGameObject.GetComponent<CanvasRenderer>().GetMaterial();
}
m_copiedProperties = new Material(mat);
m_copiedProperties.shaderKeywords = mat.shaderKeywords;
m_copiedProperties.hideFlags = HideFlags.DontSave;
}
// PASTE MATERIAL PROPERTIES
[MenuItem("CONTEXT/Material/Paste Material Properties", true)]
static bool PasteMaterialPropertiesValidate(MenuCommand command)
{
if (m_copiedProperties == null)
return false;
return AssetDatabase.IsOpenForEdit(command.context);
}
[MenuItem("CONTEXT/Material/Paste Material Properties", false)]
static void PasteMaterialProperties(MenuCommand command)
{
if (m_copiedProperties == null)
{
Debug.LogWarning("No Material Properties to Paste. Use Copy Material Properties first.");
return;
}
Material mat = null;
if (command.context.GetType() == typeof(Material))
mat = (Material)command.context;
else
{
mat = Selection.activeGameObject.GetComponent<CanvasRenderer>().GetMaterial();
}
Undo.RecordObject(mat, "Paste Material");
ShaderUtilities.GetShaderPropertyIDs(); // Make sure we have valid Property IDs
if (mat.HasProperty(ShaderUtilities.ID_GradientScale))
{
// Preserve unique SDF properties from destination material.
m_copiedProperties.SetTexture(ShaderUtilities.ID_MainTex, mat.GetTexture(ShaderUtilities.ID_MainTex));
m_copiedProperties.SetFloat(ShaderUtilities.ID_GradientScale, mat.GetFloat(ShaderUtilities.ID_GradientScale));
m_copiedProperties.SetFloat(ShaderUtilities.ID_TextureWidth, mat.GetFloat(ShaderUtilities.ID_TextureWidth));
m_copiedProperties.SetFloat(ShaderUtilities.ID_TextureHeight, mat.GetFloat(ShaderUtilities.ID_TextureHeight));
}
EditorShaderUtilities.CopyMaterialProperties(m_copiedProperties, mat);
// Copy ShaderKeywords from one material to the other.
mat.shaderKeywords = m_copiedProperties.shaderKeywords;
// Let TextMeshPro Objects that this mat has changed.
TMPro_EventManager.ON_MATERIAL_PROPERTY_CHANGED(true, mat);
}
// Enable Resetting of Material properties without losing unique properties of the font atlas.
[MenuItem("CONTEXT/Material/Reset", true, 2100)]
static bool ResetSettingsValidate(MenuCommand command)
{
return AssetDatabase.IsOpenForEdit(command.context);
}
[MenuItem("CONTEXT/Material/Reset", false, 2100)]
static void ResetSettings(MenuCommand command)
{
Material mat = null;
if (command.context.GetType() == typeof(Material))
mat = (Material)command.context;
else
{
mat = Selection.activeGameObject.GetComponent<CanvasRenderer>().GetMaterial();
}
Undo.RecordObject(mat, "Reset Material");
ShaderUtilities.GetShaderPropertyIDs(); // Make sure we have valid Property IDs
if (mat.HasProperty(ShaderUtilities.ID_GradientScale))
{
bool isSRPShader = mat.HasProperty(ShaderUtilities.ID_IsoPerimeter);
// Copy unique properties of the SDF Material
var texture = mat.GetTexture(ShaderUtilities.ID_MainTex);
var gradientScale = mat.GetFloat(ShaderUtilities.ID_GradientScale);
float texWidth = 0, texHeight = 0;
float normalWeight = 0, boldWeight = 0;
if (!isSRPShader)
{
texWidth = mat.GetFloat(ShaderUtilities.ID_TextureWidth);
texHeight = mat.GetFloat(ShaderUtilities.ID_TextureHeight);
normalWeight = mat.GetFloat(ShaderUtilities.ID_WeightNormal);
boldWeight = mat.GetFloat(ShaderUtilities.ID_WeightBold);
}
var stencilId = 0.0f;
var stencilComp = 0.0f;
if (mat.HasProperty(ShaderUtilities.ID_StencilID))
{
stencilId = mat.GetFloat(ShaderUtilities.ID_StencilID);
stencilComp = mat.GetFloat(ShaderUtilities.ID_StencilComp);
}
// Reset the material
Unsupported.SmartReset(mat);
// Reset ShaderKeywords
mat.shaderKeywords = new string[0]; // { "BEVEL_OFF", "GLOW_OFF", "UNDERLAY_OFF" };
// Copy unique material properties back to the material.
mat.SetTexture(ShaderUtilities.ID_MainTex, texture);
mat.SetFloat(ShaderUtilities.ID_GradientScale, gradientScale);
if (!isSRPShader)
{
mat.SetFloat(ShaderUtilities.ID_TextureWidth, texWidth);
mat.SetFloat(ShaderUtilities.ID_TextureHeight, texHeight);
mat.SetFloat(ShaderUtilities.ID_WeightNormal, normalWeight);
mat.SetFloat(ShaderUtilities.ID_WeightBold, boldWeight);
}
if (mat.HasProperty(ShaderUtilities.ID_StencilID))
{
mat.SetFloat(ShaderUtilities.ID_StencilID, stencilId);
mat.SetFloat(ShaderUtilities.ID_StencilComp, stencilComp);
}
}
else
{
Unsupported.SmartReset(mat);
}
TMPro_EventManager.ON_MATERIAL_PROPERTY_CHANGED(true, mat);
}
//This function is used for debugging and fixing potentially broken font atlas links.
[MenuItem("CONTEXT/Material/Copy Atlas", false, 2000)]
static void CopyAtlas(MenuCommand command)
{
Material mat = command.context as Material;
m_copiedAtlasProperties = new Material(mat);
m_copiedAtlasProperties.hideFlags = HideFlags.DontSave;
}
// This function is used for debugging and fixing potentially broken font atlas links
[MenuItem("CONTEXT/Material/Paste Atlas", true, 2001)]
static bool PasteAtlasValidate(MenuCommand command)
{
if (m_copiedAtlasProperties == null && m_copiedTexture == null)
return false;
return AssetDatabase.IsOpenForEdit(command.context);
}
[MenuItem("CONTEXT/Material/Paste Atlas", false, 2001)]
static void PasteAtlas(MenuCommand command)
{
Material mat = command.context as Material;
if (mat == null)
return;
if (m_copiedAtlasProperties != null)
{
Undo.RecordObject(mat, "Paste Texture");
ShaderUtilities.GetShaderPropertyIDs(); // Make sure we have valid Property IDs
if (m_copiedAtlasProperties.HasProperty(ShaderUtilities.ID_MainTex))
mat.SetTexture(ShaderUtilities.ID_MainTex, m_copiedAtlasProperties.GetTexture(ShaderUtilities.ID_MainTex));
if (m_copiedAtlasProperties.HasProperty(ShaderUtilities.ID_GradientScale))
{
mat.SetFloat(ShaderUtilities.ID_GradientScale, m_copiedAtlasProperties.GetFloat(ShaderUtilities.ID_GradientScale));
mat.SetFloat(ShaderUtilities.ID_TextureWidth, m_copiedAtlasProperties.GetFloat(ShaderUtilities.ID_TextureWidth));
mat.SetFloat(ShaderUtilities.ID_TextureHeight, m_copiedAtlasProperties.GetFloat(ShaderUtilities.ID_TextureHeight));
}
}
else if (m_copiedTexture != null)
{
Undo.RecordObject(mat, "Paste Texture");
mat.SetTexture(ShaderUtilities.ID_MainTex, m_copiedTexture);
}
}
#endif
// Context Menus for TMPro Font Assets
//This function is used for debugging and fixing potentially broken font atlas links.
[MenuItem("CONTEXT/TMP_FontAsset/Extract Atlas", false, 2200)]
static void ExtractAtlas(MenuCommand command)
{
TMP_FontAsset font = command.context as TMP_FontAsset;
string fontPath = AssetDatabase.GetAssetPath(font);
string texPath = Path.GetDirectoryName(fontPath) + "/" + Path.GetFileNameWithoutExtension(fontPath) + " Atlas.png";
// Create a Serialized Object of the texture to allow us to make it readable.
SerializedObject texprop = new SerializedObject(font.material.GetTexture(ShaderUtilities.ID_MainTex));
texprop.FindProperty("m_IsReadable").boolValue = true;
texprop.ApplyModifiedProperties();
// Create a copy of the texture.
Texture2D tex = Instantiate(font.material.GetTexture(ShaderUtilities.ID_MainTex)) as Texture2D;
// Set the texture to not readable again.
texprop.FindProperty("m_IsReadable").boolValue = false;
texprop.ApplyModifiedProperties();
Debug.Log(texPath);
// Saving File for Debug
var pngData = tex.EncodeToPNG();
File.WriteAllBytes(texPath, pngData);
AssetDatabase.Refresh();
DestroyImmediate(tex);
}
/// <summary>
///
/// </summary>
/// <param name="command"></param>
[MenuItem("CONTEXT/TMP_FontAsset/Update Atlas Texture...", false, 2000)]
static void RegenerateFontAsset(MenuCommand command)
{
TMP_FontAsset fontAsset = command.context as TMP_FontAsset;
if (fontAsset != null)
{
TMPro_FontAssetCreatorWindow.ShowFontAtlasCreatorWindow(fontAsset);
}
}
/*[MenuItem("CONTEXT/TMP_FontAsset/Force Upgrade To Version 1.1.0...", false, 2020)]
static void ForceFontAssetUpgrade(MenuCommand command)
{
TMP_FontAsset fontAsset = command.context as TMP_FontAsset;
if (fontAsset != null)
{
fontAsset.UpgradeFontAsset();
TMPro_EventManager.ON_FONT_PROPERTY_CHANGED(true, fontAsset);
}
}*/
/// <summary>
/// Clear Dynamic Font Asset data such as glyph, character and font features.
/// </summary>
/// <param name="command"></param>
[MenuItem("CONTEXT/TMP_FontAsset/Reset", true, 100)]
static bool ClearFontAssetDataValidate(MenuCommand command)
{
return AssetDatabase.IsOpenForEdit(command.context);
}
[MenuItem("CONTEXT/TMP_FontAsset/Reset", false, 100)]
static void ClearFontAssetData(MenuCommand command)
{
TMP_FontAsset fontAsset = command.context as TMP_FontAsset;
if (fontAsset == null)
return;
if (Selection.activeObject != fontAsset)
Selection.activeObject = fontAsset;
fontAsset.ClearFontAssetData(true);
TMP_ResourceManager.RebuildFontAssetCache();
TMPro_EventManager.ON_FONT_PROPERTY_CHANGED(true, fontAsset);
}
/// <summary>
/// Clear Character and Glyph data (only).
/// </summary>
/// <param name="command"></param>
[MenuItem("CONTEXT/TMP_FontAsset/Clear Dynamic Data", true, 2100)]
static bool ClearFontCharacterDataValidate(MenuCommand command)
{
return AssetDatabase.IsOpenForEdit(command.context);
}
[MenuItem("CONTEXT/TMP_FontAsset/Clear Dynamic Data", false, 2100)]
static void ClearFontCharacterData(MenuCommand command)
{
TMP_FontAsset fontAsset = command.context as TMP_FontAsset;
if (fontAsset == null)
return;
if (Selection.activeObject != fontAsset)
Selection.activeObject = fontAsset;
fontAsset.ClearCharacterAndGlyphTablesInternal();
TMPro_EventManager.ON_FONT_PROPERTY_CHANGED(true, fontAsset);
}
[MenuItem("CONTEXT/TMP_FontAsset/Reset FaceInfo", priority = 101)]
static void ResetFaceInfo(MenuCommand command)
{
TMP_FontAsset fontAsset = command.context as TMP_FontAsset;
if (fontAsset == null)
return;
if (Selection.activeObject != fontAsset)
Selection.activeObject = fontAsset;
if (fontAsset.LoadFontFace() != FontEngineError.Success)
return;
fontAsset.faceInfo = FontEngine.GetFaceInfo();
TextResourceManager.RebuildFontAssetCache();
TextEventManager.ON_FONT_PROPERTY_CHANGED(true, fontAsset);
EditorUtility.SetDirty(fontAsset);
AssetDatabase.SaveAssetIfDirty(fontAsset);
AssetDatabase.Refresh();
}
/// <summary>
/// Import all font features
/// </summary>
/// <param name="command"></param>
#if TEXTCORE_FONT_ENGINE_1_5_OR_NEWER
[MenuItem("CONTEXT/TMP_FontAsset/Import Font Features", true, 2110)]
static bool ReimportFontFeaturesValidate(MenuCommand command)
{
return AssetDatabase.IsOpenForEdit(command.context);
}
[MenuItem("CONTEXT/TMP_FontAsset/Import Font Features", false, 2110)]
static void ReimportFontFeatures(MenuCommand command)
{
TMP_FontAsset fontAsset = command.context as TMP_FontAsset;
if (fontAsset == null)
return;
if (Selection.activeObject != fontAsset)
Selection.activeObject = fontAsset;
fontAsset.ImportFontFeatures();
TMPro_EventManager.ON_FONT_PROPERTY_CHANGED(true, fontAsset);
}
#endif
/// <summary>
///
/// </summary>
/// <param name="command"></param>
[MenuItem("CONTEXT/TrueTypeFontImporter/Create TMP Font Asset...", false, 200)]
static void CreateFontAsset(MenuCommand command)
{
TrueTypeFontImporter importer = command.context as TrueTypeFontImporter;
if (importer != null)
{
Font sourceFontFile = AssetDatabase.LoadAssetAtPath<Font>(importer.assetPath);
if (sourceFontFile)
TMPro_FontAssetCreatorWindow.ShowFontAtlasCreatorWindow(sourceFontFile);
}
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 44e1d646473a40178712cb2150f54cec
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More