Hello, everyone! Fairly new Unity user here. I just got through the Lynda.com tutorial “Unity 5 2D Essential Training”. Generally, I have a good grasp on things but there’s a specific issue I couldn’t figure out.
In this tutorial, you’re programming a basic endless runner. Obstacles are generated on the right and leave the screen on the left. There are scripts to ensure that when they leave the screen they are recycled instead of destroyed. When an obstacle is re-used, there is some code to randomize its appearance and change its BoxCollider accordingly. I understand why this exists, and the code does work. However, I don’t quite understand WHY it works. The reference code is below (I have commented in my questions on specific lines). Also, it should be noted that the sprites for the Obstacle object have their pivot set to Bottom.
public class Obstacle : MonoBehaviour, IRecycle {
public Sprite[] sprites; //List of sprites
public Vector2 colliderOffset = Vector2.zero;
public void Restart()
{
// This allows the same recycled object to have different sprites
// The renderer randomizes within the sprites list
var renderer = GetComponent<SpriteRenderer>();
renderer.sprite = sprites[Random.Range(0, sprites.Length)];
var collider = GetComponent<BoxCollider2D>();
var size = renderer.bounds.size;
size.y += colliderOffset.y; // why is the size increased by an offset? shouldn't it be position?
collider.size = size; // matches collider size to sprite size
//
collider.offset = new Vector2(-colliderOffset.x, collider.size.y / 2 - colliderOffset.y);
}
Welcome to Unity! You’re in for a world of fun. And you’re already off to a good start by working through a tutorial, and thinking about it deeply enough to have questions!
Yeah, this is some confusing math.
In line 16, we’re taking the size from the renderer (which would just cover the sprite) and increasing it by our constant colliderOffset. The y value of this colliderOffset property is simply used to mean “how much should we grow the collider vertically.” I imagine its purpose is to make the colliders a little bigger (or smaller?) than the actual sprite.
Whatever adjustment we do to the size there, in line 21, we then position the collider offset by half its new height, minus whatever we added. That’s the confusing part. So what if we wrote it differently?
We could instead set the offset without reference to this new size, and we’d set it to renderer.bounds.size.y / 2 - colliderOffset.y / 2. The first term here, renderer.bounds.size / 2, just shifts the collider up so that it fits the sprite (presumably the pivot point on these sprites is at the bottom). The second term, - colliderOffset.y / 2, shifts it back down by half of the extra height. If we didn’t do this, the collider would get bigger equally at top and bottom; so including this means the collider will extend on bottom instead of the top.
Or that’s my reading, anyway… I could be way off. I suggest rewriting the code as above, and playing with it (taking terms out one at a time) to see what happens — that’s the best way to gain real understanding!
Hi Joe, thanks for your reply! So I’ve been trying to work this out, and I guess it only makes sense if, when the size.y of the collider is increased, it only increases upwards. Is that what happens in Unity?
No… a box collider is specified by its center and size, so if you increase the size, it extends in both directions.
(You can verify this for yourself by just finding or creating an object with a box collider, and playing with the size and offset properties in the inspector while you watch the box drawn in the scene view.)