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.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Unity 4.3 2D Tutorial: Physics and Screen Sizes
55 mins
Dealing with Screen Boundaries
When making games, you’ll often want to position sprites so they look good when running on devices with different aspect ratios. For example, imagine trying to display the player’s score in the upper right corner of the screen. If you positioned the score a fixed number of units away from the screen’s center, it would appear to be in different spots on devices with different aspect ratios, such as a 3.5″ iPhone, a 4″ iPhone and an iPad.
The following images demonstrate this point:
Respawning the enemy just off screen so she can walk into view poses the same problem as positioning a score label. You can’t pick a specific location because it might be off screen on a small device, but visible on a larger device, as shown in the following images:
To solve the above situation, you might think to try placing the spawn point further to the right to account for the largest possible device. However, that would also be incorrect because the game would then play differently on different devices, because the enemy would spend more time off screen on smaller devices than on larger ones. The following images show why:
Neither of those two scenarios is acceptable.
In this section, you’ll create a script that you can attach to a GameObject and it will position the object relative to one of the edges of the camera’s view.
If you don’t know how to do that, take a look at Unity’s tutorial video on cameras.
If you don’t know how to do that, take a look at Unity’s tutorial video on cameras.
Go to the Scripts folder in the Project browser, right-click and choose Create\C# Script. Name the new script ScreenRelativePosition.
Open ScreenReltaivePosition.cs in MonoDevelop and add the following instance variables to the script:
public enum ScreenEdge {LEFT, RIGHT, TOP, BOTTOM};
public ScreenEdge screenEdge;
public float yOffset;
public float xOffset;
This first line defines an enum
type used to identify the four sides of the screen. You’ll assign screenEdge
in the Inspector to position an object at the center of that edge of the screen, and you’ll set xOffset
and yOffset to adjust the object’s position away from that point.
Add the following code inside Start
:
// 1
Vector3 newPosition = transform.position;
Camera camera = Camera.main;
// 2
switch(screenEdge)
{
// 3
case ScreenEdge.RIGHT:
newPosition.x = camera.aspect * camera.orthographicSize + xOffset;
newPosition.y = yOffset;
break;
// 4
case ScreenEdge.TOP:
newPosition.y = camera.orthographicSize + yOffset;
newPosition.x = xOffset;
break;
}
// 5
transform.position = newPosition;
To keep things easier to digest, the above code only includes the logic for positioning along the right and top sides of the camera’s view. Here is what it does:
- It copies the object’s current position, ensuring the object maintains whatever z position you set in the editor. It also gets a reference to the scene’s main camera, which it needs to calculate the new position. If you ever use this script in a scene with more than one camera, modify it so you can specify which camera it should use.
- It uses a
switch
statement to calculate the correct position based onscreenEdge
. All calculations assume the center of the screen is at position (0,0) because that keeps the sample code the simplest. However, it means that if the camera in your game moves, as it will in Zombie Conga, then this version of the script will only work on child objects of the camera. You’ll see more about this in a bit. - If
screenEdge
equalsScreenEdge.RIGHT
, it positions the object based on the camera’sorthographicSize
. Remember, the orthographic size is half the view’s height, so multiplying it by the camera’saspect
value gives you half the width, to which you addxOffset
. You assign the result asnewPosition
‘sx
value.
As fornewPosition
‘sy
value, you simply useyOffset
because you know the center of the right side of the view has a y value of zero. - If
screenEdge
equalsScreenEdge.TOP
, it simply addsyOffset
to the camera’sorthographicSize
and assigns the result asnewPosition
‘sy
value. Because you know the center of the top of the view has an x value of zero, you simply usexOffset
fornewPosition
‘sx
value. - Finally, it updates the object’s position with
newPosition
.
Before moving on with this script, you should test your code. Save the file (File\Save) and go back to Unity.
Choose GameObject\Create Other\Cube to add a cube to your scene. Don’t worry, it’s just for a quick test.
Now drag ScreenRelativePosition from the Project browser onto Cube in the Hierarchy.
Inside the Inspector, set Screen Edge to RIGHT in the Screen Relative Position (Script) component, as shown below:
Make a note of the cube’s position within the scene, then play the scene and notice that the cube centers itself on the center of the right edge of the Game view, as shown below:
Feel free to try out some other settings, remembering that you’ve only implemented RIGHT
and TOP
thus far. The following shows the cube positioned with Screen Edge set to RIGHT, YOffset set to 2, and XOffset set to -1.5:
Once you’re satisfied that your code works, right-click on Cube in the Hierarchy and choose Delete.
With positioning along the top and right edges working, switch back to MonoDevelop and try to add the cases for the left and bottom edges yourself. Check out the Spoiler below for a solution.
[spoiler title=”Need help finding the left or bottom of your screen?”]Inside ScreenRelativePosition.cs, add the following two case
statements to the switch
statement in Start
:
case ScreenEdge.LEFT:
newPosition.x = -camera.aspect * camera.orthographicSize + xOffset;
newPosition.y = yOffset;
break;
case ScreenEdge.BOTTOM:
newPosition.y = -camera.orthographicSize + yOffset;
newPosition.x = xOffset;
break;
The only difference between the case
for ScreenEdge.LEFT
and the case
you wrote earlier for ScreenEdge.RIGHT
is that you want to move in the opposite direction before applying xOffset
. You accomplish this by using negative camera.aspect
rather than positive camera.aspect
.
Likewise, the ScreenEdge.BOTTOM
case uses negative camera.orthographicSize
rather than the positive value used by the case
for ScreenEdge.TOP
.
[/spoiler]
When you’re done with the script, save it (File\Save) and switch back to Unity.
With ScreenRelativePosition.cs complete, you can now position objects in the same place regardless of screen size. You’ll use this in Zombie Conga to place the enemy’s spawn point just off the right edge of the screen.