0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Unity】TextMeshPro の Material Preset に表示されるマテリアルの条件

Posted at

概要

TextMeshPro - Text (UI)Material Preset には Font Asset に選択したフォントアセットと紐づけられているマテリアルを選択できます.ここに表示されるマテリアルの条件がわからなかったので調べました.

image.png

ソースコードの該当部分

調べても該当する記事や QA が見つからなかったので,ソースコードを調べました.
TextMeshPro のソースコードは下記のリンクから確認できます.ただし,Unity 公式ではないようです.

Preset Material の表示に関わるのは TMP_BaseEditorPanel.csGetMaterialPresets() です.

TMP_BaseEditorPanel.cs
/// <summary>
/// Method to retrieve the material presets that match the currently selected font asset.
/// </summary>
protected GUIContent[] GetMaterialPresets()
{
    FontAsset fontAsset = m_FontAssetProp.objectReferenceValue as FontAsset;
    if (fontAsset == null) return null;

    m_MaterialPresets = TMP_EditorUtility.FindMaterialReferences(fontAsset);
    m_MaterialPresetNames = new GUIContent[m_MaterialPresets.Length];

    m_MaterialPresetIndexLookup.Clear();

    for (int i = 0; i < m_MaterialPresetNames.Length; i++)
    {
        m_MaterialPresetNames[i] = new GUIContent(m_MaterialPresets[i].name);

        m_MaterialPresetIndexLookup.Add(m_MaterialPresets[i].GetInstanceID(), i);

        //if (m_TargetMaterial.GetInstanceID() == m_MaterialPresets[i].GetInstanceID())
        //    m_MaterialPresetSelectionIndex = i;
    }

    m_IsPresetListDirty = false;

    return m_MaterialPresetNames;
}

どうやら,TMP_EditorUtility.FindMaterialReferences(fontAsset) で Material Preset を取得しているようです.FindMaterialReferences()TMP_EditorUtility.cs で定義されています.

TMP_EditorUtility.cs
// Function used to find all materials which reference a font atlas so we can update all their references.
internal static Material[] FindMaterialReferences(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();
}

つまり,フォントアセットの material プロパティにセットされているマテリアル,または,プロジェクト内のマテリアルのうち,名前にフォントアセットの名前が含まれており,マテリアルの MainTex がフォントアセットのアトラステクスチャと一致するものが Material Preset に表示されます.
ちなみに,サブアセットは AssetDatabase.FindAssets() では取得できないので表示されません.(筆者はこれに嵌りました.)

▼フォントアセットの material プロパティ
image.png

Material Preset に表示される条件

Material Preset に表示されるマテリアルは下記のいずれかになります.

  • フォントアセット自身の material プロパティにセットされているマテリアル
  • プロジェクト内のマテリアルのうち,次の条件を満たすもの
    • 名前にフォントアセットの名前を含んでいる
    • MainTex にフォントアセットのアトラステクスチャがセットされている
    • 単独のマテリアルアセットである(= サブアセットでない)

雑記

サブアセットにも対応してほしい人生だった...
でも TextMeshPro 関係のアセットはスクリプトから生成することをあまり想定していないようなので仕方ない感じがします.エディタ上で普通にマテリアルを複製したら普通に Material Preset に表示されるので,サブアセットだと表示されないことに気付く人がそもそもいないでしょうね...
まあその分調べても全く情報が出てこないので,この知見がいつか誰かの役に立てば幸いです.

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?