- Home /
Storing and Removing GameObjects - List or Dictionary?
Hey all!
Looking for some tips on which data structure is best for storing/removing game objects. What I am doing is storing all my HUD objects into a HUDElements List in my HUDManager. I am using a struct to store information for the object, and adding the struct to my list. When I don't need to object anymore, I remove it from the List, and when the object is needed again, I add it back.
The problem (I think) is how I am looking for and removing them, here's a snippet of my code:
public enum HUDType
{
MAIN = 0,
MENU,
CAMERA,
CONTROLS,
RACE_STATS,
LAPS,
LAPTIME,
SPEED,
FPS,
DEBUG,
NUM_OF_HUD_TYPES
}
public struct HUDElement
{
public HUDType hudType;
public GameObject hudObject;
public GUITexture gTexture;
public HUDElement( HUDType hudType, GameObject hudObject, GUITexture gTexture )
{
this.hudType = hudType;
this.hudObject = hudObject;
this.gTexture = gTexture;
}
}
private List<HUDElement> HUDElements = new List<HUDElement>();
public void SetHUDElement( HUDType hudType, GameObject hudObject )
{
HUDElement incomingHUD = new HUDElement( hudType, hudObject, hudObject.GetComponent<GUITexture>() );
if( !HUDElements.Contains( incomingHUD ))
HUDElements.Add( incomingHUD );
}
public void RemoveHUDElement( HUDType hudTypeToRemove )
{
Debug.Log("Removing HUDType "+ hudTypeToRemove);
foreach( HUDElement hud in HUDElements )
{
if( hud.hudType == hudTypeToRemove )
{
Debug.Log("Successfully removed "+ hudTypeToRemove +" from list!");
HUDElements.Remove( hud );
return;
}
}
}
Although the code above works, I feel like it's kinda messy and the same could be achieved in a much cleaner way. Any tips would be greatly appreciated as always! Like should I use a different data structure for this, such as Dictionary?
Thanks for your time guys!
Stephane
Answer by phodges · Nov 03, 2012 at 08:59 PM
You've got a fixed set of possible element types, so how about?
Start by preallocating all of the elements you will ever need and storing them in an array: access the type you need using an offset into the array based on the enum. That will reduce the total number of allocations you ever need to do and give you o(1) access time to find anything you ever need.
Back the above up by adding an initialise method to these elements, that you use in place of new in SetHUDElement
To give you a fast way of iterating over only active elements, use either a LinkedList or write your own intrusive linked list that embeds into your elements.
If you're going for the LinkedList approach handle your adding and removal using LinkedListNodes. You can make your RemoveHUDElement fast too, by making the LinkedListNode accessible from the HUD element: a simple null check will tell you if the item is active or not: once again o(1), getting rid of the iteration over active elements. Similar thinking applies if you roll your own list solution.
How about that?
Hey phodges, thanks for the suggestions!
I have never used LinkedList before, so I think I'll use the Array approach. But can you explain what you mean by "Back the above up by adding an initialise method to these elements, that you use in place of new in SetHUDElement" ? Do you mean to create the HUDElement within each elements, and pass that to SetHUDElement, ins$$anonymous$$d of creating it in the function with 'new' ?
Thanks for your help!
Not having used a LinkedList before should be considered an opportunity to do so; it's a good idea to explore what all of the generic containers can do for you, in terms of convenience and performance.
What I mean in my second part, was to use this initialise method to recycle already allocated objects, and so you would not be passing any new HUDElements at all.
I think the simplest thing to do is just show you a sketch of something that does broadly the same thing as you are attempting that uses LinkedLists. You can find the code here:
https://github.com/phodges/Unity/tree/master/Questions/342260
Scene set up is simple: just add $$anonymous$$onitorDemo and $$anonymous$$onitorTag to the camera in a blank scene. Create a prefab (I used the standard cube), attach $$anonymous$$onitorTag to it and then associate this prefab with $$anonymous$$onitorDemo in the inspector.
If you found this information useful then please consider accepting the answer.
$$anonymous$$an, thanks a lot for the time you took to put this little demo together, it is really helpful and I learned a lot from it! I haven't tested it in Unity yet, just read through the code, but I will when I can later on today.
And you're right about the opportunity to learn about LinkedList. I will try to implement this in my code, and let you know how it's working out for me.
Again, thanks a bunch for the extra effort you put in!
Answer by Althaen · Nov 03, 2012 at 08:29 AM
This may help you. If not them I'm not much use. :)
http://docs.unity3d.com/Documentation/ScriptReference/Object.Destroy.html
Althaen, thx for your answer but it's not at all related to my question. I am not asking how to destroy objects, I am asking about the use of data structures such as List, Dictionary and the best way to keep a list of objects that need to be removed/added whenever they become available/not available.
Your answer
Follow this Question
Related Questions
List Type Mismatch 0 Answers
A node in a childnode? 1 Answer
The name 'Joystick' does not denote a valid type ('not found') 2 Answers
missingGameObject problem 3 Answers