获取unity中prefab的中文文本内容以及和prefab有关的问题

news/2024/12/21 19:49:25/

背景1:经常会在开发中遇到策划需要改某个界面,但是我们不知道那是什么界面,只看到一些关键字比如圣诞活动,那这样我就可以轻易找到这个预设了。另外还可以扩展就是收集项目中的所有中文文本然后归集到多语言表中,然后接入百度翻译api完成自动翻译。

背景2:经常需要批处理预设却发现好多missing脚本的情况导致无法保存预设。

背景3:每次自己构建的text或者image组件总是会带一个rayCasttarget= true的属性,如果不影响事件应该处理为false。我希望在双击进入预设和退出预设的时候对预设自动处理一些属性并保存。

背景1代码如下:我写了2个接口一个是获取\uxxxx的文本内容 一个是获取Text组件上文本内容,大家可以根据需要选用接口。我不打算用unity的api来做主要是想做一个外部工具,用unity的工具有它的局限性。

 /// <summary>
    /// 获取text组件上的文本
    /// </summary>
    /// <param name="prefabPath"></param>
    /// <returns></returns>
    static string GetTextsTextFormPrefab(string prefabPath)
 {
     string prefabContent = File.ReadAllText(prefabPath);
     var listContent = Regex.Matches(prefabContent, @"m_Text:\s*""(\\u([0-9A-Fa-f]{4}))+""");
     string chinsesPattern = @"(\\u[0-9a-fA-F]{4})+";
     StringBuilder sb = new StringBuilder();

     foreach (Match collect in listContent)
     {
         var subCollect = Regex.Matches(collect.Value, chinsesPattern);
         foreach (Match sub in subCollect)
         {
             string pattern = @"\\u([0-9a-fA-F]{4})";

             sb.Append(Regex.Replace(sub.Value, pattern, match =>
             {
                 // 将匹配到的 Unicode 转义序列转换为对应的 Unicode 字符
                 string unicodeValue = match.Groups[1].Value;
                 int codePoint = Convert.ToInt32(unicodeValue, 16);
                 return char.ConvertFromUtf32(codePoint);
             }));
         }

     }
     return sb.ToString();
 }

 /// <summary>
 /// 获取预设上的文本内容
 /// </summary>
 /// <param name="prefabPath"></param>
 /// <returns></returns>
 static string GetTextFromPrefab(string prefabPath)
 {
     string prefabContent = File.ReadAllText(prefabPath);

     Regex regex = new Regex(@"(\\u([0-9A-Fa-f]{4}))+", RegexOptions.Multiline);

     var listContent = regex.Matches(prefabContent);
     string chinsesPattern = @"(\\u[0-9a-fA-F]{4})+";
     StringBuilder sb = new StringBuilder();

     foreach (Match collect in listContent)
     {
         var subCollect = Regex.Matches(collect.Value, chinsesPattern);
         foreach (Match sub in subCollect)
         {
             string pattern = @"\\u([0-9a-fA-F]{4})";

             sb.AppendLine(Regex.Replace(sub.Value, pattern, match =>
             {
                 // 将匹配到的 Unicode 转义序列转换为对应的 Unicode 字符
                 string unicodeValue = match.Groups[1].Value;
                 int codePoint = Convert.ToInt32(unicodeValue, 16);
                 return char.ConvertFromUtf32(codePoint);
             }));
         }

     }
     return sb.ToString();
 }

背景2代码如下:

[MenuItem("Tools/EasyUseEditorTool/Remove Missing Scripts")]
static void RemoveMissScriptInGame()
{
    GameObject[] gos = Resources.FindObjectsOfTypeAll<GameObject>();
    foreach (GameObject obj in gos)
    {
        var components = obj.GetComponents<Component>();
        for (int j = 0; j < components.Length; j++)
        {
            if (components[j] == null)
            {
                GameObjectUtility.RemoveMonoBehavioursWithMissingScript(obj);
                break;
            }
        }
    }
    AssetDatabase.SaveAssets();
    AssetDatabase.Refresh();
    
}

如果不移除missing的脚本批处理脚本就太难做了。

背景3代码:这块代码每个项目因人而异,需要特别注意多做测试。比如我们项目中一个image可能没有挂button组件或者toggle组件但是挂了自定义的mono对象,内部做了事件那这种也不能去掉

rayCastTarget属性,所以因项目而异。小项目简单项目可以用

using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
public class PrefabHelper 
{
    [InitializeOnLoadMethod]
    public static void init()
    {
        Debug.Log("PrefabHelper.init");
        PrefabStage.prefabStageClosing -= OnPrefabStageClosing;
        PrefabStage.prefabStageClosing += OnPrefabStageClosing;
    }
    
    public static void OnPrefabStageClosing(PrefabStage ps)
    {
        var root = ps.prefabContentsRoot;
        var window = root.transform.Find("Window");
        if (window == null)
        {
            window = root.transform.Find("window");
        }
        var rawImage = root.transform.Find("pingui");
        if(rawImage != null)
        {
            GameObject.DestroyImmediate(rawImage);
        }
        window.localScale = Vector3.zero; 
        SCGTool.RemoveNoUseRayCast(root);
        Object prefabObj = PrefabUtility.SaveAsPrefabAsset(root, ps.assetPath,out bool success);
        if(success)
        {
            Debug.Log("apply sucess " + ps.assetPath);
        }
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }
}
[InitializeOnLoad]
public class SCGTool 

{

        

public static  void RemoveNoUseRayCast(GameObject go)
 {
     var tys = new System.Type[]
        {
            typeof(Toggle),typeof(Button),
        };
     // 获取text或者rowImage或者image
     var raws = go.GetComponentsInChildren<RawImage>(true);
     for (int i = 0; i < raws.Length; i++)
     {
         bool isAllNUll = true;
         foreach(var t in tys)
         {
             
             if ( raws[i].GetComponent(t) != null)
             {
                 isAllNUll = false;
             }
         }
         raws[i].raycastTarget = !isAllNUll ;
            
     }
     var images = go.GetComponentsInChildren<Image>(true);
     for (int i = 0; i < images.Length; i++)
     {
         if (images[i].GetComponent<Button>() == null && images[i].GetComponent<Toggle>() == null
             && images[i].GetComponent<ScrollRect>() == null && images[i].GetComponent<TouchMove>() == null)
         {
             images[i].raycastTarget = false;
         }
     }

     var texts = go.GetComponentsInChildren<Text>(true);
     for (int i = 0; i < texts.Length; i++)
     {
         texts[i].raycastTarget = false;
     }

     //然后遍历所有button对于设定了
     var allButtons = go.GetComponentsInChildren<Button>(true);

     foreach (var button in allButtons)
     {
         if(button != null && button.targetGraphic != null)
         {
             var tmpImage = button.targetGraphic.GetComponent<Image>();
             if (tmpImage != null)
             {
                 tmpImage.raycastTarget = true;
                 continue;
             }
             var tmpRawImage = button.targetGraphic.GetComponent<RawImage>();
             if (tmpRawImage != null)
             {
                 tmpRawImage.raycastTarget = true;
                 continue;
             }

             var tmpText = button.targetGraphic.GetComponent<Text>();
             if (tmpText != null)
             {
                 tmpText.raycastTarget = true;
                 continue;
             }

         }
         else if(button !=null)
         {
             var tmpImage = button.targetGraphic.GetComponent<Image>();
             if (tmpImage != null)
             {
                 tmpImage.raycastTarget = true;
                 continue;
             }
             var tmpRawImage = button.targetGraphic.GetComponent<RawImage>();
             if (tmpRawImage != null)
             {
                 tmpRawImage.raycastTarget = true;
                 continue;
             }

             var tmpText = button.targetGraphic.GetComponent<Text>();
             if (tmpText != null)
             {
                 tmpText.raycastTarget = true;
                 continue;
             }
         }
     }
     


     EditorUtility.SetDirty(go);
 }


http://www.ppmy.cn/news/1534065.html

相关文章

基于SpringBoot+Vue+MySQL的在线酷听音乐系统

系统展示 用户前台界面 管理员后台界面 系统背景 随着互联网技术的飞速发展&#xff0c;网络已成为人们日常生活中不可或缺的一部分。在线音乐服务因其便捷性和丰富性&#xff0c;逐渐成为用户获取音乐内容的主要渠道。然而&#xff0c;传统的音乐播放平台往往存在歌曲资源有限…

python-矩阵转置/将列表分割成块/和超过N的最短子数组

一&#xff1a;矩阵转置 题目描述 输入一个 n 行 m 列的矩阵 A&#xff0c;输出它的转置 AT。输入 第一行包含两个整数 n 和 m&#xff0c;表示矩阵 A 的行数和列数。1≤n≤100&#xff0c;1≤m≤100。接下来 n 行&#xff0c;每行 m 个整数&#xff0c;表示矩阵 A 的元素。相邻…

C语言-进程控制编程

1、 进程的基本概念 进程的分类 交互进程 批处理进程 守护进程&#xff1a;一般在后台运行&#xff0c;一般由操作系统在开机时通过脚本自动激活启动或由超级管理用户root来启动 进程的属性 进程ID&#xff1a;进程的唯一数值&#xff0c;用来区分进程 启动…

RabbitMQ高级特性-发送方确认

对于发送方发送消息到RabbitMQ的可靠性机制 引入:在持久化的消息正确存⼊RabbitMQ之后,还需要有⼀段时间(虽然很短,但是不可忽视)才能存⼊磁盘中.RabbitMQ并不会为每条消息都进⾏同步存盘(调⽤内核的fsync⽅法)的处理, 可能仅仅保存到操作系统缓存之中⽽不是物理磁盘之中. 如…

Redis-主从复制

分布式系统,涉及到一个非常关键的问题:单点问题 如果某个服务器程序,只有一个节点,就会出现: 可用性问题(这个服务器挂了,服务中断)性能/支持的并发量有限 引入分布式系统,主要也是为了解决上述的单点问题 在分布式系统中,希望有多个服务器来部署redis服务,从而构成一个red…

【JAVA开源】基于Vue和SpringBoot的校园资料分享平台

本文项目编号 T 059 &#xff0c;文末自助获取源码 \color{red}{T059&#xff0c;文末自助获取源码} T059&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

游戏如何对抗改包

游戏改包是指通过逆向分析手段及修改工具&#xff0c;来篡改游戏包内正常的设定和规则的行为&#xff0c;游戏包被篡改后&#xff0c;会被植入/剔除模块进行重打包。 本期图文我们将通过实际案例分析游戏改包的原理&#xff0c;并分享游戏如何应对改包问题。 安卓平台常见的改…

django创建一个新的应用

使用 python manage.py startapp myapp 命令可以在你的 Django 项目中创建一个新的应用&#xff0c;名为 myapp。应用是 Django 项目的组成部分&#xff0c;可以帮助你组织代码和功能。执行该命令后&#xff0c;会在你的项目目录下创建一个名为 myapp 的文件夹&#xff0c;包含…