- Home /
How to reference a scene gameobject from a custom project asset?
Does anybody have any method for being able to have a serialized reference to a game object in a scene in a custom asset in the project?
To explain what I mean - I've written a tool for saving, loading & merging lightmap bakes to a custom asset in the project tab (i.e. something that derives from ScriptableObject, was created with ScriptableObject.CreateInstance and saved with AssetDatabase.CreateAsset). The one problem with it is that all the ways I could find to store which GameObject has what lightmap settings fails to keep track of the gameobject in interesting scenes over time.
One method I tried was saving the path to the gameobject in the scene's hierarchy tab as a string - that works terrible because the paths are not unique, and because when the hierarchy is reordered the paths change, even though the game objects are the same
A second method was GameObject.GetInstanceID and EditorUtility.InstanceIDToObject - this fails because the instance ID's change every time the scene is reloaded, so EditorUtility.InstanceIDToObject returns null after closing/opening or changing scenes
A third method is actually using a GameObject reference in the custom asset - which seems like it is the right way and seems like it ought to work great (can browse the properties of the custom asset and see the gameobjects are all set in the property inspector), and it does work for a while - unfortunately the moment any scene other the one containing the GameObject is loaded, the saved references are all killed in the asset, so that AssetDatabase.LoadAssetAtPath returns an object with all gameobject references set to null :(
here's some code bits that may help place what I'm talking about:
// got this class in "SavedLightmapData.cs"
public class SavedLightmapData : ScriptableObject
{
[System.Serializable]
public class LightmapObjectAtlasPair
{
[SerializeField]
public GameObject gameObject; // this is what goes null
public AtlasPosition atlasPosition;
public LightmapObjectAtlasPair(GameObject go, AtlasPosition pos)
{
gameObject = go;
atlasPosition = pos;
}
};
[System.Serializable]
public class LightmapCopiedData
{
public int activeLightmapIndex;
public Texture2D farMap;
public Texture2D nearMap;
public LightmapObjectAtlasPair[] atlasPairs;
}
public LightmapHelpers.LightmapCopiedData[] lightmapData;
}
// and the code to save one of these looks like this:
SavedLightmapData savedData = ScriptableObject.CreateInstance<SavedLightmapData>();
savedData.lightmapData = data;
AssetDatabase.CreateAsset(savedData, outputName);
// and the code to load looks like this:
SavedLightmapData savedData = (SavedLightmapData)AssetDatabase.LoadAssetAtPath(inputName, typeof(SavedLightmapData));
Have you found a solution to this problem? I am also having that problem.
@chuckrussell - I haven't found a solution that allows me to store gameObject references outside of the scene, but a workaround is to store the gameObject references inside an object in the scene itself.
-1 Answers Bug occurred here. $$anonymous$$ods, please read the QA
[2]: http://answers.unity3d.com/questions/526240/meta-moderation-page-1-answers-bug.html
Answer by Radivarig · Nov 29, 2014 at 02:41 PM
Documentation says: "assets can't store references to objects in a scene."
I'd go with hidden child, then reference to parent.
string uniqueID = "generateUniqueID";
GameObject child = new GameObject(uniqueID);
child.transform.parent = targetedSceneObject;
child.hideFlags = HideFlags.HideInHierarchy;
and fetch like this GameObject.Find(uniqueID).transform.parent;
Answer by DaveA · Nov 21, 2011 at 08:54 PM
" the paths are not unique, " - What I did was make an Editor script to give unique names to all the objects. Not as pretty, but at least you can always find the uniquely-named object.
$$anonymous$$y duplicate named objects are usually actually part of a model - rena$$anonymous$$g them doesn't work great. Also, it doesn't solve changing the hierarchy :(
Answer by Adrian · Jan 27, 2012 at 12:15 PM
I don't think Unity allows references from assets to scenes, only the other way round.
An option to work around this limitation could be storing a "entry point" game object in the scene with an unique name, so that you can easily locate it in every scene using GameObject.Find()
. Then add a script that contains references to the game objects in the scene and reference them from your assets using either the array index or a unique identifier. Optionally you can also hide that object using HideFlags so it doesn't clutter the hierarchy view.
Posted by @tswalk; lost to the ether.
I believe Adrian has the right direction, as I too have been trying to get gameobject references in a scene saved to an asset (assetdatabase) with serializable / scriptableobject class and it just doesn't seem to work at all. so, how unity is keeping track of object in hierarchy (either prefab'd or not) and its' unique id system out of our hands is way beyond understanding. there just is no reason why we have to come up with half-cocked solution for this at all.
I believe Adrian has the right direction, as I too have been trying to get gameobject references in a scene saved to an asset (assetdatabase) with serializable / scriptableobject class and it just doesn't seem to work at all.
so, how unity is keeping track of object in hierarchy (either prefab'd or not) and its' unique id system out of our hands is way beyond understanding.
there just is no reason why we have to come up with half-cocked solution for this at all.
Your answer
