Unity 4.3 2D Tutorial: Physics and Screen Sizes

Learn how to use Unity’s 2D physics engine for collision detection, and deal with different screen sizes and aspect ratios. By Chris LaPollo.

Leave a rating/review
Save for later
Share
You are currently viewing page 6 of 6 of this article. Click here to view the first page.

Keeping the Zombie On Screen

Now that the enemy moves and respects the world bounds, you should probably get the zombie to do the same. You could do all sorts of fancy things with physics and colliders to keep the zombie in the proper area, but sometimes the easiest thing to do is to use a few if checks and some basic math.

Open ZombieController.cs in MonoDevelop and add the following method:

private void EnforceBounds()
{
  // 1
  Vector3 newPosition = transform.position; 
  Camera mainCamera = Camera.main;
  Vector3 cameraPosition = mainCamera.transform.position;

  // 2
  float xDist = mainCamera.aspect * mainCamera.orthographicSize; 
  float xMax = cameraPosition.x + xDist;
  float xMin = cameraPosition.x - xDist;

  // 3
  if ( newPosition.x < xMin || newPosition.x > xMax ) {
    newPosition.x = Mathf.Clamp( newPosition.x, xMin, xMax );
    moveDirection.x = -moveDirection.x;
  }
  // TODO vertical bounds

  // 4
  transform.position = newPosition;
}

The code above only handles the horizontal bounds. You’ll add code to handle the vertical bounds once you know this works. Here is what it does:

  1. It copies the zombie’s current position, ensuring the zombie maintains whatever z position you set in the editor. It also gets a reference to the scene’s main camera and copies the camera’s position, both of which will be necessary to calculate the zombie’s new position.
  2. It calculates the x values in world coordinates for the edges of the screen. It does so by first calculating the distance from the center of the screen to one of its edges, and then adding that to the camera’s x position. This means that if the camera is at (50, 0), and xDist is 4.8, the right side of the screen has an x position of 54.8 in world coordinates.
  3. This checks to see if the zombie’s current position (stored in newPosition, confusingly enough) exceeds the view’s horizontal limits. If so, it sets newPosition‘s x value to the boundary value and reverses the x component of moveDirection.

    You haven’t seen it since part 1 of this series, but moveDirection is the vector that Update uses to advance the zombie’s position each frame, so reversing its x component will start it moving in the opposite direction, effectively bouncing it off the edge of the screen.
  4. Finally, it updates the zombie’s position with newPosition. This will be the same position the zombie had when you called this method if the zombie was already within its allowable space.
Note: If you want to make the zombie turn slightly before it reached the edge of the screen, simply reduce the size of xDist.

Now add a call to EnforceBounds at the end of Update:

EnforceBounds();

Save the file (File\Save) and go back to Unity.

Play the scene and try to walk the zombie off the left and right sides of the beach. He should turn right around each time rather than walking off into the great unknown.

zombie_horizontal_limits

With the left and right constraints in place, try limiting the zombie’s vertical movement yourself. Put your code inside EnforceBounds in ZombieController.cs, just after the comment that reads // TODO vertical bounds. It should be similar to what you wrote for the horizontal bounds, but even simpler. The following Spoiler has a solution.

[spoiler title=”Zombie getting away from you?”]You know the camera always has a y position of zero because the scene will only scroll horizontally in Zombie Conga. You also know that the camera’s Orthographic Size is half the height of the view. That means that the view’s upper limit is its size, and its lower limit is negative its size.

With those facts in mind, the following code will limit the zombie’s vertical movement:

float yMax = mainCamera.orthographicSize;

if (newPosition.y < -yMax || newPosition.y > yMax) {
  newPosition.y = Mathf.Clamp( newPosition.y, -yMax, yMax );
  moveDirection.y = -moveDirection.y;
}

This code simply checks the zombie’s vertical position against the bounds of the view and reverses the zombie’s vertical direction if the position exceeds those bounds. If you wanted to make the zombie turn slightly before it reached these boundaries, you could simply reduce the size of yMax.
[/spoiler]

Run again and now you’re zombie stays in its sandbox.

zombie_contained

At this point you might want a little break, so you’ll finish up Zombie Conga in the fifth and final part of this series!

Where to Go From Here?

In this part of the tutorial, you learned how to use Unity’s 2D physics engine to detect collisions, and you saw how you can handle some issues that arise when trying to support different aspect ratios. You can find a copy of the project up to this point here.

The main thing you should do next is the next part of this tutorial, of course! But if you want more information about 2D physics in Unity, take a look at Unity’s Component References for its 2D Components and Unity’s RigidBody2D and Physics 2D Overview videos.

I hope you’re enjoying this tutorial series. If you’ve made it this far, you’ve got a lot of free time on your hands. Also, you’re really close to the end, so don’t stop now!

Please ask questions or leave remarks in the comments section. Thanks for reading!

Contributors

Over 300 content creators. Join our team.