Skip to content

Instantly share code, notes, and snippets.

@grapefrukt
Last active June 28, 2022 11:19
Show Gist options
  • Save grapefrukt/e31f2a596f75964e844b9f4329378bb1 to your computer and use it in GitHub Desktop.
Save grapefrukt/e31f2a596f75964e844b9f4329378bb1 to your computer and use it in GitHub Desktop.
Replaces/modifies the Unity behavior templates using a handful of regexes.
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
using UnityEditor;
using Debug = UnityEngine.Debug;
/// <summary>
/// Unity template fixer by grapefrukt (m@grapefrukt.com)
/// Runs a series of regexes on
/// </summary>
public class UnityTemplateFixer : Editor {
static readonly string[] TemplateFiles = {
"81-C# Script-NewBehaviourScript.cs.txt"
};
readonly struct ReplaceTuple {
public readonly string regex;
public readonly string replacement;
public ReplaceTuple(string regex, string replacement = "") {
this.regex = regex;
this.replacement = replacement;
}
}
static readonly ReplaceTuple[] FindReplacePairs = {
// replaces the comment before Start()
new ReplaceTuple( @"\w*// Start is called before the first frame update$"),
// replaces the comment before Update()
new ReplaceTuple( @"\w*// Update is called once per frame$"),
// braces on line 4-ever
new ReplaceTuple( @"\s*{", " {"),
};
[MenuItem("Tools/Fix Class Templates")]
static void FixTemplates() {
foreach (var file in TemplateFiles) {
FixTemplate(file);
}
}
static void FixTemplate(string templateFile) {
var path = Path.GetDirectoryName(EditorApplication.applicationPath);
path = Path.Combine(path, "Data", "Resources", "ScriptTemplates", templateFile);
if (!File.Exists(path)) {
Debug.LogError("Could not find script template at expected location.");
return;
}
var template = File.ReadAllText(path);
foreach (var tuple in FindReplacePairs) {
var regex = new Regex(tuple.regex, RegexOptions.Multiline);
template = regex.Replace(template, tuple.replacement);
}
// read the template from disk again, compare it with the modified version
// if they're the same, we're done
var onDisk = File.ReadAllText(path);
if (template == onDisk) {
Debug.Log("Template is already as desired.");
return;
}
// write the modified template to a temp path
var newPath = FileUtil.GetUniqueTempPathInProject();
newPath = Path.GetFullPath(newPath);
File.WriteAllText(newPath, template);
// start a new process that runs copy in the command prompt
// we need to elevate the privileges of this to be able to write to the program files directory
// where unity keeps its templates
var startInfo = new ProcessStartInfo {
FileName = "cmd.exe",
Arguments = $"/c copy /y \"{newPath}\" \"{path}\"",
Verb = "runas",
};
var process = new Process { StartInfo = startInfo };
process.Start();
// we wait for the process to finish before we check the file on disk again
process.WaitForExit();
onDisk = File.ReadAllText(path);
if (template == onDisk) {
Debug.Log("Template replaced successfully.");
} else {
Debug.LogError("Template replacement failed.");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment