0
\$\begingroup\$

I have two classes. Both of them are placed in the editor/interface_field folder.

using System;
using UnityEngine;

namespace editor.interface_field
{
    public class RequiredInterfaceAttribute : PropertyAttribute
    {
        public readonly Type type;

        public RequiredInterfaceAttribute(Type type)
        {
            this.type = type;
        }
    }
}
    using UnityEditor;
    using UnityEngine;
    
    namespace editor.interface_field
    {
        [CustomPropertyDrawer(typeof(RequiredInterfaceAttribute))]
        public class RequireInterfaceDrawer : PropertyDrawer
        {
            public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
            {
                if(property.propertyType == SerializedPropertyType.ObjectReference)
                {
                    var requiredAttribute = this.attribute as RequiredInterfaceAttribute;
    
                    EditorGUI.BeginProperty(position, label, property);
    
                    property.objectReferenceValue =
                        EditorGUI.ObjectField(position, label, property.objectReferenceValue, requiredAttribute.type, true);
    
                    EditorGUI.EndProperty();
                }
                else
                {
                    var previousColor = GUI.color;
                    GUI.color = Color.red;
    
                    EditorGUI.LabelField(position, label, new GUIContent("Property is not a reference type"));
    
                    GUI.color = previousColor;
                }
            }
        }
    }

I have another class.

using editor.interface_field;
using UnityEngine;

namespace interface_user.implementations
{
    public interface IInterface {}
    public class InterfaceUser : MonoBehaviour
    {
        [SerializeField]
        [RequiredInterface(typeof(IInterface))]
        UnityEngine.Object interfaceImplementation;
    }
}

The [RequiredInterface(typeof(IInterface))] line throws the following error:

The type or namespace name 'RequiredInterfaceAttribute' could not be found (are you missing a using directive or an assembly reference?) [Assembly-CSharp]csharp(CS0246)

I can not understand why does not Unity see the RequiredInterfaceAttribute class and how could I make it see it.

\$\endgroup\$
3
  • \$\begingroup\$ Is your other class not in an editor folder? Your editor assemblies will not be visible from non-editor code. \$\endgroup\$ – DMGregory May 28 at 19:21
  • \$\begingroup\$ @DMGregory, I just figured it out. So, the best way to do it is to leave all the *Drawer classes in the editor folder and move the *Attribute classes to a separate (non-editor) folder and then reference the *Attribute classes from the *Drawer classes. This way everything is working. Should I remove my question? I mean yes, you are right the other classes are outside the editor folder. \$\endgroup\$ – qqqqqqq May 28 at 19:22
  • \$\begingroup\$ You can post your solution as an answer instead. \$\endgroup\$ – DMGregory May 28 at 19:23
0
\$\begingroup\$

So, as #DMGregory pointed out the classes inside the editor folder can not be referenced by classes outside of the editor folder. But the classes inside the editor folder can easily reference classes outside the editor folder. Given all that here is how I solved the issue.

I created a folder named game_editor and moved the RequiredInterfaceAttribute into it. Along the way I changed the namespace from the editor.interface_field.RequiredInterfaceAttribute to the game_editor.interface_field.RequiredInterfaceAttribute and added a respective using to the RequireInterfaceDrawer.

using UnityEditor;
using UnityEngine;
using game_editor.interface_field;

namespace editor.interface_field
{
    [CustomPropertyDrawer(typeof(RequiredInterfaceAttribute))]
    public class RequireInterfaceDrawer : PropertyDrawer
    {
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            if(property.propertyType == SerializedPropertyType.ObjectReference)
            {
                var requiredAttribute = this.attribute as RequiredInterfaceAttribute;

                EditorGUI.BeginProperty(position, label, property);

                property.objectReferenceValue =
                    EditorGUI.ObjectField(position, label, property.objectReferenceValue, requiredAttribute.type, true);

                EditorGUI.EndProperty();
            }
            else
            {
                var previousColor = GUI.color;
                GUI.color = Color.red;

                EditorGUI.LabelField(position, label, new GUIContent("Property is not a reference type"));

                GUI.color = previousColor;
            }
        }
    }
}
    using System;
    using UnityEngine;
    
    namespace game_editor.interface_field
    {
        public class RequiredInterfaceAttribute : PropertyAttribute
        {
            public readonly Type type;
    
            public RequiredInterfaceAttribute(Type type)
            {
                this.type = type;
            }
        }
    }
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.