Snippets
Created by
Sam Gates
last modified
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 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text.RegularExpressions;
using UnityEngine;
using UnityEditor;
using UnityEngine.SceneManagement;
using System.Linq;
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;
List<GameObject> sceneObjects = GetSceneObejcts();
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], sceneObjects)) 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;
List<GameObject> sceneObjects = GetSceneObejcts();
for (int i = 0; i < fields.Length; i++)
{
var assetName = ParseName(fields[i].Name);
if (SearchScene(command.context, assetName, fields[i], sceneObjects)) 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, List<GameObject> obj)
{
//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;
}
object targetObject = obj.Find(x =>
{
var s = search.Split(' ');
return s.All(x.name.Contains);
});
if (!field.FieldType.Name.Contains("GameObject"))
{
if (field.FieldType.Name.Contains("UnityEngine.Transform")) targetObject = ((GameObject)targetObject).transform;
else 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 List<GameObject> GetSceneObejcts()
{
List<GameObject> obj = new List<GameObject>();
SceneManager.GetActiveScene().GetRootGameObjects(obj);
var rootObj = new List<GameObject>(obj);
foreach (GameObject o in rootObj)
{
GetChildren(ref obj, o.transform);
}
return obj;
}
static void GetChildren(ref List<GameObject> l, Transform t)
{
if (!l.Contains(t.gameObject)) l.Add(t.gameObject);
for (int childIndex = 0; childIndex < t.childCount; childIndex++)
{
var child = t.GetChild(childIndex);
if (!l.Contains(child.gameObject))
{
l.Add(child.gameObject);
}
if (child.childCount > 0)
{
var r = new List<GameObject>();
GetChildren(ref r, child);
foreach (GameObject g in r) if (!l.Contains(g)) l.Add(g);
}
}
}
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" && !type.Name.Contains("Transform"));
}
}
}
|
Comments (1)
You can clone a snippet to your computer for local editing. Learn more.
1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 61 63 65 67 69 71 73 75 77 79 81 83 85 87 89 91 93 95 97 99 101 103 105 107 109 111 113 115 117 119 121 123 125 127 129 131 133 135 137 139 141 143 145 147 149 151 153 155 157 159 161 163 165 167 169 171 173 175 177 179 181 183 185 187 189 191 193 195 197 199 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 61 63 65 67 69 71 73 75 77 79 81 83 85 87 89 91 93 95 97 99 101 103 105 107 109 111 113 115 117 119 121 123 125 127 129 131 133 135 137 139 141 143 145 147 149 151 153 155 157 159 161 163 165 167 169 171 173 175 177 179 181 183 185 187 189 191 193 195 197 199 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 61 63 65 67 69 71 73 75 77 79 81 83 85 87 89 91 93 95 97 99 101 103 105 107 109 111 113 115 117 119 121 123 125 127 129 131 133 135 137 139 141 143 145 147 149 151 153 155 157 159 161 163 165 167 169 171 173 175 177 179 181 183 185 187 189 191 193 195 197 199