 To finish up here, let's quickly go through a survey of all the most important elements in the API for collisions starting with the collider type itself, which has these instance properties first attached rigid body, which is the reference to the rigid body, which is attached to this collider. We talked about how by default this will get set to the rigid body, which is on the same game object or game object up the hierarchy. So probably most commonly you don't set this explicitly, but we do have access to this property if you want to read or manipulate it. And then we have the bounds property, which is of type bounds, which is a class representing a box in space that can't be rotated. It's always aligned to the world space axes. And the reason every collider has these bounds is because the obvious way to optimize a collision test is to first check the bounds to see if there's overlapping between two colliders bounds. If not, if the bounds don't overlap, then the collider geometries themselves can't overlap. So you don't have to do the more complicated tests. The testing for when bounds overlap is very cheap. So we test the bounds first before actually looking at the colliders. The enable property when false means the collider will be ignored for all collision tests, even the manual queries. So if you do a raycast or a sphere check or overlap box sweep test, any of those methods, any disabled collider is ignored in such tests. The closest point method, given a vector three a position in space returns the point on the collider that is closest to that point. And this works for all collider types except for mesh colliders. The collider geometry has to be convex. It can't be concave, meaning it can't have any dense in it effectively. There's a more formal definition of convexity, but basically can't have dense. And I'm not sure exactly what happens if you use closest point on a concave mesh collider. I don't think you get an exception. I think you just get back a bad result. It just doesn't do the math correctly. So you get back the wrong answer. And then we have closest point on bounds, which is similar except you get back the surface on the point of the bounds, not the actual collision geometry. And then the raycast method performs a raycast. But in this raycast, the collider itself in this case C will be ignored by the raycast. It's not going to hit that collider instances of raycast hit have a number of properties. And these are probably the most important. You have first collider, which is a reference to the collider that was struck by the ray rigid body, which is the rigid body of that collider. If any, this could be no and transform, which is a transform of the game object of the struck collider point is the point in the world space where we hit the collider. Distance is the distance from the Ray's origin to that impact point. And then normal, that is a vector representing the plane of the surface. It's perpendicular to the plane of the surface, which the ray hit. The physics class contains a number of static methods that allow us to perform queries on our colliders, including as we've seen already checkbox, where in the most complete overload, the one where you provide all the options, you specify the center, the dimensions in terms of half extents. You can also specify orientation, though this defaults to identities. So by default, it's a axis aligned box, just like bounds. And we can also specify a layer mask. And also this query trigger and action value specifies whether the ray will hit trigger colliders or not. By default, it uses the global setting. That's what this means. But you can also specify that regardless of global settings, you can say I want to collide with triggers or not collide with triggers. The default global value is true. So by default, checkbox will intersect trigger colliders. And then we have check sphere and check capsule, which are very similar. Though of course you define the geometry with different arguments, but I won't go into that here. And then in addition to the check methods, we have the overlap methods, which are similar, except instead of just returning a Boolean, we get back an actual array of all the collisions overlapping that box or sphere or capsule. And because generally we don't want to create new arrays in the course of our game, we don't want to create garbage that has to get garbage collected, generally instead we'll use the non-alloc variance of these methods where instead of returning an array, the method expects the array to be passed in and it puts the colliders in this array, and it returns the number of colliders so you know how many results there were. Because the length of the array isn't going to tell you. You choose the length of the array when you pass it in, but then we need the method to tell us how many actual colliders did we collide with in this test. And then we have the raycast methods which we already discussed, the variance raycast, raycast all, and raycast non-alloc. Again raycast all will generate an array, so we generally want to avoid that. Instead we'll usually call non-alloc. There's a minor variant called linecast, which is just like raycast, but whereas with raycast you specify the starting point of the array and then the direction it travels in, with linecast you specify the starting point and then the end point, and you don't specify a distance. It's really just a convenience, it's nothing you couldn't accomplish with just raycast. In fact it's totally equivalent. If we do linecast of A and B that's the same as doing the raycast of A and B minus A and then specifying the magnitude of B minus A. So it's totally equivalent. So it's just a convenience. For whatever reason there's no linecast all or linecast non-alloc. Those don't exist, but we don't really need them anyway. We can always just express a line in terms of arraycast anyway. And then we have boxcast, spherecast, and capsulecast, which as the names imply it's like you're taking a box and moving it along array and seeing if we hit anything. Likewise spherecast you drag a sphere along array, capsulecast drags a capsule along array. And then for each there's the three variants of where we just get back one hit result, all the hit results and the variants where we don't allocate a new array. Then physics also has the static method closest point, which is really just like the instance method closest point of the collider type. But with the collider instance method you don't specify the position or rotation. You don't get to specify where the collider is in space. It just assumes you want to collide with the current position of the collider. But here we get to specify not just the collider and the point, but where that collider should be positioned and what its rotation should be. And this is useful then because sometimes you want to find the closest point relative to collider not in its current position and you don't want to have to move it. Especially if we're talking about a static collider. Static colliders again are not really supposed to move and if you do move them you're going to pay the cost of expensive recomputation. So this is useful when you want to test for the closest point of collider without moving that collider basically. And then we have compute penetration where you can test for the overlap between collider 1 and collider 2 and specify what their positions and rotations are. And the method returns true if there is any collision between them in those positions and rotations. And if there is it sets direction and distance. It sets them to the direction that C1 would have to travel and the distance it would have to travel to move away from C2 and no longer intersect. I'm a bit surprised there's no overload of this method where rather than having to explicitly specify position rotation you can just have it assumed from the collider. So anytime you use this method you do have to specify those things explicitly. Lastly in the physics class we have the static property gravity which is the vector representing the direction and force of gravity that's applied to any non-kinematic rigid body that has gravity enabled. So if in the course of the game you want to for whatever reason change gravity on the fly you can do so. And then physics dot sleep threshold that's the global default sleep threshold for any newly created rigid body. It doesn't affect any currently existing rigid bodies but any subsequently creating rigid bodies will have this as their sleep threshold by default. And very lastly here we have the methods ignore collision and ignore layer collision. You pass to ignore collision to colliders and if the third argument is true you're enabling collision and trigger events for when those two colliders overlap. But if this is false you're disabling collision and trigger events for those two colliders. And then likewise for ignore layer collision same deal except you're doing so for all colliders in layer one and layer two. And I believe the way this works is that the layer collision supersedes the specific collision property between any two colliders. So say if we've enabled collisions between C1 and C2 but then we've disabled them at the layer level if C1 is part of layer one and C2 is part of layer two and we've disabled collisions between those two layers I think in that case C1 and C2 will not generate collision or trigger events. I'd have to test this to verify but I believe that's how it works. Be clear that these methods don't affect what happens with the collision query method so you're not disabling all collision tests on these just the collision and trigger events. Lastly we'll look at the rigid body class whose instances have these properties and a few more which I left out but these are the most essential. Is kinematic defaults to false but if you set it to true that makes it a kinematic rigid body. We can get and set the position the rotation the velocity angular velocity mass drag and angular drag we can set gravity to be on or off for this particular rigid body we can set constraints so that velocity will not automatically translate or rotate an object on the specified axis so we can say like don't move automatically along the X axis or the Z axis or rotate around the Y axis etc so we can have any combination of those constraints. Freeze rotation is just a convenience property that when you set it to true it effectively enables constraints on all three axes for rotation. The interpolation property defaults to none but we can set it to interpolate or extrapolate as we demonstrated to give us a smoother movement. Collision detection mode by default this is discrete and in discrete mode what can happen is that an object is moving fast enough that in one state it's on one side of something and then in the next state the next physics update is then moved to the other side so it's like an object has magically passed through an object which it's supposed to collide with but because the way the tests are done it's done discretely at that first state and then that second without checking the in between. So to avoid this problem for fast moving objects you may want to send its collision detection mode to continuous in which case checks for collision from state A to B it checks for the states in between it doesn't just warp the object to the destination and do the collision test there it does effectively a sweep test and so it will prevent these cases fast moving objects will warp through other objects and then the continuous dynamic setting not only prevents warping through static colliders but also through dynamic colliders, moving colliders so if you have two fast moving rigid bodies that might pass through each other in the space of one physics update if they're both continuous dynamic then that collision is detected and they will pass through each other and then lastly we have sleep threshold which is sort of a measure of mass normalized energy basically meaning like cumulative velocity and angular velocity so below a certain amount of movement the object will totally go to sleep it will stop moving entirely and then the physics engine assumes that the object isn't moving again until something moves it like something else collides into it or its velocity is explicitly set then it wakes up as for the methods of rigid body we have move position and move rotation which are basically like setting the position rotation properties but if you have interpolation enabled this will account for that so if you're using interpolation you'll want to use these methods rather than directly setting the position and rotation we also have the add force method we talked about before there's add relative force which is relative to the local coordinate system rather than the global coordinate system then we have add torque which is just like add force but it's applying angular velocity again measured in radians and then we have add force at position which applies the force but not on the center of gravity somewhere else which we specify with this position so you can use this to effectively like imagine you poke at an object with a stick so where that stick is hitting the rigid body you find that position and that's what you specify here and then we have add explosion force which is like applying force as if from a nearby explosion you specify the force of the explosion the position the radius and you can have this upwards modifier which defaults to zero but it sort of just adds lift to the objects I assume you don't have a choice of what the direction is I assume it's just always up the y axis in the positive direction I assume that's the case but this sometimes is useful for like a grenade and you want the things to bounce into the air more than just they bounce away from the center that's just a commonly desired behavior so that's why this modifier is here and very very lastly on rigid body we have closest point on bounds where it just returns the closest point to a position on any of the colliders to which this rigid body is attached sometimes that's useful and convenient sweep test we saw before there's also sweep test all which returns an array of raycast hits strangely though there's not sweep test non-alloc so I don't know how you're supposed to really actually use this method because every time you use it it's going to be creating garbage perplexed by that maybe it's just a case that people don't have much cause to use sweep test all in the first place so they don't really need the non-alloc version I don't know it seems like an obvious omission anyway very very very last thing we have the isleeping method which returns true when a rigid body is sleeping and then we can explicitly put an object to sleep or wake it up with these two methods I don't know of any scenario where using sleep is useful I assume something must exist they put it in the API so where wake up is useful the most common example is you have a rigid body resting on top of a static collider but then you disable the static collider so that you should no longer be colliding with anything well that's not going to wake up the rigid body so it's not going to move gravity is not going to be applied it's not going to move at all so what you need to do then is you need to explicitly wake up the rigid body and then it will start falling