当前位置: 首页 > news >正文

一键替换工程文件和场景中的UI对象字体

具体流程:

  1. 找到工程中使用到的所有字体
  2. 找到工程和场景中包含Text的所有对象
  3. 展示要替换的字体名字让用户选择
  4. 通过用户选择的字体,展示响应的物体对象
  5. 一键替换

通过AssetDatabase.FindAssets找到工程中包含的所有字体:

 private List<string> FindAllFonts(){List<string> list = new List<string>();// 获取所有字体文件string[] fontGUIDs = AssetDatabase.FindAssets("t:Font");foreach (string fontGUID in fontGUIDs){string fontPath = AssetDatabase.GUIDToAssetPath(fontGUID);Font font = AssetDatabase.LoadAssetAtPath<Font>(fontPath);list.Add(font.name);}list.Add("Arial");//默认字体添加进去return list;}

 通过AssetDatabase.FindAssets找到工程中的所有预制体

  private List<GameObject> GetAllPrefabByAssetDatabase(params string[] path){List<GameObject> _prefabList = new List<GameObject>();string[] _guids = AssetDatabase.FindAssets("t:Prefab", path);string _prefabPath = "";GameObject _prefab;foreach (var _guid in _guids){_prefabPath = AssetDatabase.GUIDToAssetPath(_guid);_prefab = AssetDatabase.LoadAssetAtPath(_prefabPath, typeof(GameObject)) as GameObject;_prefabList.Add(_prefab);}
#if UNITY_2020_1_OR_NEWERText[] texts = GameObject.FindObjectsOfType<Text>(true);foreach (var text in texts){_prefabList.Add(text.gameObject);}
#elseScene activeScene = EditorSceneManager.GetActiveScene();GameObject[] allObjectsInScene = activeScene.GetRootGameObjects();foreach (var obj in allObjectsInScene){Text[] texts = obj.GetComponentsInChildren<Text>(true);foreach (var text in texts){_prefabList.Add(text.gameObject);}}
#endifreturn _prefabList;}

过滤没有含Text组件的对象

 private List<GameObject> FilterNoTextPrefabs(){List<GameObject> templist = new List<GameObject>();Dic_Font_Prefabs.Clear();foreach (var prefab in prefabs){Text[] texts = prefab.GetComponentsInChildren<Text>(true);if (texts.Length != 0){foreach (var text in texts){if (text.font != null){if (!Dic_Font_Prefabs.ContainsKey(text.font.name)){Dic_Font_Prefabs.Add(text.font.name, new List<GameObject>());//根据Font类型,添加一个Text集合到字典中}if (!Dic_Font_Prefabs[text.font.name].Contains(prefab)){Dic_Font_Prefabs[text.font.name].Add(prefab);}if (!templist.Contains(prefab)){templist.Add(prefab);//包含该Text的预制体添加到集合中}}}}}return templist;}

最后,用户选择完要替换的字体,选择开始替换即可。

TextMeshPro跟Text是一个道理,只需要把代码中响应的Text和Font改为TextMeshProGUI和FontAssets即可。

最后附上完整代码:

using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine.UI;
using System.Linq;
using UnityEditor.SceneManagement;
using UnityEngine.SceneManagement;
/// <summary>
/// 查找替换工程场景中Text的Font
/// </summary>
public class ChangePrefabFont : EditorWindow
{[MenuItem("Tools/替换字体/Text")]//入口static void GetWindow()//静态函数{//创建窗口ChangePrefabFont window = EditorWindow.GetWindow<ChangePrefabFont>("Text字体替换窗口");//生成一个unity窗口弹窗window.Show();//展示OnGUI中的界面显示}#region 属性/// <summary>/// 工程中包含的字体的名字/// </summary>List<string> fontsOnAssets = new List<string>();/// <summary>/// 对应字体是否需要替换/// </summary>List<bool> textPaidFontRelpace = new List<bool>();/// <summary>/// 代替要替换的字体的字体/// </summary>List<Font> textReplaceFonts = new List<Font>();/// <summary>/// 预制体集合/// </summary>List<GameObject> prefabs = new List<GameObject>();/// <summary>/// 根据字体类型分类的预制体对象/// </summary>Dictionary<string, List<GameObject>> Dic_Font_Prefabs = new Dictionary<string, List<GameObject>>();#endregionprivate void OnEnable(){InitFont();}private void OnGUI(){InitPrefabs();#region 显示替换选项EditorGUILayout.LabelField("下面是工程中包含的字体,和工程中&场景中的对象使用的字体情况。请选择要替换的字体:");for (int i = 0; i < fontsOnAssets.Count; i++){EditorGUILayout.BeginHorizontal();EditorGUILayout.LabelField($"更换[{fontsOnAssets[i]}]字体");textPaidFontRelpace[i] = EditorGUILayout.Toggle(textPaidFontRelpace[i], GUILayout.Width(position.width));//是否要替换当前字体的复选框EditorGUILayout.EndHorizontal();EditorGUILayout.BeginHorizontal();EditorGUILayout.LabelField($"    预制体数量:{GetGetUseFontPrefabCount(fontsOnAssets[i])}");if (!textPaidFontRelpace[i]){if (Dic_Font_Prefabs.ContainsKey(fontsOnAssets[i])){foreach (var item in Dic_Font_Prefabs[fontsOnAssets[i]]){if (prefabs.Contains(item)){prefabs.Remove(item);}}}}else{EditorGUILayout.LabelField($"代替【{fontsOnAssets[i]}】的字体:");textReplaceFonts[i] = (Font)EditorGUILayout.ObjectField(textReplaceFonts[i], typeof(Font), true);//代替的字体复选框if (Dic_Font_Prefabs.ContainsKey(fontsOnAssets[i])){foreach (var item in Dic_Font_Prefabs[fontsOnAssets[i]]){if (!prefabs.Contains(item)){prefabs.Add(item);}}}}EditorGUILayout.EndHorizontal();}EditorGUILayout.Space();#endregion#region 开始替换操作if (GUILayout.Button("开始替换")){if (textReplaceFonts == null || textReplaceFonts.Count == 0){EditorUtility.DisplayDialog("提示", "没有字体!", "确定");return;}if (prefabs == null || prefabs.Count == 0){EditorUtility.DisplayDialog("提示", "没有需要替换的对象!", "确定");return;}List<GameObject> ReplaceGo = new List<GameObject>();Dictionary<string, Font> Dic_Font_ReplaceFont = new Dictionary<string, Font>();for (int i = 0; i < textPaidFontRelpace.Count; i++){if (textPaidFontRelpace[i] == true){if (textReplaceFonts[i] != null){if (Dic_Font_Prefabs.ContainsKey(fontsOnAssets[i])){ReplaceGo.AddRange(Dic_Font_Prefabs[fontsOnAssets[i]]);Dic_Font_ReplaceFont.Add(fontsOnAssets[i], textReplaceFonts[i]);}else{EditorUtility.DisplayDialog("提示", $"使用了【{fontsOnAssets[i]}】字体的预制体数量为0!", "确定");}}else{EditorUtility.DisplayDialog("提示", $"【{fontsOnAssets[i]}】的替代字体为空!", "确定");}}}if (ReplaceGo.Count == 0){EditorUtility.DisplayDialog("提示", "没有需要替换的对象!", "确定");}else{string hintInfo = "";foreach (var font in Dic_Font_ReplaceFont){hintInfo += $"{font.Key} >> {font.Value.name}\n";}if (EditorUtility.DisplayDialog("确认进行下面的替换?", hintInfo, "确定", "取消")){foreach (var font in Dic_Font_ReplaceFont){ReplaceFont(Dic_Font_Prefabs[font.Key], font.Key, font.Value);}SaveChangedToAsset(prefabs);}}}#endregion#region 预制体列表InitReorderableList();if (reorderableList != null && reorderableList.count != 0){scrollPos = EditorGUILayout.BeginScrollView(scrollPos);reorderableList.DoLayoutList();EditorGUILayout.EndScrollView();}else{EditorGUILayout.LabelField("提示:没有需要替换字体的预制体");}#endregion}#region 列表和滚动窗口ReorderableList reorderableList;//列表显示Vector2 scrollPos;//滚动窗口需要private void DrawHeader(Rect rect){EditorGUI.LabelField(rect, "对象列表数量:" + prefabs.Count);}private void DrawElement(Rect rect, int index, bool isActive, bool isFocused){rect.height -= 4;rect.y += 2;prefabs[index] = (GameObject)EditorGUI.ObjectField(rect, "包含Text的对象", prefabs[index], typeof(GameObject), true);}private void AddItem(ReorderableList list){prefabs.Add(null);}#endregion#region 逻辑方法/// <summary>/// 字体相关初始化/// </summary>private void InitFont(){textPaidFontRelpace.Clear();textReplaceFonts.Clear();fontsOnAssets = FindAllFonts();foreach (var item in fontsOnAssets){textPaidFontRelpace.Add(false);textReplaceFonts.Add(null);}}/// <summary>/// 预制体相关初始化/// </summary>private void InitPrefabs(){prefabs = GetAllPrefabByAssetDatabase();prefabs = FilterNoTextPrefabs();prefabs.Clear();foreach (var item in Dic_Font_Prefabs){prefabs.AddRange(item.Value);}}/// <summary>/// 初始化链表操作对象/// </summary>private void InitReorderableList(){prefabs = prefabs.Distinct().ToList();reorderableList = new ReorderableList(prefabs, typeof(GameObject), true, true, true, true);reorderableList.drawHeaderCallback = DrawHeader;reorderableList.drawElementCallback = DrawElement;reorderableList.onAddCallback = AddItem;}#endregion#region 功能方法#region 查找和过滤/// <summary>/// 找到工程和场景中的含有Text组件的对象/// </summary>/// <param name="path"></param>/// <returns></returns>private List<GameObject> GetAllPrefabByAssetDatabase(params string[] path){List<GameObject> _prefabList = new List<GameObject>();string[] _guids = AssetDatabase.FindAssets("t:Prefab", path);string _prefabPath = "";GameObject _prefab;foreach (var _guid in _guids){_prefabPath = AssetDatabase.GUIDToAssetPath(_guid);_prefab = AssetDatabase.LoadAssetAtPath(_prefabPath, typeof(GameObject)) as GameObject;_prefabList.Add(_prefab);}
#if UNITY_2020_1_OR_NEWERText[] texts = GameObject.FindObjectsOfType<Text>(true);foreach (var text in texts){_prefabList.Add(text.gameObject);}
#elseScene activeScene = EditorSceneManager.GetActiveScene();GameObject[] allObjectsInScene = activeScene.GetRootGameObjects();foreach (var obj in allObjectsInScene){Text[] texts = obj.GetComponentsInChildren<Text>(true);foreach (var text in texts){_prefabList.Add(text.gameObject);}}
#endifreturn _prefabList;}/// <summary>/// 过滤没有包含Text的预制体/// 过滤没有包含付费字体的预制体/// 根据Text类型分类/// </summary>/// <param name="gameObjects"></param>/// <returns></returns>private List<GameObject> FilterNoTextPrefabs(){List<GameObject> templist = new List<GameObject>();Dic_Font_Prefabs.Clear();foreach (var prefab in prefabs){Text[] texts = prefab.GetComponentsInChildren<Text>(true);if (texts.Length != 0){foreach (var text in texts){if (text.font != null){if (!Dic_Font_Prefabs.ContainsKey(text.font.name)){Dic_Font_Prefabs.Add(text.font.name, new List<GameObject>());//根据Font类型,添加一个Text集合到字典中}if (!Dic_Font_Prefabs[text.font.name].Contains(prefab)){Dic_Font_Prefabs[text.font.name].Add(prefab);}if (!templist.Contains(prefab)){templist.Add(prefab);//包含该Text的预制体添加到集合中}}}}}return templist;}/// <summary>/// 找到工程中的所有字体文件/// </summary>/// <returns>返回字体名称列表</returns>private List<string> FindAllFonts(){List<string> list = new List<string>();// 获取所有字体文件string[] fontGUIDs = AssetDatabase.FindAssets("t:Font");foreach (string fontGUID in fontGUIDs){string fontPath = AssetDatabase.GUIDToAssetPath(fontGUID);Font font = AssetDatabase.LoadAssetAtPath<Font>(fontPath);list.Add(font.name);}list.Add("Arial");//默认字体添加进去return list;}#endregion#region 替换字体方法/// <summary>/// 替换Text的字体/// </summary>/// <param name="texts">要替换的Text集合</param>/// <param name="fontName">要替换的字体的名字</param>/// <param name="font">用来替换的字体</param>private void ReplaceFont(List<GameObject> gameObjects, string fontName, Font font){foreach (var go in gameObjects){Text[] texts = go.GetComponentsInChildren<Text>(true);foreach (var text in texts){if (text.font != null){if (text.font.name == fontName){text.font = font;}}//else//{//    text.font = Resources.GetBuiltinResource<Font>("Arial.ttf");//}}}}/// <summary>/// 保存更改/// </summary>/// <param name="gameObjects"></param>private void SaveChangedToAsset(List<GameObject> gameObjects){foreach (var gameObject in gameObjects){EditorUtility.SetDirty(gameObject);}AssetDatabase.SaveAssets();AssetDatabase.Refresh();EditorUtility.DisplayDialog("提示", "替换完毕!", "确定");}#endregionprivate List<GameObject> GetUseFontPrefabs(string font){if (Dic_Font_Prefabs.ContainsKey(font))return Dic_Font_Prefabs[font];elsereturn null;}private int GetGetUseFontPrefabCount(string font){List<GameObject> temp = GetUseFontPrefabs(font);return temp == null ? 0 : temp.Count;}#endregion
}

相关文章:

一键替换工程文件和场景中的UI对象字体

具体流程&#xff1a; 找到工程中使用到的所有字体找到工程和场景中包含Text的所有对象展示要替换的字体名字让用户选择通过用户选择的字体&#xff0c;展示响应的物体对象一键替换 通过AssetDatabase.FindAssets找到工程中包含的所有字体&#xff1a; private List<strin…...

微信小程序编辑器代码格式缩进设置

第一步点击这个编辑器设置&#xff1a; 然后设置tab为空格&#xff0c;并且设置占几个空格&#xff0c;这里是4个空格。 这样就好了&#xff0c;文件保存就会自动设置好缩进格式了。...

Android Aidl跨进程通讯(二)--异常捕获处理

学更好的别人&#xff0c; 做更好的自己。 ——《微卡智享》 本文长度为1623字&#xff0c;预计阅读5分钟 前言 上一篇《Android Aidl跨进程通讯的简单使用》中介绍了跨进程的通讯处理&#xff0c;在进程间的数据通过Aidl实现了交互&#xff0c;项目中经常会遇到Bug&#xff0c…...

Android中OkHttp源码阅读二(责任链模式)

博主前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住也分享一下给大家 &#x1f449;点击跳转到教程 Android OkHttp源码阅读详解一 看OkHttp源码&#xff0c;发现OkHttp里面使用了责任链设计模式&#xff0c;所以才要学习…...

2023年03月 C/C++(六级)真题解析#中国电子学会#全国青少年软件编程等级考试

C/C++编程(1~8级)全部真题・点这里 第1题:波兰表达式 波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2 + 3的波兰表示法为+ 2 3。波兰表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2 + 3) * 4的波兰表示法为* + 2 3 4。本题求解…...

顺序表链表OJ题(1)——【LeetCode】

W...Y的主页 &#x1f60a; 代码仓库分享 &#x1f495; 前言&#xff1a; 今天我们来回顾一下顺序表与链表&#xff0c;针对这一块我们也有许多OJ题目供大家参考。当我们学习完顺序表链表后避免不了一些习题的练习&#xff0c;这样才能巩固我们学习的内容。 话不多说&#xf…...

flex:1

问题1&#xff1a;“flex: 1” 与其他 “flex” 值有何区别&#xff1f; 答案&#xff1a; “flex: 1” 是 “flex” 属性的一种简写形式&#xff0c;它将 “flex-grow”、“flex-shrink” 和 “flex-basis” 设置为特定的值。与其他 “flex” 值相比&#xff0c;“flex: 1” …...

iOS练手项目知识点汇总

基础理解篇 Objective-C是一种面向对象的编程语言&#xff0c;它支持元编程。元编程是指编写程序来生成或操纵其他程序的技术。 Objective-C中&#xff0c;元编程可以使用Objective-C的动态特性来实现。例如可以使用Objective-C的运行时函数来动态地创建类、添加属性和方法等等…...

【Linux】Libevent相关小知识总结

Libevent是基于事件的&#xff0c;也就是说&#xff0c;相当于去注册一个事件&#xff0c;当这个事件发生的话&#xff0c;那么就会调用回调函数。...

【Spring Security】UserDetailsService 接口介绍

文章目录 UserDetailsService 介绍UserDetailsService 具体操作UserDetailsService 方法介绍 UserDetailsService 介绍 UserDetailsService 在 Spring Security 中主要承担查询系统内用户、验证密码、封装用户信息和角色权限。大白话就是你写一个实现类实现 UserDetailsServic…...

Mybatis学习|日志工厂、分页

1.日志工厂 如果一个数据库操作&#xff0c;出现了异常&#xff0c;我们需要排错。日志就是最好的助手! 曾经: sout、debug 现在:日志工厂! 我们主要掌握STDOUT_LOGGING 和LOG4j 在Mybatis中具体使用哪个一日志实现&#xff0c;在设置中设定! 在mybatis核心配置文件中&#…...

Vivado 添加FPGA开发板的Boards file的添加

1 digilent board file 下载地址 下载地址 &#xff1a; https://github.com/Digilent/vivado-boards 2 下载后 3 添加文件到 vivado 安装路径 把文件复制到 Vivado\2019.1\data\boards\board_files4 创建工程查看是否安装成功...

vmstat

vmstat VirtualMeomoryStatistics&#xff0c;虚拟内存统计&#xff0c;是Linux中监控内存的常用工具&#xff0c;可对操作系统的虚拟内存、进程、CPU等的整体情况进行监视。 [rootwenzi wenzi]# vmstat procs -----------memory---------- ---swap-- -----io---- -system--…...

LinuxShell变量

变量&#xff1a; 命名规则&#xff1a; 在Shell中&#xff0c;变量名可以由字母、数字或者下划线组成&#xff0c;并且只能以字母或者下划线开头。对于变量名的长度&#xff0c;Shell并没有做出明确的规定。因此&#xff0c;用户可以使用任意长度的字符串来作为变量名。但是…...

如何实现的手机实景自动直播,都有哪些功能呢?

手机实景自动直播最近真的太火了&#xff0c;全程只需要一部手机&#xff0c;就能完成24小时直播带货&#xff0c;不需要真人出镜&#xff0c;不需要场地&#xff0c;不需要搭建直播间&#xff0c;只需要一部手机就可以了。真人语音讲解&#xff0c;真人智能回复&#xff0c;实…...

如何让qt tableView每个item中个别字用不同颜色显示?

如何让qt tableView每个item中个别字用不同颜色显示&#xff1f; 从上面图片可以看到&#xff0c;Item为红色&#xff0c;数字5为黑色。 要实现在一个控件实现不同颜色&#xff0c;目前想到的只有QTextEdit 、QLabel。有两种方法&#xff0c;第一种是代理&#xff0c;第二种是…...

Aspose导出word使用记录

背景&#xff1a;Aspose系列的控件&#xff0c;功能实现都比较强大&#xff0c;可以实现多样化的报表设计及输出。 通过这次业务机会&#xff0c;锂宝碳审核中业务功需要实现Word文档表格的动态导出功能&#xff0c;因此学习了相关内容&#xff0c;在学习和参考了官方API文档的…...

[Java]_[初级]_[使用SAX流的方式写入XML文件]

场景 文件的写入目前没有发现可以增量写入的&#xff0c;只能是完全重新写入。对于大量数据需要写入XML文件&#xff0c;还是和读XML文件一样&#xff0c;不需要生成DOM模型能节省不少的内存和指令。 说明 在java标准库里&#xff0c;也是有相关的SAX类来写入数据流&#xf…...

java里面封装https请求工具类

1.工具类如下 Component Slf4j public class RestClientUtil<T> {private final RestTemplate restTemplate;public RestClientUtil() {this.restTemplate new RestTemplate();}public JSONObject uploadFile(String url, String fileUrl) throws IOException {List<…...

uniApp常见面试题-附详细答案

uniApp中如何进行页面跳转&#xff1f; 答案&#xff1a;可以使用uni.navigateTo、uni.redirectTo和uni.reLaunch等方法进行页面跳转。其中&#xff0c;uni.navigateTo可以实现页面的普通跳转&#xff0c;uni.redirectTo可以实现页面的重定向跳转&#xff0c;uni.reLaunch可以实…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

Redis:现代应用开发的高效内存数据存储利器

一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发&#xff0c;其初衷是为了满足他自己的一个项目需求&#xff0c;即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源&#xff0c;Redis凭借其简单易用、…...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下&#xff1a; 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载&#xff0c;下载地址&#xff1a;https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...