x


Inspector Field for Scene Asset

Pretty straightforward question: is there a way to create an inspector field for either a Scene asset or an array of Scene assets?

I'm trying to create a custom editor window that allows our designers to easily modify our level packs and the levels in them. It would be ideal if, rather than having to add scenes manually to the Build Settings list, I could provide an inspector field to slot in a Scene (.unity3d) asset. This way, I could throw warnings when a level isn't assigned a scene file, and ensure that all the scenes needed for the game are included when we do a build.

So far, this seems much harder than necessary because I can't find an appropriate asset type that corresponds to the scene asset type.

Thanks!

more ▼

asked Apr 20 '12 at 11:33 PM

kromenak gravatar image

kromenak
1.6k 23 29 41

(comments are locked)
10|3000 characters needed characters left

2 answers: sort voted first

Found a workable solution through experimentation, thought I would share:

There is no class exposed in Unity's API to create an inspector reference to a Scene, but it turns out that a Scene does inherit from Object, so it is possible to have an Object reference and then slot in a Scene asset:

public Object[] mySceneAssets;

The only problem with this solution is that you can't really enforce that the list contain only Scene objects at compile time; there is nothing stopping someone on the team from inserting a reference to some other asset entirely. Still, it is better than nothing, and you can do some runtime checks to make sure it works.

With the scene asset reference, you can use the AssetDatabase object to get path information, and manually add the scene data to the build settings list of scenes.

List<EditorBuilderSettingsScene> scenes = new List<EditorBuilderSettingsScene>();

//have some sort of for loop to cycle through scenes...
string pathToScene = AssetDatabase.GetAssetPath(mySceneAssets[i]);
EditorBuildSettingsScene scene = new EditorBuildSettingsScene(pathToScene, true);
scenes.Add(scene);

//later on...
EditorBuildSettings.scenes = scenes.ToArray();
more ▼

answered Apr 24 '12 at 05:18 PM

kromenak gravatar image

kromenak
1.6k 23 29 41

(comments are locked)
10|3000 characters needed characters left

I'm assuming you could make a script or such and have a public variable so it can be assigned in the editor window. I am unsure ifna similar thing applies to asset packages.

more ▼

answered Apr 20 '12 at 11:39 PM

1337GameDev gravatar image

1337GameDev
526 43 49 54

I would also assume this, but I'm having trouble finding the class to use in this instance.

To make a transform field, I use a "public Transform myTransform;" field.

To make an AudioClip field, I use a "public AudioClip myClip;" field.

To make a scene file field, I have no idea what class I should be using to create the inspector field. I'm fearing that there is no such class exposed.

Apr 20 '12 at 11:56 PM kromenak

I am also looking for the answer to this. Are there any updates on this. And a related question. If Application.LoadLevel("aLevel") does not take any paths, how does it avoid name clashes if you have levels with the same name in different folders?

thanks

Mar 11 at 05:32 PM fwalker

It is stated above that scenes inherit from Object. You could try using this in a public variable.

For the scene name problem, unity might grab the first name it finds (or random) so avoid sharing names of scenes. It's similar to Java's arraylist object and the find method. It returns the first occurrence. If the arraylist is unwonted you don't know which is returned. Same principle here. Just name them differently, and come up with a naming convention for your scene assets.

Mar 11 at 06:59 PM 1337GameDev

Thanks GameDev. I get the part about using an Object. But then how in the world do I load that object as a scene at runtime?. I can use Application.LoadLevel() which takes a string. And the only way I see of getting the LevelName from the Object is to call AssetDatabase.GetAssetPath which is an Editor class. So it will not work at runtime. This can't possibly be this hard :(

Mar 11 at 07:35 PM fwalker

You can probably achieve what you're looking for by creating a custom inspector. In the custom inspector, you can trim and save the scene names for use at runtime. For example, something like this seems to work:

using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(YourClass))]
public class YourCustomInspector : Editor 
{
        public override void OnInspectorGUI()
    {
       DrawDefaultInspector();

       YourClass comp = (YourClass)target;
       if(comp != null)
       {
         if(comp.scenes.Length > 0)
         {
          comp.sceneNames = new string[comp.scenes.Length];
          for(int i = 0; i < comp.scenes.Length; i++)
          {
              string scenePath = AssetDatabase.GetAssetPath(comp.scenes[i]);
              scenePath = scenePath.Substring(scenePath.LastIndexOf('/') + 1);
              scenePath = scenePath.Substring(0, scenePath.LastIndexOf('.'));

              comp.sceneNames[i] = scenePath;
          }
         }
       }
    }
}

Since this editor class creates an array of scene names for you, you can then use those scene names at runtime to load the scenes. I think this is kind of a dumb solution, but I don't see a better way to do it, unfortunately :-\

Mar 15 at 05:14 AM kromenak
(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x717
x466
x32

asked: Apr 20 '12 at 11:33 PM

Seen: 980 times

Last Updated: Mar 15 at 05:14 AM