Wrote some scripts to auto optimize code, would like it if some people tested them out, just don’t get mad if they break your code a bit ( backup first ). Place all files in the editor folder. Plan to turn them into a store asset once I develop and test them a bit more.
First one replaces string in update function with hardcoded string set in start to remove garbage collection
header.txt
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class stringManager : MonoBehaviour
{
private static stringManager instance = null;
// Game Instance Singleton
public static stringManager Instance
{
get
{
return instance;
}
}
private void Awake()
{
// if the singleton hasn't been initialized yet
if (instance != null && instance != this)
{
Destroy(this.gameObject);
}
instance = this;
DontDestroyOnLoad( this.gameObject );
}
// Strings DB ( Reduces Garbage Collection )
footer.txt
}
stringOptimizer.cs
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.IO;
using UnityEngine;
using UnityEditor;
public class stringOptimizer
{
private static StreamWriter managerOutput;
private static string line;
private static int bracketCount;
private static bool bracketRead = false;
[MenuItem ("Window/Optimize/Optimize Strings", false)]
static void FindAssetsUsingSearchFilter ()
{
// Find all code assets
string[] guids = AssetDatabase.FindAssets ("t:MonoScript");
bool inUpdate;
bool inFixedUpdate;
bool inLateUpdate;
if (File.Exists ("Assets/stringManager.cs")) {
File.Copy ("Assets/stringManager.cs", "Assets/stringManager.cs" + ".undo");
}
managerOutput = new StreamWriter ("Assets/stringManager.cs");
stringManagerHeadFoot ("Assets/Editor/header.txt");
Debug.LogError (guids.Length + " Strings found");
foreach (string guid in guids) {
int stringCount = 0;
Debug.Log (AssetDatabase.GUIDToAssetPath (guid));
if (!AssetDatabase.GUIDToAssetPath (guid).Contains ("Editor")) {
saveUndoFile (AssetDatabase.GUIDToAssetPath (guid));
StreamReader input = new StreamReader (AssetDatabase.GUIDToAssetPath (guid));
StreamWriter output = new StreamWriter ("Assets/temp.txt");
bracketCount = 0;
inUpdate = false;
inLateUpdate = false;
inFixedUpdate = false;
while ((line = input.ReadLine ()) != null) {
Debug.LogError ("Read line " + line);
bracketRead = false;
inUpdate = inFunction ("Update(", "Update (", inUpdate, 0);
inLateUpdate = inFunction ("LateUpdate(", "LateUpdate (", inUpdate, 0);
inFixedUpdate = inFunction ("FixedUpdate(", "FixedUpdate (", inUpdate, 0);
if (((inUpdate) || (inFixedUpdate) || (inLateUpdate)) && (line.Contains ("\"") && (!line.Contains ("case") && (!line.Contains ("[ContextMenu"))))) {
line = line.Replace ("\\\"", "DOUBLESTRING");
Debug.LogError ("String found");
string[] temp = line.Split ('"');
if (temp.Length >= 3) {
Debug.LogError (temp [0] + temp [1] + temp [2]);
int count = 1;
while (count < temp.Length) {
Debug.LogError ("String number " + count);
Debug.LogError ("Match");
// write string to string manager
managerOutput.Write ("\tpublic string " + Path.GetFileNameWithoutExtension (AssetDatabase.GUIDToAssetPath (guid)) + stringCount + " = \"" + temp [count] + "\";");
managerOutput.WriteLine ();
// replace string with stringManager.Instance.classnameStringcount
string originalString = '"' + temp [count] + '"';
string replaceString = "stringManager.Instance." + Path.GetFileNameWithoutExtension (AssetDatabase.GUIDToAssetPath (guid)) + stringCount;
line = line.Replace (originalString, replaceString);
//line.Replace (originalString, replaceString);
Debug.LogError ("Writing line " + line + " replaced " + originalString + " with " + replaceString);
stringCount++;
count = count + 2;
}
}
line = line.Replace ("DOUBLESTRING", "\\\"");
}
// Write the current line
output.Write (line);
output.WriteLine ();
}
output.Close ();
input.Close ();
File.Delete (AssetDatabase.GUIDToAssetPath (guid));
File.Move ("Assets/temp.txt", AssetDatabase.GUIDToAssetPath (guid));
}
}
stringManagerHeadFoot ("Assets/Editor/footer.txt");
managerOutput.Close ();
}
static void stringManagerHeadFoot (string headerPath)
{
string headerLine;
StreamReader input = new StreamReader (headerPath);
while ((headerLine = input.ReadLine ()) != null) {
managerOutput.Write (headerLine);
managerOutput.WriteLine ();
}
input.Close ();
}
static bool inFunction (string search1, string search2, bool testCondition, int braceMatch)
{
if ((line.Contains (search1)) || (line.Contains (search2))) {
testCondition = true;
if ((line.Contains ("{")) && (!bracketRead)) {
bracketRead = true;
bracketCount++;
}
Debug.LogError ("In Function " + search1);
Debug.LogError (bracketCount);
} else {
if (testCondition) {
if ((line.Contains ("{")) && (!bracketRead)) {
bracketRead = true;
bracketCount++;
Debug.LogError ("Open function " + bracketCount);
}
if ((line.Contains ("}")) && (!bracketRead)) {
bracketRead = true;
bracketCount--;
Debug.LogError ("Close function " + bracketCount);
}
if ((bracketCount == braceMatch)) {
testCondition = false;
Debug.LogError (bracketCount);
Debug.LogError ("Exit Function");
}
}
}
return(testCondition);
}
static void saveUndoFile (string path)
{
if (File.Exists (path + ".undo")) {
File.Delete (path + ".undo");
}
File.Copy (path, path + ".undo");
}
}
The second optimizes GetComponent calls in Update on the local gameobject
optimizeComponents.cs
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.IO;
using UnityEngine;
using UnityEditor;
using System.Text.RegularExpressions;
public class componentOptimizer
{
private static string line;
private static int bracketCount;
private static bool bracketRead = false;
[MenuItem ("Window/Optimize/Optimize Components", false)]
static void FindAssetsUsingSearchFilter ()
{
// Find all code assets
string[] guids = AssetDatabase.FindAssets ("t:MonoScript");
Debug.LogError (guids.Length + " Strings found");
bool inUpdate = false;
bool inAwake = false;
bool inStart = false;
bool inClass = false;
bool writtenVars = false;
bool written = false;
foreach (string guid in guids) {
int stringCount = 0;
bracketCount = 0;
inUpdate = false;
inAwake = false;
inStart = false;
inClass = false;
written = false;
bracketRead = false;
writtenVars = false;
written = false;
Debug.Log (AssetDatabase.GUIDToAssetPath (guid));
if (!AssetDatabase.GUIDToAssetPath (guid).Contains ("Editor")) {
saveUndoFile (AssetDatabase.GUIDToAssetPath (guid));
StreamReader input = new StreamReader (AssetDatabase.GUIDToAssetPath (guid));
StreamWriter output = new StreamWriter ("Assets/temp.txt");
List<string> newVariables = new List<string> ();
List<string> newInitializer = new List<string> ();
int componentCount = 0;
while ((line = input.ReadLine ()) != null) {
//Debug.LogError ("Read line " + line);
bracketRead = false;
inUpdate = inFunction ("Update(", "Update (", inUpdate, 0);
if ((inUpdate) && ((line.Contains ("gameObject.GetComponent")) || (line.Contains ("\tGetComponent")) || (line.Contains (" GetComponent")))) {
Debug.LogError ("String found");
Regex expression = new Regex (@"GetComponent<.*?>");
MatchCollection results = expression.Matches (line);
foreach (Match result in results) {
Debug.LogError (result);
string compName = result.Value.Substring (13, result.Value.Length - 14);
newVariables.Add (compName);
newInitializer.Add (compName + "Cache" + (newVariables.Count - 1).ToString () + "=GetComponent<" + compName + ">();");
//Debug.LogError (newVariables [newVariables.Count - 1]);
}
}
}
input.BaseStream.Seek (0L, SeekOrigin.Begin);
bracketCount = 0;
inUpdate = false;
inAwake = false;
inStart = false;
inClass = false;
written = false;
bracketRead = false;
writtenVars = false;
written = false;
while ((line = input.ReadLine ()) != null) {
//Debug.LogError ("Read line " + line);
bracketRead = false;
inUpdate = inFunction ("Update(", "Update (", inUpdate, 1);
inStart = inFunction ("Start(", "Start (", inStart, 1);
inAwake = inFunction ("Awake(", "Awake (", inAwake, 1);
inClass = inFunction ("class " + Path.GetFileNameWithoutExtension (AssetDatabase.GUIDToAssetPath (guid)), "class " + Path.GetFileNameWithoutExtension (AssetDatabase.GUIDToAssetPath (guid)), inClass, 0);
if ((inUpdate) && ((line.Contains ("gameObject.GetComponent")) || (line.Contains ("\tGetComponent")) || (line.Contains (" GetComponent")))) {
Debug.LogError ("String found");
Regex expression = new Regex (@"GetComponent<.*?>");
MatchCollection results = expression.Matches (line);
foreach (Match result in results) {
Debug.LogError (result);
string compName = result.Value.Substring (13, result.Value.Length - 14);
line = line.Replace ("GetComponent<" + compName + ">()", compName + "Cache" + componentCount);
line = line.Replace ("GetComponent<" + compName + "> ()", compName + "Cache" + componentCount);
componentCount++;
}
}
// Write the current line
output.Write (line);
output.WriteLine ();
if ((inClass) && (!writtenVars) && (bracketCount == 1)) {
output.WriteLine ();
int componentCount2 = 0;
foreach (string vars in newVariables) {
output.Write (vars + " " + vars + "Cache" + componentCount2 + ";");
output.WriteLine ();
componentCount2++;
}
output.WriteLine ();
writtenVars = true;
}
if ((inStart) && (!written) && (bracketCount == 2)) {
output.WriteLine ();
foreach (string vars in newInitializer) {
output.Write (vars);
output.WriteLine ();
}
output.WriteLine ();
written = true;
}
if ((inAwake) && (!written) && (bracketCount == 2)) {
output.WriteLine ();
foreach (string vars in newInitializer) {
output.Write (vars);
output.WriteLine ();
}
output.WriteLine ();
written = true;
}
}
output.Close ();
input.Close ();
if (written) {
File.Delete (AssetDatabase.GUIDToAssetPath (guid));
File.Move ("Assets/temp.txt", AssetDatabase.GUIDToAssetPath (guid));
} else {
File.Delete ("Assets/temp.txt");
}
}
}
}
static bool inFunction (string search1, string search2, bool testCondition, int braceMatch)
{
if ((line.Contains (search1)) || (line.Contains (search2))) {
testCondition = true;
if ((line.Contains ("{")) && (!bracketRead)) {
bracketRead = true;
bracketCount++;
}
Debug.LogError ("In Function " + search1);
Debug.LogError (bracketCount);
} else {
if (testCondition) {
if ((line.Contains ("{")) && (!bracketRead)) {
bracketRead = true;
bracketCount++;
Debug.LogError ("Open function " + bracketCount);
}
if ((line.Contains ("}")) && (!bracketRead)) {
bracketRead = true;
bracketCount--;
Debug.LogError ("Close function " + bracketCount);
}
if ((bracketCount == braceMatch)) {
testCondition = false;
Debug.LogError (bracketCount);
Debug.LogError ("Exit Function");
}
}
}
return(testCondition);
}
static void saveUndoFile (string path)
{
if (File.Exists (path + ".undo")) {
File.Delete (path + ".undo");
}
File.Copy (path, path + ".undo");
}
}