TMP在Unity2018中是带有动态字体这个功能的 在Unity2018之前的版本中 都是以package的形式导入的并且不支持动态字体
1.生成一个7000+的静态字体上挂载一个动态字体资产 通常来说7000+够用了 但是异体字生僻字繁体字不全 会导致文本渲染不出的问题
2.自己写个工具把项目中用到的中文收集起来去生成一个静态字体资产然后挂载一个动态字体 这样做的好处是静态字体可控 占用的内存相对较少
3.纯动态字体 使用动态图集的多图集模式
右键选中字体文件
会创建出一个xxx.asset
是一个ScriptableObject 的序列化资产, 根据自己项目的资源管理打包加载
运行时在文本渲染时如果静态字体找不到会把文字动态生成到动态图集中
TMP的代码是通过Resources.Load加载TMPSettings.asset的 如果你不想这么实现 魔改代码根据自己的资源管理加载也可以
嫌麻烦的游戏开始时反射赋值也可以
TMP_Settings tMP_Settings = Assetbundle.LoadAllAssets<TMP_Settings>()[0];
Type type = typeof(TMP_Settings);
FieldInfo fieldInfo = type.GetField("s_Instance", BindingFlags.Static | BindingFlags.NonPublic);
fieldInfo.SetValue(null, tMP_Settings);
如果想删除TextMeshPro.asmdef的可能会用得到
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using UnityEngine.TextCore;
using UnityEngine.TextCore.LowLevel;
namespace TMPro
{
public static class TMP_ReflectionInterface
{
private static Type _type;
private static Dictionary<string, MethodInfo> _methodInfos = new Dictionary<string, MethodInfo>();
private static Type type
{
get
{
if (_type == null)
_type = typeof(FontEngine);
if (_type == null)
Log(1, "type is null.");
return _type;
}
}
private static MethodInfo GetMethod(string name, Type[] parameterTypes = null)
{
Log(2, $"TMP_ReflectionInterface.{name}()");
MethodInfo methodInfo;
if (_methodInfos.TryGetValue(name, out methodInfo))
return methodInfo;
if (parameterTypes != null)
{
Log(2, $"Param Type[] = {parameterTypes.ToString()}");
methodInfo = type.GetMethod(name, BindingFlags.Static | BindingFlags.NonPublic, null, parameterTypes, null);
}
else
{
methodInfo = type.GetMethod(name, BindingFlags.Static | BindingFlags.NonPublic);
}
_methodInfos.Add(name, methodInfo);
return methodInfo;
}
private static void Log(int level, string log)
{
Debug.Log(log);
}
public static GlyphPairAdjustmentRecord[] GetGlyphPairAdjustmentTable(uint[] glyphIndexes)
{
try
{
MethodInfo method = GetMethod("GetGlyphPairAdjustmentTable");
if (method == null)
{
Log(1, "no find GetGlyphPairAdjustmentTable method.");
return null;
}
GlyphPairAdjustmentRecord[] result = (GlyphPairAdjustmentRecord[])method.Invoke(null, new object[] { glyphIndexes });
if (result == null)
return null;
return result;
}
catch (Exception ex)
{
Log(1, "GetGlyphPairAdjustmentTable Exception: " + ex.Message);
return null;
}
}
public static GlyphPairAdjustmentRecord[] GetGlyphPairAdjustmentRecords(List<uint> glyphIndexes, out int recordCount)
{
try
{
Type[] types = new Type[] { typeof(List<uint>), typeof(int).MakeByRefType() };
MethodInfo method = GetMethod("GetGlyphPairAdjustmentRecords", types);
if (method == null)
{
recordCount = 0;
Log(1, "no find GetGlyphPairAdjustmentRecords method.");
return null;
}
object[] methodParameters = { glyphIndexes, 0 };
GlyphPairAdjustmentRecord[] result = (GlyphPairAdjustmentRecord[])method.Invoke(null, methodParameters);
if (result == null)
{
recordCount = 0;
return null;
}
recordCount = (int)methodParameters[1];
return result;
}
catch (Exception e)
{
Log(1, "GetGlyphPairAdjustmentRecords Error: " + e.Message);
}
recordCount = 0;
return null;
}
public static bool TryAddGlyphToTexture(uint glyphIndex, int padding, GlyphPackingMode packingMode, List<GlyphRect> freeGlyphRects, List<GlyphRect> usedGlyphRects, GlyphRenderMode renderMode, Texture2D texture, out Glyph glyph)
{
try
{
MethodInfo method = GetMethod("TryAddGlyphToTexture");
if (method == null)
{
glyph = null;
Log(1, "no find TryAddGlyphToTexture method.");
return false;
}
object[] methodParameters = { glyphIndex, padding, packingMode, freeGlyphRects, usedGlyphRects, renderMode, texture, null };
bool result = (bool)method.Invoke(null, methodParameters);
if (!result)
{
Log(1, "TryAddGlyphToTexture failed.");
glyph = null;
return false;
}
glyph = (Glyph)methodParameters[7];
if (glyph == null)
{
Log(1, "Glyph object is null.");
return false;
}
return result;
}
catch(Exception e)
{
Log(1, "TryAddGlyphToTexture Error: " + e.Message);
}
glyph = null;
return false;
}
public static bool TryAddGlyphsToTexture(List<uint> glyphIndexes, int padding, GlyphPackingMode packingMode, List<GlyphRect> freeGlyphRects, List<GlyphRect> usedGlyphRects, GlyphRenderMode renderMode, Texture2D texture, out Glyph[] glyphs)
{
try
{
Type[] parameterTypes = new Type[] { typeof(List<uint>), typeof(int), typeof(GlyphPackingMode), typeof(List<GlyphRect>), typeof(List<GlyphRect>), typeof(GlyphRenderMode), typeof(Texture2D), typeof(Glyph[]).MakeByRefType() };
MethodInfo method = GetMethod("TryAddGlyphsToTexture", parameterTypes);
if (method == null)
{
glyphs = null;
Log(1, "no find TryAddGlyphsToTexture method.");
return false;
}
object[] methodParameters = { glyphIndexes, padding, packingMode, freeGlyphRects, usedGlyphRects, renderMode, texture, null };
bool result = (bool)method.Invoke(null, methodParameters);
if (!result)
{
Log(1, "TryAddGlyphsToTexture failed.");
glyphs = null;
return false;
}
glyphs = (Glyph[])methodParameters[7];
if (glyphs == null)
{
Log(1, "Glyphs array is null.");
return false;
}
return result;
}
catch (Exception e)
{
Log(1, "TryAddGlyphsToTexture Error: " + e.Message);
}
glyphs = null;
return false;
}
public static uint GetGlyphIndex(uint unicode)
{
try
{
MethodInfo method = GetMethod("GetGlyphIndex");
if (method == null)
{
Log(1, "no find GetGlyphIndex method.");
return 0;
}
object[] methodParameters = { unicode };
object result = method.Invoke(null, methodParameters);
uint glyphIndex = (uint)result;
return glyphIndex;
}
catch (Exception e)
{
Log(1, "GetGlyphIndex Error: " + e.Message);
}
return 0;
}
public static Texture2D ResetAtlasTexture(Texture2D texture2D)
{
try
{
MethodInfo method = GetMethod("ResetAtlasTexture");
if (method == null)
{
Log(1, "no find GetGlyphIndex method.");
return null;
}
object[] methodParameters = { texture2D };
object result = method.Invoke(null, methodParameters);
Texture2D t2d = (Texture2D)result;
return t2d;
}
catch (Exception e)
{
Log(1, "ResetAtlasTexture Error: " + e.Message);
}
return null;
}
}
}