I'm sure that based on the past few lectures, you're excited about the power of lists. I'm also sure that you must have one burning question. Specifically, how can we use lists to have teddy bears collect things? I'm here to help. In this lecture, we'll build a small game in which teddy bears collect stuff and we'll use lists to implement that functionality. Let's go take a look. Here's our Ted, the Collector game, and I'll start by showing you how it works. I can place pickups, which are little Dr. T head by clicking the right mouse button. Then when I want the teddy bear to start collecting, I left click the teddy bear and he starts collecting. I can add another head while he's collecting and he'll go get it. But if I add more now, I have to click the teddy bear again for him to go collect those. He collects those pickups from oldest to newest. My main camera has a Ted the Collector script attached to it, and my teddy bear has the teddy bear script attached to it. Let's go look at the teddy bear script first. In the teddy bear, we have a number of field. We have a constant for the impulse force magnitude that I'll use to get the teddy bear moving when I need to add a force, I have a flag that tells whether the teddy bear is currently collecting or not, and we'll see why I need that soon. I also save the target pickup, the pickup that I'm currently going towards to pick up. Then for efficiency, I save the rigid body 2D that's attached to this teddy bear object. I save a reference to the Ted the Collector script, that script that's attached to the main camera. I save both of these for efficiency, so I don't have to go get those components every time I need them. I just need to get them once and then I can use them while the game plays. In my start method, I make sure that the teddy bear is centered in the screen. The Vector3 class has a zero property, which just returns a Vector3 object with zeros for the x, y, and z components. Setting transform position 2000 centers it in the screen. Here's where I save those references. This get component works just like we've seen before, where I get the rigid body 2D that's attached to the same game object that the script is attached to, the teddy bear game object. For the Ted the Collector script, it's attached to the main camera. I say camera.main, and then it can just call the get component method on the main camera to get the Ted the Collector script. OnMouseDown is a method that's called when the user has pressed the mouse button over the collider. On top of the teddy bear, I don't just left-click anywhere, I have to left-click on the collider of the teddy bear. When that happens, I first make sure I'm not collecting. If I'm not collecting right now, I'll go to the next pickup. If I am collecting right now, I'm just going to ignore this mouse click because the teddy bear's already been tasked to go collect a pickup and there's no reason to respond to more clicking on the teddy bear. OnTriggerStay2D is a method that gets called when another object within a trigger collider attached to this object, I have one trigger collider attached to this object. The way I make a trigger collider is here in the box collider 2D component that I have attached to the teddy bear. I check this checkbox that says Is Trigger. That makes this a trigger collider rather than a normal physics collider. I don't want it to be normal physics collider because I don't want it to run into the pickups and have that collision resolved with physics responses, I just want to do some processing when I have that collision. By checking this Is Trigger checkbox, I'm basically saying the physics 2D engine shouldn't do any collision resolution for me other than calling one of the on trigger method. As you can see in the scripting reference, we get three on trigger methods that get called when another object is colliding with the trigger for this GameObject. We get OnTriggerEnterD, which is called the very first frame in which we have an overlap with that other game objects collider and our trigger collider. This is just like the OnCollisionEnter2D method that we've seen before that we use to do collision resolution. We have OnTriggerExit2D which gets called on the first frame in which the other object leaves our trigger collider. We have OnTriggerStay2D that gets called every frame that another object is overlapping with our trigger collider. This is the one that I'm using it in my code. I started by using the OnTriggerEnter2D, but it turned out that it didn't work if I had two pickups that were very close to each other. Because what would happen is OnTriggerEnter2D would get called when I collided with the targetPickup, but when I went to get the next pickup, if it was really close, OnTriggerEnter2D didn't get called because the colliders were already overlapping. OnTriggerEnter2D only gets called on that first frame of overlap. By using OnTriggerStay2D, I solved that problem because as soon as I destroyed that targetPickup OnTriggerStay2D got called because the other pickup was already overlapping with my trigger collider. I check to make sure that the gameObject for the other object that just entered my trigger collider, even though I'm the one that's moving, the other object has entered my trigger collider. Of course, I have a collider attached to my pickups as well. I check to make sure that that's the targetPickup because I may pass over other pickups on my way to my targetPickup, and I don't want to respond to those collisions. I only want to respond to collisions with the targetPickup I'm trying to go pick up. If in fact I've just reached my targetPickup, I call a method in the tedTheCollector script called RemovePickup, so it take out that pickup that I've just collected. I set my velocity to zero. While we often modified the velocity of our rigid body 2D by adding forces to it, in this particular case I want to directly access the velocity property and set it to zero. The reason I want to do that is each time I pick up a pickup, I want to stop and then they want to start moving toward the other pickup. If I just kept adding forces to change where I'm going, I will make the teddy bear go faster and faster, and that's not what we want to have happen. After I do that, I go to the next pickup, which is the same method that I called here when I clicked on the teddy bear. In the GoToNextPickup method, the first thing I do is I access a property in the tedTheCollector script, which says give me a TargetPickup, and I save that here in my field so that when I have a collision, I can check to see if that's the targetPickup for me. If the targetPickup isn't null, it's possible, and we will look at this property soon. It's possible that this TargetPickup property will return null, so we need to protect against that before we do anything with the targetPickup. If the targetPickup object isn't null, the first thing I do is I calculate the direction from my location to the targetPickup's location. We've seen similar things to this before where we were trying to calculate an angle to get from where a particular gameObject is to where another gameObject is in one of the very first programming assignments you did. I take the targetPickup's X location and subtract my current location. The target pickups y location and subtract my y location, which gives me a direction vector. But this direction vector has a magnitude that is based on how far apart I am the teddy bear from the pickup. The next thing I do is I normalize that. I make it a unit vector. I make it a vector that has a magnitude of one. I want to do that so that the force vector that I apply when I call the, AddForce method on my rigid body 2d. This is a unit vector and I multiply by that constant for how much force I want to apply. By making sure direction is a unit vector, I will always be applying an AddForce with a consistent magnitude. Of course it's an impulse force like we're used to using. That's the end of the teddy bear script. The collector script, has a prefab, a pickup that we populate in the Unity editor. That's why I've marked it with the serialized field attribute. This TED, the collector script, which you can think of as a Game Manager. It does game level stuff, not behavior that really belongs in a specific teddy bear. This TED, the collector script, also keeps a list of GameObject of all the pickups that are currently in the game. Here's that single property we've been talking about. When the teddy bear script asks for a target pickup, the first thing we need to do is make sure the list of pickups isn't empty. If the list of pickups is empty, there's no target pickup to provide, so we return null and we've seen how we handle that scenario in the teddy bear script. But if there's at least one pick up in the list of pickups in the game, we return pickups 0, which is the pickup that's at the front of the list. That also means it's the oldest pickup in the game. Because when we add pickups to the list, which we'll take a look at soon, we add them to the end of the list. The list is ordered by age from oldest to newest. In the update method. If the user has pressed the right mouse button, add pick up on right press not right-click. On the first frame that the player has de-pressed to the right mouse button. We calculate the world position of mouse click, which you've seen before when we meet GameObjects follow the mouse around and so on. We instantiate our prefab. You'll notice I'm using an overload of the instantiate method that doesn't provide a position or a rotation. I just give it the prefab that I want to have instantiated, and then I move that prefab to the world position that I calculated up here based on where the mouse is and I add that pickup to the list. As I mentioned, this gets added at the end of the list. The last method in the Ted, the collector script is the, RemovePickup method that we saw the teddy bear script call. When it has picked up it's targeted pickup. We do two things here. Here's another list method called, Remove, and we can call that on our list of pickups and give it the GameObject we want it to remove. Now we actually know from the way this game works that this will be the pickup at the very front of the list at index 0. We want to remove that pickup, which is the same pickup we provided to the teddy bear script as its target pickup. We want to remove that pickup and one of the nice things about list is when we remove an element from the list, it shifts all the other elements of the list so there all right next to each other again and so on. We don't have to do any extra processing ourselves, we just remove the front of the list and all the other elements in the list get shifted down. Then we destroy the pickup, which removes it from the game. To recap, in this lecture, we use lists to have teddy bears collect things in a small game.