Snippets
Revised by
Sam Gates
3562165
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 | using System;
using System.Collections.Generic;
using System.Reflection;
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: "Optimistic_Unicorn"
/// </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 = fields[i].Name.Replace('_',' ');
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 = fields[i].Name.Replace('_', ' ');
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 = fields[i].Name.Replace('_', ' ');
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 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.