AutoAssign Attribute & PropertyDrawer

October 6, 2016

Everyone working with a big team in Unity knows that if a script is finished the work is not.

So in our small team there where several situations where I would code something and let Properties [Serializable] or [public] so that the gamedesigners could change targets or other settings.

I guess flexibility and safety are the keyword here. So I thought: “ok there should be an easy and reusable solution”!

Here you go:

AutoAssignAttribute

This Custom Attribute and PropertyDrawer show the gamedesigners that the script will take its references automatically, but the designer can still change it manually if he needs it! Init your Properties in Start() or Awake() with an if(prop == null) statement. 😉

The code is below feel free to use it, GNU licence. 🙂

PropertyDrawer

/*********************
* Copyright (c) 2015, Rudolf Chrispens.  All rights reserved.
* found on http://www.rudolf-chrispens.de/posts/
* Copyrights licensed under the GNU License.
* https://www.gnu.org/licenses/gpl-3.0
***********************/

#region USE
using UnityEngine;
using UnityEditor;
#endregion

[CustomPropertyDrawer(typeof(AutoAssignAttribute))]
[SerializeField]
public class AutoAssignDrawer : PropertyDrawer
{
    float buttonWidth   = 70f;
    AutoAssignAttribute autoAssignAttribute = null;

    float infoButtonWidth = 20f;
    Color customColor = new Color(0.639215f, 0.96078f, 1.0f);
    Color storedBGColor = GUI.backgroundColor;

    public override void OnGUI(Rect _Position, SerializedProperty _Property, GUIContent _Label)
    {
        //button width
        EditorGUIUtility.labelWidth = EditorGUIUtility.labelWidth - buttonWidth;

        //get attribute
        autoAssignAttribute = (AutoAssignAttribute)base.attribute;

        GUI.backgroundColor = customColor;

        Rect pos1 = new Rect (_Position.x, _Position.y, buttonWidth, _Position.height);
        Rect pos2 = new Rect (_Position.x + buttonWidth, _Position.y, _Position.width - buttonWidth - infoButtonWidth, _Position.height);

        if (autoAssignAttribute.Auto && _Property.objectReferenceValue == null)
        {
            //Custom Auto Button
            //default assignable property
            if(GUI.Button(pos1, "Auto"))
            {
                autoAssignAttribute.Auto = false;
            }

            string propType = _Property.type.Remove(0, 5);
            EditorGUI.LabelField(pos2, _Property.displayName, propType.Remove(propType.Length-1));
        }
        else
        {
            //default assignable property
            if (GUI.Button(pos1, "Manual"))
            {
                autoAssignAttribute.Auto = true;
                _Property.objectReferenceValue = null;
            }
            EditorGUI.PropertyField(pos2, _Property);
        }

        //info button
        if (GUI.Button(new Rect(_Position.x + _Position.width - infoButtonWidth, _Position.y, infoButtonWidth, _Position.height), "i"))
        {
            if (autoAssignAttribute.Auto)
            {
                Debug.Log("This property will be set automatically on initialization.\nBut you can force a custom assignment.");
            }
            else
            {
                Debug.Log("This property is set manually to a referenced object.\nBut you can switch back to automatic initialization.");
            }
        }

        GUI.backgroundColor = storedBGColor;
    }
}

Attribute

#region USE
using UnityEngine;
using System;
#endregion

[AttributeUsage(AttributeTargets.Field, Inherited = true, AllowMultiple = false)]
public class AutoAssignAttribute : PropertyAttribute
{
    private bool auto = true;

    public bool Auto
    {
        get { return auto; }
        set { auto = value; }
    }
}

Using this Attribute is easy:

[AutoAssign]
 public Transform MyTransform = null;
 [AutoAssign]
 public GameObject MyGameObject = null;
 [AutoAssign]
 public MonoBehaviour MyBehaviour = null;

 

UPDATE 1.01:

Changed the color of my custom property drawers. And I will add a info button to all of my drawers. Got this idea from @Kalladystine thanks for your review!

AutoAssign_1_1

With the “i” button you will get some information about the drawer.

AutoAssign_1_1_log