Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 11 Next capture
2021 2022 2023
1 capture
11 Jun 22 - 11 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by Jaap Kreijkamp · Jan 16, 2010 at 11:10 AM · editorassetdatabase

Determining which Asset is connected to a GameObject.

I'm trying to write an editor script that sort of exports a Scene. For this it has to find out which asset a GameObject is created from. Is there a way to do this?

To explain a little bit more, let's say I've got a Prefab Assets/environment/barrel.prefab, I drop this to the Scene so the scene has a GameObject barrel. Now the script should be run over all GameObjects and if a GameObject is a prefab tell which prefab it is, thus in this example print something like:

barrel: Assets/environment/barrel.prefab

Why do I want this? My designer uses Unity Basic and we're making an iPhone game, for this I regularly have to import about 30 scenes to Unity iPhone. However the importer is so broken that about 10 scenes are messed up and only crashes Unity. Of course I filed several bug reports but this doesn't solve the problem for me. I already spend several days in time to fix scenes again and again to have them broken on next import again. As basically almost all the gameobjects in the scene are prefabs positioned I would think it shouldn't be too hard to make an exporter for this myself. Except I have to map the GameObjects to the assets somehow. I could try to determine it by the name of the GameObject as this normally matches the asset name, but this doesn't sound foolproof. That's why I'm hoping to get an answer here :-)

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

3 Replies

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by Lucas Meijer 1 · Jan 16, 2010 at 01:16 PM

Not sure what kind of assets you refer to, but you say you want to find out in which file a certain material lives that a MeshRenderer component on your GameObject uses, you could do:

Material m = myGameObject.renderer.material;
string AssetDatabase.GetAssetPath();

which will return something like "Assets/MyMaterials/RedSmokingHot.mat"

For GameObject, there's an additional step required. When you drag a prefab into your scene, copies of the gameobjects in the prefab will be created, and stored in the scene. These copies actually "remember" which gameobjects they were created from. Using GetAssetAtPath() on these copies won't give you anything, since these live in a scene. You can use EditorUtility.GetPrefabParent() to get the prefab-gameobject your scene-gameobject was created from. You can then call GetAssetPath() on that gameobject, which should result in something like "Assets/building.prefab"

Not all UnityEngine.Object types have an assetpath. Some live in a scenefile, others are generated at runtime, and are not saved anywhere. Some live in the assets folder in some way. i.e. Material live in .mat files, gameObjects live in .prefab files, etc.

PS For the adventurous, all these .mat and .prefab files are actually just generic containers for UnityEngine.Object's. These files can host more than one UnityEngine.Object, in fact you can do crazy stuff like add a gameobject to a materialfile using AssetDatabase.AddObjectToAsset()

Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Jaap Kreijkamp · Jan 17, 2010 at 02:15 AM 0
Share

Thanks for your answer but it doesn't work for GameObjects. I'll extend the description to make it clearer what I'm looking for.

avatar image Lucas Meijer 1 ♦♦ · Jan 18, 2010 at 08:44 AM 0
Share

Thanks, I extended my answer to explain how to achieve the same for gameobjects. Could you be so kind to post the case#'s of the bugs you logged against the editor crashing for you here? thnx.

avatar image Jaap Kreijkamp · Jan 18, 2010 at 11:56 PM 0
Share

Wow, it works! I used GetAssetPath before on all gameobjects in scene but that didn't work, but with the GetPrefabParent I do get results! Thanks, this is a lot better than my hack-around...

avatar image Jaap Kreijkamp · Jan 19, 2010 at 12:18 AM 0
Share

Case 312962 is the latest bug submission, have a few earlier case numbers but they are a bit double posts as the submitter app failed to post the project (is there a limit of 100$$anonymous$$B on a submitted zipfile?).

avatar image Alex-Chouls · Sep 25, 2010 at 09:37 PM 0
Share

AddObjectToAsset() is very useful. I'm using it to save nested ScriptableObjects and it keeps the objects all nicely bundled in one file. But I have a question: Is there a RemoveObjectFromAsset? Or would I need to rebuild the asset from scratch without the object I want to remove?

Show more comments
avatar image
1

Answer by Jessy · Jan 16, 2010 at 11:44 AM

I never got an answer. I don't think so.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Jaap Kreijkamp · Jan 16, 2010 at 12:11 PM 0
Share

Would be an amazing miss in the API. I searched through the editor classes and couldn't really find anything of use but can't believe there isn't something there.

avatar image
0

Answer by Jaap Kreijkamp · Jan 18, 2010 at 12:32 AM

It seems it's just not possible at the moment, at least not through a public API function. For now I hacked a solution using the names of the GameObjects (they normally matches the names of the prefabs). For people interested I added the code below. It doesn't export everything, basically only prefabs and their parent gameobjects with their default values. The prefabs are only searched in the directories specified with the paths variable. Code isn't efficient, clearly written or documented, it just does what it needs to do for me.

using UnityEngine; using UnityEditor; using System.Collections; using System.IO;

public class JSimpleExporter { static Hashtable parents = new Hashtable(); static Hashtable prefabs = new Hashtable(); static string[] paths = new string[] { "JaapPrefabs/Environment", "JaapPrefabs/Effects/Environment", "JaapPrefabs/Enemies", "Levels" };

 public static Transform FindPrefab(string name) {
     Transform result = (Transform)prefabs[name];
     if (result == null) {
         foreach (string path in paths) {
             Object objref = AssetDatabase.LoadAssetAtPath("Assets/" + path + "/" + name + ".prefab", typeof(Transform));
             if (objref != null) {
                 prefabs.Add(name, objref);
                 result = (Transform) objref;
                 return result;
             }
         }
     }
     return result;
 }

 private static StreamWriter wrt;

 static void Write(string str) {
     wrt.WriteLine(str);
 }

 static string TransformStr(Transform t) {
     Vector3 pos = t.position;
     Vector3 rot = t.rotation.eulerAngles;
     Vector3 scale = t.localScale;
     return "" + pos.x + "," + pos.y + "," + pos.z + "," + rot.x + "," + rot.y + "," + rot.z + "," + scale.x + "," + scale.y + "," + scale.z;
 }

 static string GetPath(Transform t, bool isPrefab) {
     if (t == null) return "";
     if (parents[t] != null) return (string)parents[t];
     string p = GetPath(t.parent, false);
     p = p + "/" + t.name;
     parents.Add(t, p);
     if (!isPrefab) {
         Write("#" + p + "," + TransformStr(t));
     }
     return p;
 }

 [MenuItem("Ctrl-J/MyExport")]
 static void MyExport() {
     FileInfo f = new FileInfo("Assets/export.txt");
     wrt = f.CreateText();
     parents = new Hashtable();
     GameObject[] result = Object.FindObjectsOfType(typeof(GameObject)) as GameObject[];
     foreach (GameObject go in result) {
         Transform t = FindPrefab(go.name);
         if (t != null) {
             string path = GetPath(go.transform, true);
             Write("@" + path + "," + AssetDatabase.GetAssetPath(t) + "," + TransformStr(t));
         }
     }
     wrt.Close();
     AssetDatabase.ImportAsset("Assets/export.txt");
 }

 static Transform GetParentChild(string path, out string childName) {
     int p = path.LastIndexOf('/');
     string p2 = path.Substring(0, p);
     childName = path.Substring(p + 1);
     GameObject go = GameObject.Find(p2);
     if (go != null) {
         return go.transform;
     }
     return null;
 }

 static string GetParam(ref string path) {
     int delim = path.IndexOf(',');
     if (delim < 0) {
         string result = path;
         path = "";
         return result;
     }
     string result2 = path.Substring(0, delim);
     path = path.Substring(delim + 1);
     return result2;
 }

 static Vector3 GetVector3(ref string path) {
     string p0 = GetParam(ref path);
     string p1 = GetParam(ref path);
     string p2 = GetParam(ref path);
     return new Vector3(float.Parse(p0), float.Parse(p1), float.Parse(p2));
 }

 [MenuItem("Ctrl-J/MyImport")]
 static void MyImport() {
     FileInfo f = new FileInfo("Assets/export.txt");
     if (f.Exists) {
         StreamReader r = f.OpenText();
         bool ready = false;
         while (!ready) {
             string l = r.ReadLine();
             if (l == null) {
                 ready = true;
             }
             else if (l.StartsWith("#")) {
                 l = l.Substring(1);
                 string path = GetParam(ref l);
                 string name;
                 Transform parent = GetParentChild(path, out name);
                 GameObject go = new GameObject(name);
                 Transform got = go.transform;
                 got.parent = parent;
                 got.position = GetVector3(ref l);
                 got.rotation = Quaternion.Euler(GetVector3(ref l));
                 Vector3 ls = GetVector3(ref l);
                 got.localScale = ls;
             } else if (l.StartsWith("@")) {
                 l = l.Substring(1);
                 string path = GetParam(ref l);
                 string name;
                 Transform parent = GetParentChild(path, out name);
                 string assetPath = GetParam(ref l);
                 Object objref = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Transform));
                 Transform t = (Transform) EditorUtility.InstantiatePrefab(objref);
                 EditorUtility.SetDirty(t);
                 t.name = name;
                 t.position = GetVector3(ref l);
                 t.rotation = Quaternion.Euler(GetVector3(ref l));
                 t.parent = parent;
                 Vector3 ls = GetVector3(ref l);
                 t.localScale = ls;
             }
         }
         r.Close();
     } else {
         Debug.Log("Can't find 'Assets/export.txt'");
     }
 }

}

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

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

Answers Answers and Comments

No one has followed this question yet.

Related Questions

The name 'Joystick' does not denote a valid type ('not found') 2 Answers

Getting direct dependencies for an asset 1 Answer

How do I access the list of all assets in a project? 4 Answers

Is there a way to get a unique hash for an asset? 1 Answer

Limiting EditorGUI.ObjectField() to Prefabs only? 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges