0
\$\begingroup\$

I've created a script which helps me auto-generate a GameObject prefab. It uses some UnityEditor, so it can't be used at runtime (and its not meant to be).

Normally, a script like this I would put in the "Editor" folder.

However, since it needs to be attached to a GameObject as a Component to do its thing, I'm not sure where I should put it. I can't store it in the Editor folder, because Unity yells at me and says I'm not allowed.

Are there any best practices defined for things like this?

\$\endgroup\$
1
\$\begingroup\$

You could use Platform dependent compilation blocks in your scripts, so certain parts would be compiled just if they are in a specific platform. Example:

using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif

public class PrefabCreatorExample : MonoBehaviour
{
    public string path;

    private void Start()
    {
#if UNITY_EDITOR
        PrefabUtility.CreatePrefab(path, GenerateObject());
#endif
    }

    private GameObject GenerateObject()
    {
        GameObject newObject = new GameObject();

        // Your creation logic here...

        return newObject;
    }
}

I use this a lot to write Gizmos' attributes for the Editor without generating unnecessary data types on the final build.

You could also use Inspector classes that will only be compiled on Editor mode, this scrips must be on Editor's folder of course. With this solution you separate the Game's functionality from the Editor's (on this case, I have created the PrefabUtilities MonoBehaviour class). Example:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(PrefabUtilities))]
public class PrefabUtilitiesInspector : Editor
{
    private PrefabUtilities prefabUtilities;    /// <summary>Inspector's Target.</summary>

    /// <summary>Sets target property.</summary>
    void OnEnable()
    {
        prefabUtilities = target as PrefabUtilities;
    }

    /// <summary>OnInspectorGUI override.</summary>
    public override void OnInspectorGUI()
    {   
        DrawDefaultInspector();
        if(GUILayout.Button("Substitute with Prefab.")) prefabUtilities.SubstituteGameObjectsForPrefab();
    }
}

This would draw a button on the inspector, but you can also do the Editor's exclusive logic there.

enter image description here

Hope it helps.

\$\endgroup\$
  • \$\begingroup\$ Thanks, this is more or less what I'm doing now. The thing that makes it a bit odd though is that the entire file is only for UnityEditor. The entire script gets removed from the GameObject once it's built. I'll probably just keep it like this and put it in some folder that isn't named Editor, but named something that makes it obvious it isn't for runtime code. \$\endgroup\$ – samanime May 2 '18 at 14:05
1
\$\begingroup\$

Myself I'll usually just wrap the whole file in a preprocessor conditional directive block like this:

#if UNITY_EDITOR
using UnityEditor;

public class Foo : MonoBehaviour {
    // All contents here...
}

#endif

That way when I compile a build, the compiler sees the file as effectively empty and skips over it, even if it's not sitting in an Editor folder.

\$\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.