LoadList<Transform>() creates "New Game Object"

Easy Save 2 has been replaced by Easy Save 3, so is no longer supported.
Locked
justinl
Posts: 7
Joined: Mon May 27, 2013 3:46 am

LoadList<Transform>() creates "New Game Object"

Post by justinl »

Hello,

I'm storing a List<Transform> but when I load it back into my scene using ES2.LoadList<Transform>(myPath); it creates a bunch of objects in my scene view named "New Game Object" (1 for each Transform in my list). Each of the New Game Objects has the properties of the Transform that I'm loading. I'm just wondering if there's a way to delete them or not have them load into the scene since it seems like a waste to Instantiate and then Destroy them. I also don't seem to be able to even get reference to them because if I load my list into a variable, and then I do Destroy(myTransformList[0].gameObject) it doesn't even delete the object from the scene.

I know I could simply store a different data type such as the Vector Position and the Vector Rotation but I'm curious because it seems like with ES2.LoadList() there's no way to avoid having these ghost Transform nodes show up in the heirarchy. A bug perhaps?

Cheers & Thanks!
Justin

Here is my code for your reference:

Code: Select all


List<Transform> myListOfTransforms = new List<Transform>();

void Save(){
    ES2.Save(myListOfTransforms, transformListSavePath);
}

void Load(){
    myListOfTransforms = ES2.LoadList<Transform>(transformListSavePath);
    //at this point in the code is where the ghost "New Game Object" appears in the scene.
}

User avatar
Joel
Moodkie Staff
Posts: 4851
Joined: Wed Nov 07, 2012 10:32 pm

Re: LoadList<Transform>() creates "New Game Object"

Post by Joel »

Hi there,

This is not a bug. In Unity, you cannot have a Transform without a GameObject. Therefore, we have to create a GameObject to attach the Transform to.

The way around this is that ES2 also has a self-assigning load function, which automatically assigns the Transform to the GameObject given as a parameter, though there is no self-assigning functions for Lists at this current point in time. For more information on the self-assigning load, see the second method on this page.

In your circumstance, you could either load each Transform separately and use the self-assigning function. Alternatively, you can assign the Transform to your GameObjects manually and then delete the GameObjects created by ES2 afterwards.

Edit: I should also mention that there is also a self-assigning Load function for native arrays, though this is currently not documented. It's the same as the normal self-assigning Load, except it accepts an array of GameObjects as the second parameter.

I hope this helps.

All the best,
Joel
justinl
Posts: 7
Joined: Mon May 27, 2013 3:46 am

Re: LoadList<Transform>() creates "New Game Object"

Post by justinl »

Thanks Joel,

It just seems like an unusual feature because what's the point in saving a List of Transforms when if you load it, it generates inaccessible Game Objects in the scene view. The only way to get access to them is using something like Find("New Game Object") since I tried to reference the gameobject via the List (myTransformList.gameObject) but it didn't appear to have a reference to the "New Game Object". Perhaps I'm trying to access them incorrectly or I couldn't Destroy(myTransformList.gameObject) it because a reference to it still existed in the List....

That undocumented self-assigning Load function for native arrays does sound like that might work though :)

Thanks!
Justin
User avatar
Joel
Moodkie Staff
Posts: 4851
Joined: Wed Nov 07, 2012 10:32 pm

Re: LoadList<Transform>() creates "New Game Object"

Post by Joel »

Hi Justin,

You can access the GameObject of a Transform (or any Component for that matter) using the 'gameObject' variable, so there's no need for the GameObject.Find() function. For example:
Transform t = ES2.Load<Transform>("transform.txt");
// Get the GameObject containing the Transform
GameObject go = t.gameObject;
I should also note that if you destroy a List, it doesn't destroy the items in that List. If you want to destroy a list of GameObjects, you should iterate through the list and destroy the GameObjects in the List, not the list itself.

Regards,
Joel
User avatar
Joel
Moodkie Staff
Posts: 4851
Joined: Wed Nov 07, 2012 10:32 pm

Re: LoadList<Transform>() creates "New Game Object"

Post by Joel »

Actually the best thing to do is to save the length of the array when saving the array itself. Then when you load you can do:
Transform[] transforms = new Transform[ES2.Load<int>("transformsLength")];
// Initialise the array
for(int i=0; i<transforms.Length; i++)
	transforms = (new GameObject()).transform;


Hope this helps!
Joel
jalex19
Posts: 5
Joined: Sat Nov 23, 2013 6:16 pm

Re: LoadList<Transform>() creates "New Game Object"

Post by jalex19 »

I still seem to be stuck when loading the saved array back in to the newly created one. I'm probably messing up some syntax somewhere.

Here is my script - I get a null reference exception:
NullReferenceException: Object reference not set to an instance of an object
MoodkieReader.ReadTransform (UnityEngine.Transform t)
MoodkieReader.Read[Transform] (UnityEngine.Transform c)

Doesn't give a line, but I suspect it's the LoadArray function. Thanks for helping me round this out :)

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class LevelEditor : MonoBehaviour {

	public List<Transform> starTransforms = new List<Transform>();
	public GameObject bananaPrefab;
	public Transform[] loadedTransforms;

	// Use this for initialization
	void Start () {
		if (ES2.Exists("LevelEditorTest.txt")) {
			loadedTransforms = new Transform[ES2.Load<int>("LevelEditorTest.txt?tag=StarTransformsLength")];
			ES2.LoadArray<Transform>("LevelEditorTest.txt?tag=StarTransforms", loadedTransforms);
			for (int i = 0; i < loadedTransforms.Length; i++) {
				GameObject star = Instantiate(bananaPrefab, loadedTransforms.position, loadedTransforms.rotation) as GameObject;
				starTransforms.Add (star.transform);
			}
		}
	}

	void Save () {
		ES2.Save (starTransforms.ToArray(), "LevelEditorTest.txt?tag=StarTransforms");
		ES2.Save (starTransforms.Count, "LevelEditorTest.txt?tag=StarTransformsLength");
	}
}
jalex19
Posts: 5
Joined: Sat Nov 23, 2013 6:16 pm

Re: LoadList<Transform>() creates "New Game Object"

Post by jalex19 »

Hmm seeing your reply to my other thread lead me to this example http://www.moodkie.com/forum/viewtopic.php?f=4&t=482 - which I read before but now makes more sense, looks like instead of LoadArray I will use a loop to load things. I'm optimistic that this should solve the issues in both my threads. Will report back if I have problems.

Cheers!
User avatar
Joel
Moodkie Staff
Posts: 4851
Joined: Wed Nov 07, 2012 10:32 pm

Re: LoadList<Transform>() creates "New Game Object"

Post by Joel »

Hi again,

Actually the error in your previous piece of code is that you've not initialised the loadedTransforms array before calling ES2.LoadArray.

If you just do:
loadedTransforms = new Transform[ES2.Load<int>("LevelEditorTest.txt?tag=StarTransformsLength")];
You have an array, but it doesn't contain any Transforms to assign to, it just contains lots of null values (hence the NullReferenceException). Self-assigning functions don't create the Transforms for you, so we have to create some transforms to go into it, like this:
loadedTransforms = new Transform[ES2.Load<int>("LevelEditorTest.txt?tag=StarTransformsLength")];
// Initialise the array (ie. Add some blank Transforms to it)
for(int i=0; i<loadedTransforms.Length; i++)
    loadedTransforms = (new GameObject()).transform;


Because we no longer officially support this method we cannot guarantee that there aren't other errors with it, but hopefully it should work fine :)

Regards,
Joel
Locked