最近在写shader的时候看着用vs打开的shader文件排版痛不欲生,即使用了一些shader扩展工具也是想爆粗口。个人比较喜欢用VSCode编写shader,但写cs文件还是习惯使用vs。如果你也有同样的诉求,需要根据不同的文件扩展名自定义打开方式的话,就可以用到unity自带的OnOpenAsset属性。
1.配置环境变量
下面的代码只扩展了VSCode和Sublime的打开方式,因为考虑到代码要在不同的电脑上同步使用,exe路径不直接使用完整路径而是使用环境变量。
VSCode和Sublime的环境变量名分别为VSCode_Path和Subline_Path,环境变量的配置方式可自行百度,配置到对应exe文件的上级目录就可以了。
配置完成后需要重启Unity,但有时候也需要重启电脑。。。
2.窗口代码
下面的脚本要放再Editor目录下,然后就可以通过XDEDZL/Asset/OpenMode来打开这个窗口并修改文件打开方式了
using System;
using System.Diagnostics;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEngine;
public class AssetOpenModeWindow : EditorWindow
{
private static CodeOpneMode shaderOpenMode = CodeOpneMode.VSCode;
private static CodeOpneMode csOpenMode = CodeOpneMode.Default;
private AssetOpenModeWindow window;
private float currentWidth;
private float currentHeight;
private void OnEnable()
{
Load();
}
private void OnGUI()
{
GUI.backgroundColor = new Color32(0, 170, 255, 50);
EditorGUILayout.BeginVertical("box");
GUI.backgroundColor = new Color32(255, 255, 0, 180);
shaderOpenMode = (CodeOpneMode)EditorGUILayout.EnumPopup("Shader", shaderOpenMode);
csOpenMode = (CodeOpneMode)EditorGUILayout.EnumPopup("CS", csOpenMode);
EditorGUILayout.EndVertical();
}
private void OnDestroy()
{
Save();
}
[MenuItem("XDEDZL/Asset/OpenMode")]
private static void OpenWidown()
{
GetWindow(typeof(AssetOpenModeWindow));
}
[OnOpenAsset(1)]
public static bool OpenAsset(int instanceID, int line)
{
string fileFullPath = System.IO.Directory.GetParent(Application.dataPath) + "/" + AssetDatabase.GetAssetPath(EditorUtility.InstanceIDToObject(instanceID));
if (fileFullPath.EndsWith(".shader")) //文件扩展名类型
{
return OpenAssetWithEnd(shaderOpenMode, fileFullPath);
}
else if(fileFullPath.EndsWith(".cs"))
{
return OpenAssetWithEnd(csOpenMode, fileFullPath);
}
return false;
}
/// <summary>
/// 打开文件
/// </summary>
private static bool OpenAssetWithEnd(CodeOpneMode mode,string strFileName)
{
string fullName = GetFileFullname(mode);
if (fullName == null)
return false;
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = GetFileFullname(mode);
startInfo.Arguments = "\"" + strFileName + "\"";
process.StartInfo = startInfo;
process.Start();
return true;
}
/// <summary>
/// 通过打开方式获取exe完整路径
/// </summary>
private static string GetFileFullname(CodeOpneMode mode)
{
string editorPath;
switch (mode)
{
case CodeOpneMode.VSCode:
editorPath = Environment.GetEnvironmentVariable("VSCode_Path");
return editorPath == null ? null : editorPath + (editorPath.EndsWith("/") ? "" : "/") + "Code.exe";
case CodeOpneMode.Sublime:
editorPath = Environment.GetEnvironmentVariable("Sublime_Path");
return editorPath == null ? null : editorPath + (editorPath.EndsWith("/") ? "" : "/") + "sublime_text.exe";
default:
return null;
}
}
/// <summary>
/// 保存编辑器变量
/// </summary>
private void Save()
{
EditorPrefs.SetInt("shaderMode", (int)shaderOpenMode);
EditorPrefs.SetInt("csMode", (int)csOpenMode);
}
/// <summary>
/// 加载编辑器变量
/// </summary>
private void Load()
{
shaderOpenMode = (CodeOpneMode)EditorPrefs.GetInt("shaderMode", 1);
csOpenMode = (CodeOpneMode)EditorPrefs.GetInt("csMode", 0);
}
enum CodeOpneMode
{
Default,
VSCode,
Sublime,
}
}