Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Should I Use a List<> in this situation? Advice requested.

Discussion in 'Scripting' started by outtoplay, Jul 14, 2014.

  1. outtoplay

    outtoplay

    Joined:
    Apr 29, 2009
    Posts:
    741
    I have a simple level with a locked door. There are 12 targets that need to be destroyed before the door will function and open (activating it's OnTriggerEnter()). The number of targets could vary, so I imaged I could create a list, populated in Start() by finding all objects that have the tag "Target". When the Target.Count == 0, the door's Trigger would be activated.

    Is this the cleanest way to perform this function? I guess I could create an int var called targetCount and set it to 12 in the inspector or hard code it. But I might want to have a random number of targets generated at the start of the level.

    Any thoughts on this would be appreciated. thanks.

    B.
     
  2. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,716
    Yes... why not?
     
  3. outtoplay

    outtoplay

    Joined:
    Apr 29, 2009
    Posts:
    741
    It was a question. There are plenty of ways to do things, some far more efficiently than others, like not using GetComponents in Update. I was looking for experienced feedback on how best to accomplish this (not actually the coding part, but from a design stance). For instance, I have no idea if I can actually destroy objects that are in a List<> and the list would register that decrease in members.
     
  4. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,716
    Just to be clear, you are aware that you cannot implicitly destroy managed object? When you do GameObject.Destroy(gameObject), it destroys only the unmanaged object.

    The only way to destroy a managed object is to not reference it, and let the GarbageCollector performs its job.

    So at best, you just need to loop in the list once in a while, and remove any index that is equal to null.

    As for performance issue, I haven't encounter a moment where my bottleneck was having a list instead of an array.
     
  5. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,500
    That's more or less what I'd do. I'd add a bit to it, though.

    1. I wouldn't use a tag, I'd attach a Target component to the objects.

    2. In the Target component's OnDestroy method, I'd explicitly remove that item from the list. This means you don't have to poll for null objects.

    3. In line with that, instead of looking them up externally, I'd probably have the Target component add itself to the list in its Start or Awake. This is subjective, but I like to be consistent in that whatever creates or registers something is generally also responsible for destroying or unregistered it (except for where it's arbitrary anyway).

    4. This might not be necessary, but I'd probably make a class to represent the list. It'd just wrap a list and give it some use-case specific functionality - AddTarget, RemoveTarget, ExistingTargetCount, ClearTargets... whatever you might need. Remember it doesn't have to be a MonoBehaviour. The benefit of this is that if you expand its functionality later you're already using everything through high-level interface, so you should have complete freedom about how you change the implementation while minimizing the impact on the rest of your code.