Last active
October 26, 2020 04:03
-
-
Save AsherVo/5ee0cdc5f2696fe2d528070f23562394 to your computer and use it in GitHub Desktop.
Using unity's standard ObjectField in RequireReferenceDrawer to fix bugs and improve prefab workflow.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// PLEASE NOTE: This will add ~1sec to your save time | |
// If that is unacceptable (which it was to me), then you can change all the | |
// references to "MonoBehaviour" in this file to your own custom behaviour type | |
// that this script will search through each time you save | |
using UnityEditor; | |
using UnityEngine; | |
using System.Linq; | |
using System.Reflection; | |
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEditor.Experimental.SceneManagement; | |
public class RequireReferenceAlert : UnityEditor.AssetModificationProcessor | |
{ | |
static string[] OnWillSaveAssets(string[] paths) | |
{ | |
bool doValidate = false; | |
foreach ( string path in paths ) | |
{ | |
if ( path.Contains( ".prefab" ) || path.Contains( ".scene" ) ) | |
{ | |
doValidate = true; | |
break; | |
} | |
} | |
if ( !doValidate ) | |
return paths; | |
MonoBehaviour[] allBehaviours; | |
PrefabStage stage = PrefabStageUtility.GetCurrentPrefabStage(); | |
if ( stage != null ) | |
{ | |
List< MonoBehaviour > foundBehaviours = new List< MonoBehaviour >(); | |
GameObject[] rootObjects = stage.scene.GetRootGameObjects(); | |
foreach ( GameObject rootObj in rootObjects ) | |
foundBehaviours.AddRange( rootObj.GetComponentsInChildren< MonoBehaviour >( true ) ); | |
allBehaviours = foundBehaviours.ToArray(); | |
} | |
else | |
{ | |
allBehaviours = Object.FindObjectsOfType< MonoBehaviour >(); | |
} | |
foreach ( MonoBehaviour b in allBehaviours ) | |
{ | |
FieldInfo[] fields = b.GetType().GetFields(); | |
foreach ( FieldInfo field in fields ) | |
{ | |
object[] attrs = field.GetCustomAttributes( true ); | |
foreach ( object attr in attrs ) | |
{ | |
if ( attr is RequireReferenceAttribute ) | |
{ | |
object obj = field.GetValue( b ) as object; | |
if ( obj is IEnumerable && obj.GetType().IsGenericType ) | |
{ | |
IEnumerable listObj = obj as IEnumerable; | |
foreach ( Object o in listObj ) | |
{ | |
if ( IsNullShowWarning( o, b.ToString(), b) ) | |
return new string[ 0 ]; | |
} | |
} | |
else | |
{ | |
if ( IsNullShowWarning( obj, b.ToString(), b ) ) | |
return new string[ 0 ]; | |
} | |
break; | |
} | |
} | |
} | |
} | |
return paths; | |
} | |
static bool IsNullShowWarning ( object obj, string name, Object selectObject ) | |
{ | |
if ( obj == null ) | |
{ | |
Selection.activeObject = selectObject; | |
return !EditorUtility.DisplayDialog( | |
"Missing References", | |
$"The following component is missing some required references: {name}", | |
"Save Anyway", | |
"Cancel" | |
); | |
} | |
return false; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class RequireReferenceAttribute : PropertyAttribute | |
{ | |
public RequireReferenceAttribute () | |
{ | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEditor; | |
using UnityEngine; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Text.RegularExpressions; | |
[CustomPropertyDrawer(typeof(RequireReferenceAttribute))] | |
public class RequireReferenceDrawer : PropertyDrawer | |
{ | |
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) | |
{ | |
EditorGUI.BeginProperty(position, label, property); | |
EditorGUI.ObjectField( position, property ); | |
if ( property.objectReferenceValue == null ) | |
{ | |
EditorGUI.DrawRect( position, new Color( 1.0f, 0.0f, 0.0f, 0.5f ) ); | |
} | |
EditorGUI.EndProperty(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment