x


How can I create a custom import object?

I would like to create my own file format, which is text based, which is imported by the editor and then made available to the runtime player as an prefab object.

I other words, I would like to mimic what happens with fbx. The editor reads it, shows any editable properties in the project window, it becomes part of the build, and then the player can instantiate a copy of it at runtime.

Is it reasonable to think I can do this with the current C# API?

I know I can load a txt extension as a TextAsset, and then process it at runtime. But I'm burning cycles at runtime and I would rather the importer did most of the processing.

more ▼

asked May 21, 2010 at 09:48 PM

Brian 4 gravatar image

Brian 4
245 20 17 22

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

4 answers: sort voted first

I know this is kind of old, but it really bugs me that the only answers here are to use TextAssets which you then parse at runtime.

The correct answer is to create an AssetPostprocessor and override the OnPostprocessAllAssets method. Like so:

using UnityEngine;
using UnityEditor;
public class CustomPostprocessor : AssetPostprocessor
{
    /// <summary>
    /// Handles when ANY asset is imported, deleted, or moved.  Each parameter is the full path of the asset, including filename and extension.
    /// </summary>
    /// <param name="importedAssets">The array of assets that were imported.</param>
    /// <param name="deletedAssets">The array of assets that were deleted.</param>
    /// <param name="movedAssets">The array of assets that were moved.  These are the new file paths.</param>
    /// <param name="movedFromPath">The array of assets that were moved.  These are the old file paths.</param>
    private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromPath)
    {
        foreach(string asset in importedAssets)
        {
            Debug.Log("Imported: " + asset);
        }

        foreach (string asset in deletedAssets)
        {
            Debug.Log("Deleted: " + asset);
        }

        for (int i = 0; i < movedAssets.Length; i++ )
        {
            Debug.Log("Moved: from " + movedFromPath[i] + " to " + movedAssets[i]);
        }
    }
}

Then you can use the standard Mono libraries to parse the files and do whatever you want in Unity.

more ▼

answered Dec 06, 2010 at 06:48 PM

GlitchEnzo2 gravatar image

GlitchEnzo2
333 7 8 20

Do you have an example of the code that actually imports something in OnPostprocessAllAssets()? I'm trying to create a GameObject and save it as asset with AssetDatabase.CreateAsset(go,path+".asset"); but the result seems broken somehow (unity crashes eventually). Also, the GameObject immediately appears in the current scene, which is not my intention...

Dec 29, 2010 at 07:12 PM femi

After some more research: is is possible to process custom files in OnPostprocessAllAssets() and create assets but impossible to create prefabs with hierarchy of game objects. That's because it's impossible to create a GameObject suitable for storing in a prefab (like OnPostprocessModel() receives) on your own.

Dec 30, 2010 at 10:00 AM femi
(comments are locked)
10|3000 characters needed characters left

I have never tried this, but you could give this a shot: Make your file be imported as a textfile. Write an AssetPostProcessor, and in that do the parsing of the text, create a bunch of new objects (texture2d, material, custom scriptableobjects, AnimationClips, whatever), and use AssetDatabase.AddObjectToAsset() to add it to the just imported file.

Again, I'm not 100% sure this will work, but it's a good first shot. Please be aware that Unity2.6.1 has a bug that makes a textasset being read as binary be garbled, so use an actual textformat, and not a binary one. I fixed this for Unity3.

more ▼

answered May 22, 2010 at 10:31 PM

Lucas Meijer 1 gravatar image

Lucas Meijer 1 ♦♦
8.9k 29 55 101

Thanks for the suggestion. It gave me an error that the asset is not persistent.

OnPostprocessModel is almost working. When I get this event for the FBX import, I load the associated text file. I can then create additional GameObjects...

GameObject newgo = new GameObject( name ); newgo.transform.parent = go.transform;

I then create a mesh based on the text file...

Mesh mesh = new Mesh(); ...populate mesh... newgo.AddComponent< MeshFilter >().sharedMesh = mesh;

At runtime, I see the new GameObject with a MeshFilter, but the mesh is missing. Any ideas what is wrong?

May 23, 2010 at 07:55 PM Brian 4
(comments are locked)
10|3000 characters needed characters left

You can't create your own file formats that Unity imports, as far as I know. Sure, you can stick whatever files you want inside your Assets folder, and you could MAYBE write an editor script to have a custom Inspector for those files, but that's unreasonable. Here's what you can do that should be relatively easy:

  • Create an empty game object.
  • Create a script.
  • Create a TextAsset object (something like: public TextAsset myTextFile;)
  • Apply the script to the empty game object.
  • Drag the text file from your Unity Assets into your script, so the script has a reference to it.
  • Create a prefab in your assets, and drag the game object with the script on it, into the prefab slot.

Now, in that script, you'll have your text file with all its data in it. You can read how to get the data of the text file by checking out the TextAsset documentation.

more ▼

answered May 21, 2010 at 10:15 PM

qJake gravatar image

qJake
12.6k 91 121 200

Yeah, right now I'm basically doing that. But it means that all the parsing is happening at runtime, which is slow.

I would rather have the editor parse the file during import and create an object that I can then include with the build and instantiate as needed.

The documentation seems to elude to having classes that will do this, but it isn't very clear.

May 22, 2010 at 02:54 AM Brian 4

Parsing a file shouldn't take that long. Try timing it to see how fast it actually goes. You could also just parse it in Start() or Awake(), which is where most of your "slow code" should go anyway. You can then store references to your created objects and just pass them around as needed (which is extremely fast and efficient).

May 22, 2010 at 07:45 AM qJake

Would it be possible to run the script to parse the text file once, and save the resulting GameObjects while the editor is running the game? That way, once you stop the editor running the engine you still have your generated GameObjects that you can include with the build, and remove your TextAsset and generator script?

Apr 13, 2013 at 10:34 PM p_025
(comments are locked)
10|3000 characters needed characters left

Hi! I would like to import my own formats, too. These are to then emerge also in the Project folder and also the characteristics them have to point out. For example Xpresso tags or simply only dependence of each other. I have already tried with the function AssetDatabase.AddObjectToAsset () to get ahead. however unsuccessfully. Can someone help me? Thanks a lot.

more ▼

answered Jun 01, 2011 at 12:31 PM

hunn3s gravatar image

hunn3s
1 3 2 2

(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:

x657
x279
x40

asked: May 21, 2010 at 09:48 PM

Seen: 8015 times

Last Updated: Apr 13, 2013 at 10:34 PM