在TextMeshPro出现之前,Unity是不支持emoji的,所以导出的包是把emoji过滤掉的,在导出工程的Keyboard.mm中。但是emoji却是大多游戏的刚需,所以很多游戏自己实现了文本组件支持emoji。但这还不够,要把Unity在原生层对emoji的过滤去掉。

#ifndef FILTER_EMOJIS_IOS_KEYBOARD
#define FILTER_EMOJIS_IOS_KEYBOARD 1
#endif

2017版本中,在导出工程流程中,添加预定义宏就行。

static void OnPostprocessBuild(BuildTarget target, string pathToBuildProject){
    string projPath = PBXProject.GetPBXProjectPath(pathToBuildProject);
    PBXProject pbxProj = new PBXProject ();
    pbxProj.ReadFromString (File.ReadAllText (projPath));
    string target = pbxProj.TargetGuidByName ("Unity-iPhone");
    if (!string.IsNullOrEmpty (target)) {
        pbxProj.SetBuildProperty (target, "GCC_PREPROCESSOR_DEFINITIONS", "FILTER_EMOJIS_IOS_KEYBOARD=0");//关闭ios emoji过滤

但在2020版本中,这个设置却没用了。于是想到TMP应该也要处理一样的问题,于是找到Unity TMP的源码,抄了一波。其实就是导出工程以后,直接覆写Keyboard.mm过滤emoji的宏。源码在项目根目录\Library\PackageCache\com.unity.textmeshpro@3.0.6\Scripts\Editor\TMP_PostBuildProcessHandler.cs

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)
                    return;
                string 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);