Snippets
Revised by
Sam Gates
30c9bf2
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 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text.RegularExpressions;
using UnityEngine;
using UnityEditor;
using UnityEngine.SceneManagement;
namespace Helios.Otto
{
//add me to an Editor folder
public class Otto
{
/// <summary>
/// Loops through all public fields on the target mono behaviour and searches for a relevant asset in the asset database
/// Separate your search terms with an underscore, and being as specific as possible with your variable names helps Otto to find the right assets
/// Example: "Optimistic Unicorn.mp4" can be found with variable names "Optimistic", "Unicorn", or best of all: "OptimisticUnicorn"
/// </summary>
[MenuItem("CONTEXT/MonoBehaviour/Auto Populate - All")]
static void AutoPopulateAll(MenuCommand command)
{
Debug.Log("[Otto]: Auto populating variables");
var type = command.context.GetType();
Debug.Log($"[Otto]: Doing a kickflip over the {type.Name}");
var fields = type.GetFields();
var fieldsSet = 0;
for (int i = 0; i < fields.Length; i++)
{
var assetName = ParseName(fields[i].Name);
if (SearchAssets(command.context, assetName, fields[i]))
{
fieldsSet++;
continue;
}
if (SearchScene(command.context, assetName, fields[i])) fieldsSet++;
}
Debug.Log($"[Otto]: All done! I set {fieldsSet} fields");
}
[MenuItem("CONTEXT/MonoBehaviour/Auto Populate - Assets")]
static void AutoPopulateAssets(MenuCommand command)
{
Debug.Log("[Otto]: Auto populating variables");
var type = command.context.GetType();
Debug.Log($"[Otto]: Doing a kickflip over the {type.Name}");
var fields = type.GetFields();
var fieldsSet = 0;
for (int i = 0; i < fields.Length; i++)
{
var assetName = ParseName(fields[i].Name);
if (SearchAssets(command.context, assetName, fields[i])) fieldsSet++;
}
Debug.Log($"[Otto]: All done! I set {fieldsSet} fields");
}
[MenuItem("CONTEXT/MonoBehaviour/Auto Populate - Scene")]
static void AutoPopulateScene(MenuCommand command)
{
Debug.Log("[Otto]: Auto populating variables");
var type = command.context.GetType();
Debug.Log($"[Otto]: Doing a kickflip over the {type.Name}");
var fields = type.GetFields();
var fieldsSet = 0;
for (int i = 0; i < fields.Length; i++)
{
var assetName = ParseName(fields[i].Name);
if (SearchScene(command.context, assetName, fields[i])) fieldsSet++;
}
Debug.Log($"[Otto]: All done! I set {fieldsSet} fields");
}
static bool SearchAssets(UnityEngine.Object target, string search, FieldInfo field)
{
var asset = AssetDatabase.FindAssets(search);
if (asset.Length > 0)
{
var assetPath = AssetDatabase.GUIDToAssetPath(asset[0]);
var loadedAsset = AssetDatabase.LoadAssetAtPath(assetPath, field.FieldType);
if (loadedAsset != null)
{
Undo.RecordObject(target, $"Set field {field.Name}");
field.SetValue(target, loadedAsset);
return true;
}
}
return false;
}
static bool SearchScene(UnityEngine.Object target, string search, FieldInfo field)
{
//if we can't even find the obejct type in the scene, why search for it?
//i.e. you won't find a float or audio clip in the scene!
if (TypeNotSceneCompatible(field.FieldType)) return false;
List<GameObject> obj = new List<GameObject>();
SceneManager.GetActiveScene().GetRootGameObjects(obj);
var rootObj = new List<GameObject>(obj);
foreach (GameObject o in rootObj)
{
for (int childIndex = 0; childIndex < o.transform.childCount; childIndex++)
{
var t = o.transform.GetChild(childIndex);
if (!obj.Contains(t.gameObject)) obj.Add(t.gameObject);
}
}
object targetObject = obj.Find(x => x.name.Contains(search));
if (!field.FieldType.Name.Contains("GameObject"))
{
targetObject = ((GameObject)targetObject)?.GetComponent(field.FieldType);
}
if (targetObject != null)
{
Undo.RecordObject(target, $"Set field {field.Name}");
field.SetValue(target, targetObject);
return true;
}
return false;
}
static string ParseName(string name)
{
var parsedName = String.Join(" ", Regex.Split(name, @"(?<!^)(?=[A-Z])"));
return parsedName.Replace('_', ' ');
}
static bool TypeNotSceneCompatible(Type type)
{
return (!type.IsSubclassOf(typeof(MonoBehaviour)) && !type.IsSubclassOf(typeof(Behaviour)) && type.Name != "GameObject");
}
}
}
|
You can clone a snippet to your computer for local editing. Learn more.