Unity项目较大刷新及编译卡顿解决方法

2023-10-27

开发中当Unity项目比较大的时候,每次Unity窗口获取焦点时刷新需要3-5秒,非常麻烦!常见有几种方法来缓解这个问题:

  •      关闭unity自动刷新Edit->Preferences->General->Auto Refresh,改为自己手动Ctrl+R刷新;

           

        缺点:每次都需要手动刷新比较麻烦

  •    修改unity的ScriptChangesWhilePlaying选项Editor->Preferences->General->Script Changes While Playing

          

        Recompile And Continue Playing 编译并继续播放

        Recompile After Finished Playing 停止播放后再编译

        Stop Playing And Recompile 停止播放进行编译

  •  开发工具在Editor模式自动检查资源变更自动刷新,代码如下:

        第一步:检查开发过程中需要及时刷新的资源,如:Scripts目录,prefab目录

        第二步:获取最后改动时间是否与上一次检查的时间一致,不一致则启动刷新

        第三步:将时间写入文件缓存,方便下一次对比

        第四步:在窗口获取焦点以及Playing启动时启动检测

#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security.Cryptography;

[InitializeOnLoad]
public class EditorNotification : AssetPostprocessor
{
    private static bool isFocused;
    private static bool isPlaymode;
    static EditorNotification()
    {
        EditorApplication.update -= Update;
        EditorApplication.update += Update;
        EditorApplication.playmodeStateChanged -= PlaymodeStateChanged;
        EditorApplication.playmodeStateChanged += PlaymodeStateChanged;
    }

    private static void Update()
    {
        if (isFocused == UnityEditorInternal.InternalEditorUtility.isApplicationActive)
        {
            return;
        }
        isFocused = UnityEditorInternal.InternalEditorUtility.isApplicationActive;
        OnEditorFocus(isFocused);
    }

    private static void PlaymodeStateChanged()
    {
        if(EditorApplication.isPlayingOrWillChangePlaymode && !isPlaymode)
        {
            //Debug.LogError(EditorApplication.isPlaying.ToString() + " - " + EditorApplication.isPlayingOrWillChangePlaymode.ToString());
            isPlaymode = true;
            Refresh();
        }
        else if(!EditorApplication.isPlayingOrWillChangePlaymode && !EditorApplication.isPlaying)
        {
            isPlaymode = false;
        }
    }
    /// <summary>
    /// Unity窗口聚焦状态改变回调
    /// </summary>
    /// <param name="focus"></param>
    private static void OnEditorFocus(bool focus)
    {
        if (focus)
        {
            //Debug.LogErrorFormat("编辑器激活状态:{0}", focus);
            if(!EditorApplication.isPlaying && !EditorApplication.isPlayingOrWillChangePlaymode)
            {
                Refresh();
            }
        }
    }

    private void OnPreprocessAsset()
    {
        //Debug.LogError("Asset下文件改变时回调");
    }

    //[MenuItem("File/RefreshManual")]
    static void Refresh()
    {
        bool needRefresh = false;
        MD5File md5 = new MD5File();
        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
        sw.Reset();
        sw.Start();
        string path = Path.Combine($"{Application.dataPath}/../Library", "md5Refresh.dat");
        if(File.Exists(path))
        {
            FileStream fs = new FileStream(path, FileMode.OpenOrCreate);
            BinaryFormatter bin = new BinaryFormatter();
            md5 = (MD5File)bin.Deserialize(fs);
            fs.Close();
        }
        
        string scriptPath = Path.Combine($"{Application.dataPath}", "Scripts");
        DirectoryInfo dinfo = new DirectoryInfo(scriptPath);
        FileInfo[] fileInfos = dinfo.GetFiles("*.cs", SearchOption.AllDirectories);
        foreach(FileInfo file in fileInfos)
        {
            string timestr = file.LastWriteTime.ToLongTimeString();
            string value = string.Empty;
            if(md5.m_DicMD5.TryGetValue(file.FullName, out value))
            {
                System.DateTime dt = System.DateTime.Parse(value);
                System.DateTime dt2 = System.DateTime.Parse(timestr);
                if(!System.DateTime.Equals(dt, dt2))
                {
                    needRefresh = true;
                    md5.m_DicMD5[file.FullName] = timestr;
                    Debug.LogError(file.FullName + " - " + value + " -- " + timestr);
                }
            }
            else
            {
                needRefresh = true;
                md5.m_DicMD5.Add(file.FullName, timestr);
                Debug.LogError(file.FullName + " -------- " + timestr);
            }
        }

        {
            FileStream fs = new FileStream(path, FileMode.OpenOrCreate);
            BinaryFormatter bin = new BinaryFormatter();
            bin.Serialize(fs, md5);
            fs.Close();
        }
        sw.Stop();
        string str = "C#变更检查结束,不需要刷新!";
        if (needRefresh)
        {
            str = "C#变更检查结束,需要刷新!";
            string t = (sw.Elapsed.TotalMilliseconds / 1000).ToString("N2");
            Debug.LogError($"{str}FileCount:{fileInfos.Length} Time:{t}秒");
            AssetDatabase.Refresh();
            EditorUtility.RequestScriptReload();
        }
    }
}
#endif

 

using System.Collections;
using System.Collections.Generic;

[System.Serializable]
public class MD5File
{
    public Dictionary<string, string> m_DicMD5 = new Dictionary<string, string>();
}

 这种方法只需要检查少部分资源自动刷新,基本没有卡顿,体验相对比较好!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unity项目较大刷新及编译卡顿解决方法 的相关文章

随机推荐

  • Android 移动安全知识技术全解(加固技术、常规漏洞、Android 逆向......),移动安全问题不容忽视

    前言 您的设备是否处于遭受攻击 劫持或损害的风险中 毫无疑问 剑桥大学的研究人员发现 87 的 Android 智能手机有至少一个严重漏洞 Zimperium Labs 在早些时候发现 黑客只需通过一条简单的短信便能对 95 的 Andro
  • Let’s Make C++ Great Again——multiset与unordered_set

    文章目录 multiset 头文件 定义和插入元素 访问元素 遍历元素 删除元素 以下是一些常用的函数和用法 size empty 自定义排序方式 删除所有相同的元素 multiset和set有什么区别 元素唯一性 插入和删除 查找 uno
  • JVM垃圾回收与性能调优总结

    JVM垃圾回收与性能调优总结 JVM调优的几种策略 一 JVM内存模型及垃圾收集算法 1 根据Java虚拟机规范 JVM将内存划分为 New 年轻代 Tenured 年老代 永久代 Perm 其中New和Tenured属于堆内存 堆内存会从
  • 免费虚拟服务器注册,如何注册免费虚拟主机空间

    如何注册免费 目前能提供免费虚拟主机空间的服务商 非常少 即使有 也是各种限制 这里仅推荐几款比较熟知的品牌 OpenShift OpenShift空间是Red Hat的平台即服务的 但也存在着 PHP程序不兼容 国内访问速度慢 访问出现莫
  • 如何使用overleaf&LaTeX

    Introduction What is LaTeX LaTeX是一种基于 的排版系统 由美国计算机学家莱斯利 兰伯特 Leslie Lamport 在20世纪80年代初期开发 利用这种格式 即使使用者没有排版和程序设计的知识也可以充分发挥
  • Python: list列表的11个内置方法

    前言 在实际开发中 经常需要将一组 不只一个 数据存储起来 以便后边的代码使用 在VBA中有使用数组 可以把多个数据存储 到一起 通过数组下标可以访问数组中的每个元素 Python 中没有数组 但是加入了更加强大的列表 list 下面就对列
  • 从输入URL到浏览器显示页面到底经历了什么?

    文章目录 从输入URL到浏览器显示页面到底经历了什么 DNS解析 1 DNS解析过程 2 DNS优化 建立TCP连接 1 什么是TCP 2 TCP的连接建立 三次握手 3 为什么是三次握手 发送HTTP请求 1 请求行 2 HTTP缓存优化
  • Yii Framework 开发教程(29) Zii组件-Menu 示例

    介绍完Yii数据库接口外 从本篇开始介绍Zii组件 包括列表视图ListView 表格视图GridView 此外还包括一些基于JQuery的UI组件 如AutoComplete DataPicker Button Drag 和 Drop等
  • 用Java生成N个不重复的随机数,3种实例

    1 Random类和Set集合来完成 Java实现生成n个不重复的随机数可以使用Java中的Random类和Set集合来完成 具体代码如下 import java util HashSet import java util Random i
  • el-table 中嵌入el-input 输入框无法输入问题(已解决)

    在使用elment ui中的el table 中嵌入el input 会出现 input 无法输入的情况 最后找到了问题的根源 是有时候获取到了数据 但是视图并没有更新 修改前代码
  • STM32f103系列 USART2 USART3 串口2和串口3通信

    最近在做一个工程要用到多个串口同时通讯的 就参考了正点原子的串口通讯例程 发现例程是USART1 串口1的 后面我想改成USART2 串口2的 上网找了资料 要不是不靠谱 要不就是要积分下载 所以后面自己写了一个可用程序来和大家分享 废话不
  • 期货反向跟单犯法吗?

    本篇文章给大家为分析一下关于 期货反向跟单犯法吗 这个疑问 对于想从事或正在运作跟单交易的朋友们来说有必要看一下 做反单跟单不同于做一个黑平台 黑平台的利润是来源于客户的亏损 而做反单的利润来源是市场 和杀羊具有本质区别 不存在什么违法行为
  • 【Educoder作业】C++ 面向对象 - 类的继承与派生

    Educoder作业 C 面向对象 类的继承与派生 关于继承 更多的是关注它的意义 在代码量很少的时候用处不大 大不了再写一个 但是当完成一些工作量比较大的工程时 继承就会避免我们重复的写很多东西 T1 公有继承 学生信息类 关注一下如何继
  • SpringBoot中使用Log4j2

    一 简介 slf4j是日志接口 logback和log4j2是其实现 log4j2的并发效率优于logback 二 SpringBoot中使用log4j2 由于SpringBoot中默认使用logback作为其日志框架 因此如果需要替换为l
  • VS报错runtime check failure #2的解决办法

    第一类 如果后续报错变量为指针类型 检查数组下标访问是否正确 有可能是越界访问 第二类 如果不是指针变量 可以将该局部变量改为全局变量
  • static_cast、dynamic_cast、const_cast和reinterpret_cast总结

    前言 这篇文章总结的是C 中的类型转换 这些小的知识点 有的时候 自己不是很注意 但是在实际开发中确实经常使用的 俗话说的好 不懂自己写的代码的程序员 不是好的程序员 如果一个程序员对于自己写的代码都不懂 只是知道一昧的的去使用 终有一天
  • 【读点论文】Image Style Transfer Using Convolutional Neural Networks(将卷积特征图提取语义信息,融合内容和风格的做法)

    Image Style Transfer Using Convolutional Neural Networks 以不同风格呈现图像的语义内容是一项困难的图像处理任务 可以说 以前的方法的一个主要限制因素是缺乏明确表示语义信息的图像表示 从
  • java 文字转语音

    使用 jacob project 插件 注意 jacob不支持linux jacob是 JAVA COM Bridge 的缩写 是一个中间件 能够提供自动化访问MS系统下COM组件和 Win32 libraries 的功能 并且jacob只
  • Jsp+Servlet+JavaBean到EJB,再到Spring,最后到SpringBoot

    一 知史可以明鉴 我们学习技术的时代赶上了最好的时代 跳过了很多前人经常踩的坑 前人在踩坑的过程中总结了很多经验和教训 而新时代的我们只是继承了前人的经验和教训 而忽略了这些采坑的过程 以至于我们面对很多新技术都不知道他是什么 他为什么存在
  • Unity项目较大刷新及编译卡顿解决方法

    开发中当Unity项目比较大的时候 每次Unity窗口获取焦点时刷新需要3 5秒 非常麻烦 常见有几种方法来缓解这个问题 关闭unity自动刷新Edit gt Preferences gt General gt Auto Refresh 改