Battlehub0x / RTE_Docs

This is a repository for Runtime Editor documentation, discussion and tracking features and issues.
https://assetstore.unity.com/packages/tools/modeling/runtime-editor-64806
9 stars 0 forks source link

How to import font at runtime #84

Closed Battlehub0x closed 12 months ago

Battlehub0x commented 12 months ago

I need to use import from file button instead of import asset, cause im making so player can add any font asset into the project. can you explain further about this, 1 minute video like this link would be really apreciated. fontImport.txt

Battlehub0x commented 12 months ago

Related issue https://github.com/Battlehub0x/RTE_Docs/issues/82

Battlehub0x commented 12 months ago

The following approach is a HACK, but it seems to work fine.

Watch this video at twelfth second but use the following custom PersistentTMP_FontAsset implementation instead

#if !RTSL_MAINTENANCE
using Battlehub.RTSL;
using ProtoBuf;
using System;
using System.IO;
using UnityEngine;

namespace TMPro.Battlehub.SL2
{
    [CustomImplementation]
    public partial class PersistentTMP_FontAsset<TID>
    {
        [ProtoMember(1)]
        public byte[] m_fontData;

        public override void ReadFrom(object obj)
        {
            var uo = obj as UnityEngine.Object;
            if (uo != null && !m_assetDB.IsStaticResourceID(ToID(uo)))
            {
                TMP_FontAsset fontAsset = uo as TMP_FontAsset;
                if (fontAsset != null && fontAsset.sourceFontFile != null && File.Exists(fontAsset.sourceFontFile.name))
                {
                    m_fontData = File.ReadAllBytes(fontAsset.sourceFontFile.name);
                }
                else
                {
                    base.ReadFrom(obj);
                }
            }
        }

        public override object WriteTo(object obj)
        {
            var uo = obj as UnityEngine.Object;
            if (uo != null && !m_assetDB.IsStaticResourceID(ToID(uo)))
            {
                if (m_fontData == null)
                {
                    return base.WriteTo(obj);
                }
            }

            return obj;
        }

        public override void GetDeps(GetDepsContext<TID> context)
        {
            if (m_fontData == null)
            {
                base.GetDeps(context);
            }
        }

        public override void GetDepsFrom(object obj, GetDepsFromContext context)
        {
            var uo = obj as UnityEngine.Object;
            if (uo != null && !m_assetDB.IsStaticResourceID(ToID(uo)))
            {
                if (m_fontData == null)
                {
                    base.GetDepsFrom(obj, context);
                }
            }
        }

        public override bool CanInstantiate(Type type)
        {
            return true;
        }

        public override object Instantiate(Type type)
        {
            if (m_fontData == null)
            {
                return base.Instantiate(type);
            }

            string fileName = Path.GetTempFileName();
            File.WriteAllBytes(fileName, m_fontData);

            Font customFont = new Font(fileName);
            customFont.name = fileName;

            customFont.material = new Material(Shader.Find("UI/Default"));
            customFont.material.mainTexture = new Texture2D(2, 2);
            customFont.material.mainTexture.filterMode = FilterMode.Point;
            customFont.hideFlags = HideFlags.HideAndDontSave;
            customFont.RequestCharactersInTexture("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-=_+[]{}|;':\",./<>?\\");

            TMP_FontAsset fontAsset = TMP_FontAsset.CreateFontAsset(customFont);
            File.Delete(fileName);

            return fontAsset;
        }
    }
}
#endif

Also change the FontImporter сode:

 private IEnumerator LoadFont(string path, string targetPath, IProjectAsync project, TaskCompletionSource<Font> tcs)
    {

        UnityWebRequest request = UnityWebRequest.Get(path);
        yield return request.SendWebRequest();

        if (request.result == UnityWebRequest.Result.ConnectionError)
        {
            tcs.SetException(new UnityWebRequestException(request.error));
        }
        else
        {
            Font customFont = new Font(path);
            customFont.name = path; // <----------

            customFont.material = new Material(Shader.Find("UI/Default"));
            customFont.material.mainTexture = new Texture2D(2, 2);
            customFont.material.mainTexture.filterMode = FilterMode.Point;
            customFont.hideFlags = HideFlags.HideAndDontSave;
            customFont.RequestCharactersInTexture("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-=_+[]{}|;':\",./<>?\\");

            TMP_FontAsset font_asset = TMP_FontAsset.CreateFontAsset(customFont);
            yield return Wait(project.SaveAsync(targetPath, font_asset));  // <----------

            tcs.SetResult(customFont);
        }
    }

    private IEnumerable Wait(Task task)
    {
        while (!task.IsCompleted)
        {
            yield return null;
        }
    }