Search Unity

Array Tracking (?)

Discussion in 'Scripting' started by drJones, Aug 23, 2007.

  1. drJones

    drJones

    Joined:
    Oct 19, 2005
    Posts:
    1,351
    i'm learning some more about arrays i have a question. hopefully i can explain this clearly - some example code:

    Code (csharp):
    1.  
    2. var assets = new Array ();
    3.  
    4. function AddAsset (asset : Transform)
    5. {
    6.     assets.Push (asset);
    7.     AssetNumber (asset);
    8. }
    9.  
    10. function RemoveAsset (assetNum : int)
    11. {
    12.     assets.RemoveAt (assetNum);
    13.     print ("removed asset # " + assetNum);
    14. }
    15.  
    16. function AssetNumber (asset : Transform)
    17. {
    18.     var currentAsset = assets.length - 1;
    19.     asset.BroadcastMessage ("SetNumber", currentAsset);
    20.     print ("added asset # " + currentAsset);
    21. }
    22.  
    when an object is created it gets added to the array, a variable is set on that object with its array number. if the object gets destroyed it sends the array number to the array to have it removed. if you have 10 objects in the array remove #4 5 for instance, for everything after that object the number changes so you can get an out of range exception - this was expected my first thought was to do a for loop every time something gets removed to shift all the following numbers.

    that seems very cumbersome (especially for alot of objects) - is there a better way to do this? for keeping track of specific objects in an array am i going about this all wrong?

    any help would be greatly appreciated ; )
     
  2. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    If I understand you correctly, what you are looking for is something called a "weak reference" but I am pretty sure that it doesn't exist in JavaScript, not in this version at least.

    However, you can get much the same effect if your object can be marked in some way to denote that it is no longer available. For example, if it has a name field then you could set the name to "<Gone>" or some other value that would never naturally occur. Or, you could have a boolean value that the object sets when it expires. Then, when you iterate through the list with a for loop, you can just ignore expired objects using an if statement ( if (obj.name == "<Gone>"), etc).

    When you need to add an object to the list, loop through the elements until you find one that is marked as expired and simply replace it with the new element. Only if you get to the end of the list without finding a free place do you need to extend the array.

    If you use this approach, you probably won't need to store the array index of the object inside the object itself. Since the order of the objects doesn't matter, you could go through the list occasionally and use RemoveAt to weed out the dead object references if necessary. However, this would only be worth the bother in exceptional cases.

    Anyway, post again if I haven't understood your problem correctly.
     
  3. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    I can't tell what you're actually trying to accomplish with this?

    My best guess is that you need each object pointed to in the array to be aware of its own index in that array. Best course of action would probably be to loop through the array and set the index (as opposed to subtracting one) - much less fragile that way.

    Unless you're looping through thousands of objects, it'll be plenty fast enough, too.[/list]
     
  4. drJones

    drJones

    Joined:
    Oct 19, 2005
    Posts:
    1,351
    great idea ; )

    in the intervening time i've come up with a few non-array solutions to my situation now i'll just have to figure out which one fits everything best.

    keeping objects in an array would help with a few different things in the project i'm working on but the basic idea is to manipulate objects en masse in the order they were created (while still being able to remove any of them) - and to learn about arrays!

    many thanks guys ; )
     
  5. thylaxene

    thylaxene

    Joined:
    Oct 10, 2005
    Posts:
    716
    or use a hashtable and track it via a unique name/key... that way you don't need to care about indices at all.

    Code (csharp):
    1. var assets = new Hashtable ();
    2.  
    3. function AddAsset (asset : Transform)
    4. {
    5.    assets.Add(asset.name, asset);
    6.    // just loading in the transform. obviously you could put 0 or something else
    7. }
    8.  
    9. function RemoveAsset (keyName : String)
    10. {
    11.    assets.Remove (keyName);
    12. }
    http://msdn2.microsoft.com/en-us/library/system.collections.hashtable.aspx

    Cheers.
     
  6. drJones

    drJones

    Joined:
    Oct 19, 2005
    Posts:
    1,351
    hey thanks thylaxene! i've heard mention of them but never knew what the function of those were - i'll look into that.

    as a side note - i haven't tested it rigorously but i've found that overlapsphere seems to return objects in the order they were instantiated. i don't know how the engine internals work but maybe there's an id # for each cloned object overlapsphere starts with the lowest id it finds? (just guessing though i would have thought it ordered by distance from center)