一直以来,我都是Rider的忠实用户,它写代码真的很爽,但是随着公司项目越来越大,Rider的一个插件:Rider For Unity,其石一样的代码会导致每次Rider启动需要花几十分钟的时间,在项目中非代码文件特别多的时候,Rider打开时需要初始化非常非常久,原以为是额外扫描了非代码文件导致,但是我在Rider设置中过滤了所有非代码文件,也在这个插件的设置界面配置了大项目禁止文件索引,但结果还是一样的,但是,如果我禁用这个Unity插件,Rider就可以在1分钟之内完成初始化,开始正常工作,但是我又需要这个插件的Debug和Shader提示功能。
尝试过下载插件源码 https://github.com/JetBrains/resharper-unity 来重编译,但是复杂的编译模块和无数个报错让我放弃了
恰巧那阵子Cursor AI大火,我也就没继续深入研究,就转头去用Cursor了,基于VSCode的编码体验,你们懂得,经常遇到智能提示失效,缓慢的问题
又恰巧这阵子Claude以碾压姿态发布了自己的命令行工具,由于其优秀的性能和断档级领先的使用体验,国内各种中转站也是赚的盆满钵满(顺带打个广告: https://aicodewith.com/?invitation=IQCVL6U ),而Claude由于其命令行的形式,可以无缝集成在各大IDE里,当我看到官网的Rider支持,不禁见景思人,回想起最近被VSCode折磨得经历,决定痛定思痛,去修复Rider For Unity这个插件。

首先,重编译插件肯定是走不通了,毕竟没有那个兴致和精力去学他们的编译模块,遂决定曲线救国:

  1. Cursor分析插件源码,找到问题,并修复代码
  2. 直接通过dnspy反编译插件的dll,将Cursor给出的代码替换进去

编译完成后,新的插件将不会扫描非代码文件,这应该能解决您遇到的初始化缓慢问题。测试时您会发现Rider启动速度明显提升,同时Debug和Shader功能依然正常工作。

resharper/resharper-unity/src/Unity/Core/Psi/Modules/UnityExternalFilesModuleProcessor

修复后代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
public virtual void OnHasUnityReference()  
{
// PERFORMANCE OPTIMIZATION: Skip file collection for large projects
return;
}

public UnityExternalFilesModuleProcessor(Lifetime lifetime, ILogger logger, ISolution solution,
ChangeManager changeManager,
IPsiModules psiModules,
PackageManager packageManager,
IShellLocks locks,
IFileSystemTracker fileSystemTracker,
IProjectFileExtensions projectFileExtensions,
UnityExternalPsiSourceFileFactory psiSourceFileFactory,
UnityExternalFilesModuleFactory moduleFactory,
UnityExternalFilesIndexDisablingStrategy indexDisablingStrategy,
ILazy<UnityAssetInfoCollector> usageStatistics,
AssetIndexingSupport assetIndexingSupport,
UnityExternalProjectFileTypes externalProjectFileTypes)
{
myLifetime = lifetime;
myLogger = logger;
mySolution = solution;
myChangeManager = changeManager;
myPackageManager = packageManager;
myLocks = locks;
myFileSystemTracker = fileSystemTracker;
myProjectFileExtensions = projectFileExtensions;
myPsiSourceFileFactory = psiSourceFileFactory;
myModuleFactory = moduleFactory;
myIndexDisablingStrategy = indexDisablingStrategy;
myUsageStatistics = usageStatistics;
myAssetIndexingSupport = assetIndexingSupport;
myExternalProjectFileTypes = externalProjectFileTypes;

myRootPathLifetimes = new Dictionary<VirtualFileSystemPath, LifetimeDefinition>();

// SolutionDirectory isn't absolute in tests, and will throw an exception if we use it when we call Exists
mySolutionDirectory = solution.SolutionDirectory;
if (!mySolutionDirectory.IsAbsolute)
mySolutionDirectory = solution.SolutionDirectory.ToAbsolutePath(FileSystemUtil.GetCurrentDirectory().ToVirtualFileSystemPath());

myProjectSettingsFolder = mySolutionDirectory.Combine(ProjectExtensions.ProjectSettingsFolder);
changeManager.RegisterChangeProvider(lifetime, this);
changeManager.AddDependency(lifetime, psiModules, this);

assetIndexingSupport.IsEnabled.Change.Advise(lifetime, args =>
{
// previously disabled, now enabled
if (args.HasOld && !args.Old && args.HasNew && args.New)
{
myLocks.ExecuteOrQueueReadLockEx(lifetime, "UnityInitialUpdateExternalFiles", () =>
{
// ========================================== 此行注释
//CollectInitialFiles(false);
// =============================================此行注释
});
}
});
}

Rider For Unity插件反编译

不知道从哪个版本起,Unity插件被内置到Rider了,可以从Rider主界面-帮助-特殊文件和文件夹,看到所有路径,而Rider For Unity位于C:\Users\UserName\AppData\Local\Programs\Rider\plugins\rider-unity
根据命名空间原则,我们直接找到JetBrains.ReSharper.Plugins.Unity.dll进行修改,用dnspy打开,并添加基础dll:全都位于C:\Users\UserName\AppData\Local\Programs\Rider\lib\ReSharperHost中,直接拖到dnspy窗口即可
在dnspy定位到JetBrains.ReSharper.Plugins.Unity.Core.Psi.Modules.UnityExternalFilesModuleProcessor文件
修改代码,并编译保存,如果有报错直接注释整个函数内容,只保留空函数体即可,反正我们不需要这些乱七八糟的功能
重新打开Rider,原本几十分钟的初始化时间,现在几分钟直接搞定!
尤其需要注意的是,由于插件被内置到Rider,所以不同版本的Rider必须都手动反编译这个代码文件

拓展

当然,这只是核心问题被解决,实际上可以继续优化,比如让Cursor帮我们将文件扫描的入口整个关掉,但是不确定会不会导致其他问题,大家可以自行尝试