Quantcast
Channel: Kodeco | High quality programming tutorials: iOS, Android, Swift, Kotlin, Unity, and more
Viewing all articles
Browse latest Browse all 4370

Physics Joints in Unity 2D

$
0
0

Screen Shot 2015-05-26 at 2.10.57 PMThe cross-platform game engine Unity has powerful support for creating 2D and 3D games. It’s a great choice for aspiring game developers, since it works for most mobile, desktop and console platforms, and even better, it’s free to use for lower-revenue developers and studios.

One of the key components of Unity are physics joints, which let you create various connections between objects in Unity. Using joints, you can describe a connection between two objects, which means you can simulate the physics of almost any multi-part object you can think of, including doors, sliding platforms, chains or even wrecking balls! :]

This tutorial will focus on using joints in Unity 2D, although Unity supports joints in its 3D engine as well.

Note: If you don’t have much experience with Unity, you’d do well to work through the Getting Started with Unity and What’s new in Unity 5 articles on this site.

Getting Started

First, ensure you have the latest version of Unity, which you can download here. This tutorial was using version 5.0.2f1. If you are using another version of the 5.x branch, chances are, this will work fine.

Next, download the 2D_Joints_Starter. Unzip it and open the 2d_Joints_Starter project in Unity. The Demo scene should open automatically, but if not, you can open it from the project’s Scene folder.

The scene should look as follows:

joints_at_launch

This scene contains various objects with physics components, much like you might find in any game. However, none of these shapes are connected by joints. Throughout this tutorial, you’ll get to try out each of Unity’s 2D joint types to see how they work.

Play the scene; you’ll see some of the objects immediately fall to earth due to the effects of gravity:

joints_initial_run

Note: While the labels in this scene are in fixed positions, the movement of the objects is based on the size of your Game view. For best results, put your Game view in Free Aspect mode and adjust its size in the Unity GUI until the objects and labels appear similar to the above image.

It’s time to get these objects working together with joints!

Distance Joint 2D

The first joint you’ll add – the Distance Joint 2D – has a very basic goal: to keep two objects separated by a constant distance. You’ll test this out on the red square and blue hexagon in the upper left of the scene.

Select Hexagon_Djoint in the Hierarchy and add a Distance Joint 2D Component to it, as shown below:

04

As you can see in the following image, this new component has several parameters that you can adjust to produce the best result for your game:

05

Fear not — you’ll soon learn what all these these parameters do and how you can adjust them.

You’ll notice that once you have the component attached to the Hexagon that a green line extends from the Hexagon to the center of the screen. This is the origin point (0,0).

Screen Shot 2015-05-20 at 5.34.41 PM

Run the scene, keeping your eye on the Hexagon.

distance-gif

Right away, you’ll notice that the Hexagon flies across the screen until it stops near the origin point, then begins to rock back and forth on the joint. The rocking behavior is the actual joint behavior, but what’s the deal with the initial jolt of energy? This is actual expected behavior and you’ll learn about it soon.

Turn your attention back the component in the Inspector. The Distance Joint 2D’s first parameter is Collide Connected. This determines whether or not the two objects connected by the joint can collide with each other. In this case, you don’t want this to happen, so leave it unchecked.

The second parameter is Connected Rigid Body. While one end of the distance joint always remains connected to the object that contains the component, you can use this field to pass a reference to an object for the other end of the joint’s connection. If you leave this field empty, Unity will simply connect the other end of the joint to a fixed point in the scene.

You want to connect Hexagon_Djoint to Square_Djoint in this case, so drag Square_Djoint to the Connected Rigid Body field:

06

With the connection set up and Hexagon_Djoint still selected, you should now see the two objects connected by the joint in the Scene view as follows:

distance_joint_connected

The next parameter is Anchor, which indicates where the end point of the joint attaches to the GameObject as specified in the object’s local coordinate space. In the Scene view, with Hexagon_Djoint selected, you can see the anchor point as an unfilled blue circle centered over Hexagon_Djoint in the image above In this case, leaving the value at (0, 0) is fine.

Note: The unfilled blue circle representing the joint’s first anchor point may appear filled if you currently have the Transform tool selected in the Scene view. Likewise, you will see a white square if you have the Scale tool selected. In either case, moving the anchor away from (0, 0) will show that it is indeed an unfilled circle.

The Connected Anchor parameter specifies the anchor point of the other end of the joint. If the Connected Rigid Body field is empty, this value is in the scene’s coordinate system. However, when Connected Rigid Body is set, as it is now, the Connected Anchor coordinates refer to the connected rigid body’s local coordinate space. This anchor point appears in the above image as a solid blue circle centered over Square_joint. Once again, you can leave this value at (0, 0).

The fifth parameter of the Distance Joint 2D is the one that bears its namesake: Distance. The name says it all: this parameter indicates the distance to maintain between both objects.

Back in the Scene view, you can see a small green line intersecting the line connecting the two objects; you can see this in the image below.

distance_joint_connected

This line indicates the distance enforced by the joint. When you run the scene, the joint will move Hexagon_Djoint so that the Anchor you defined is at the point where the small line. As you increase or decrease, the line will correspondingly move up or down.

distance-property

To give you a bit more room to see the joint in action, set Distance to 2, as shown below:

08

The last parameter is Max Distance Only. If enabled, the joint will only enforce a maximum distance, meaning that the objects can get closer to each other, but never further away than the value specified in the Distance field. In this example, you want the distance to be fixed, so leave this parameter disabled.

Run the scene and you should see that the hexagon attached to the square no longer falls from the scene:

09

While that’s sort of helpful, joints really only shine when one or more of their connections are moving. The project contains a helpful script that lets you drag objects with your mouse. Select Square_Djoint in the Hierarchy and drag Movement from the Scripts folder to the Inspector, as demonstrated below:

10

Run the scene; drag Square_Djoint around with your mouse to see your joint in action:

11

While you can see your joint working, you can’t actually see your joint. Sure, the Scene view shows a green line connecting the two objects, but the Game view doesn’t.

To get a better understanding of what’s happening, the project includes a script that renders a line between two objects at runtime. To visualize the joint, select Square_Djoint in the Hierarchy and drag Line from the Scripts folder to the Inspector:

12

Next, tell the Line script where to draw by dragging Square_Djoint and Hexagon_Djoint to Game Object 1 and Game Object 2 in the Inspector, as shown below:

13

Play your scene; you’ll see a line connecting the two objects:

14

Note: The Line script draws a line between the positions of two GameObjects. It doesn’t actually use the joint’s data, and as such, will not faithfully reproduce some joint settings. For example, if your distance joint does not specify a Connected Rigid Body, or if the anchors are not at (0, 0), then the line displayed will not properly visualize the joint’s location.

You’ll notice that no matter where you move the Square_Djoint, the Hexagon_Djoint will always be a certain distance from it. Run your scene again, only this time check the Max Distance Only property of the Distance Joint 2D. This will only enforce the max distance of the joint, allowing the two objects to pass through each other. Now when you you move the Square_Djoint, you’ll see a different behavior.

max-distance

Now that you’ve covered the Distance joint, the next logical step is to investigate Springs.

Spring Joint 2D

The Spring Joint 2D works in a similar way to distance joints. However, while distance joints enforce a fixed distance, spring joints apply tension to a connection, causing objects to bounce as if connected by, well, a spring! :]

To see how they work, select Hexagon_Sjoint in the Hierarchy and add a Spring Joint 2D component to it like so:

15

As you can see, this new component has several parameters that you can adjust:

16

Spring Joint 2D has several fields in common with Distance Joint 2D: Enable Collision, Connected Rigid Body, Anchor and Connected Anchor all work exactly the same way for springs as they do for distance joints, so there’s no need to re-explain these.

Before covering the other fields, first connect Square_Sjoint to the spring by dragging it from the Hierarchy tab and dropping it over the Connected Rigid Body field:

sjoint

Just like Distance Joint 2D, Spring Joint 2D contains a Distance field that specifies the distance the spring should try to maintain between the two objects. However, while distance joints strictly enforce this distance, spring joints bounce back and forth around this distance, gradually coming to a stop at the specified value.

Set Distance to 2:

18

The Damping Ratio specifies the degree of suppression for the spring oscillation. In other words, it determines how quickly the objects connected by the spring will come to a rest. Its value ranges from 0 to 1, with 0 being the slowest and 1 being the fastest. You’ll want to play around with this value to get the best result in your games, but for now, leave it at 0 to get a very bouncy spring.

Frequency indicates the frequency at which the spring oscillates in cycles per second; in other words, the number of times the spring bounces each second. This value should be higher than zero, where zero means the spring starts out at rest. Lower values produce stretchier springs and higher values produce tighter ones.

Frequency and Damping Ratio work together to produce the spring’s final behavior. You’ll usually need to tweak each of these quite a bit to get the perfect result for your game.

Once again, you’ll add mouse interaction and a line renderer to help see how this joint works. Add the Movement and Line scripts to Square_Sjoint. Make sure to set Game Object 1 and Game Object 2 references on the Line (Script) component to Square_Sjoint and Hexagon_Sjoint:

19

Play your scene; drag Square_Sjoint around the scene and give your spring a good workout:

20

Play around with the different values in both the Frequency and the Dampening values to get an idea of how the spring moves.

While the distance and spring joints are similar to each other, the next one — Hinge Joint — is quite different.

Hinge Joint 2D

The Hinge Joint 2D is slightly different from the last two. This specific joint lets a GameObject with a Rigidbody rotate around a fixed point. The joint calculates the correct rotation for the object when a force affects the object’s Rigidbody, meaning no additional script or code is needed. As you’ll soon see, hinge joints provide several configuration options so you can create various moving bodies such as doors, weight-triggered trap doors, water wheels and more.

In this example, you’ll make Square_Hjoint (which is actually a rectangle) rotate when you put some weight on it.

Select the Square_Hjoint and add a Hinge Joint 2D component to it:

21

This component contains quite a few new fields, along with some old favorites:

22

Once again, there’s Collide Connected, Connected Rigidbody, Anchor and Connected Anchor. These fields all work the same way as before.

This time, leave the Connected Ridigbody field empty to connect the joint to a point in space. Recall that when Connected Rigidbody is empty, the Connected Anchor coordinates are in the scene’s coordinate system. That means the default coordinates (0, 0) aren’t correct in this case.

Instead, place the anchor on the center of the rectangle by changing the Connected Anchor‘s X and Y values to -3.5 and -3.2, respectively:

23

The next parameters are specific to Hinge Joint 2D. Checking Use Motor makes the physics engine apply a constant force to rotate the joint in an effort to reach the specified speed. I say “in an effort”, because the Rigidbody might have other forces acting on it that speed up or slow down the rotation.

You specify the motor’s target speed in the Motor Speed field as a value in degrees per second. The motor will try to maintain this speed by applying torque to the joint. You can specify the maximum torque the motor may apply using the Maximum Motor Force field. The higher this value, the more the motor will resist external forces that might try to stop the rotation.

The Use Limits enables or disables rotation limits, which restricts the joint’s rotation between the specified Lower Angle and Upper Angle values.

In this example, you don’t want the platform to spin around in circles, so enable Use Limits and set Lower Angle to -245 and Upper Angle to 0.5:

limit_hinge_angles

The Scene view shows the extents of the joint’s rotation:

hinge_joint_in_scene

The balls in the scene already respond to gravity and re-spawn at their original position when they fall from the scene, as demonstrated below:

25

Play your scene; drag one of the balls and drop it over the Square_Hjoint to see how the platform rotates:

26

Try the same thing with the different balls in the scene; notice how bigger balls increase the speed of rotation. That’s because the three balls in the scene were each created with a different mass — this demonstrates how the hinge rotates differently based on the force applied.

To see the motor in action, select the Square_Hjoint in the Hierarchy and in the Inspector, check the Use Motor checkbox. Next set the Motor Speed to 500 and uncheck Use Limits.

Run your game. Now you’ll get movement without needing to anything. Congratulations! You defied physics and created a perpetual motion machine!

hinge

Uncheck Use Motor and check Use Limits for the rest of this tutorial.

Now that your platform spins, you’ll add a slider joint to create some more physics-based interaction.

Slider Joint 2D

Slider joints restrict an object’s movement along a line in space. In this section, you will use the hinge joint you just created to start another object moving along a slider joint.

Select Hexagon_Sljoint in the Hierarchy and add a Slider Joint 2D component to it:

27

The fields available in the Slider Joint 2D component are similar to those you saw in the hinge joint, but with a few semantic changes. Because slider joints deal in linear, rather than angular, motion, Motor Speed is measured in units per second. Likewise, instead of angle limits, you can specify translation limits. Translation limits work the same way as angle limits, except they specify the distance the Rigidbody can be from the Connected Anchor point:

28

Leave Connected Rigidbody empty and set Connected Anchor‘s X value to 4.3 and its Y value to -4.7:

29

You can see the path described by the joint in the Scene view as shown below:

slider_joint_scene

The one completely new field you see is Angle; this sets the angle between the Anchor point and the Connected Anchor point. The GameObject with the slider joint will reposition itself at runtime to match this angle.

Set the Angle to -45. You’ll notice a small green line in the scene view will replicate that angle.

Screen Shot 2015-05-25 at 2.29.55 PM

Now, run your game. You’ll see that instead the joint is now positioned at a forty five degree angle.

Screen Shot 2015-05-25 at 2.31.57 PM

Since you want Hexagon_Sljoint to move to the right of where it starts in the scene, set the Angle back to 0.

In order to see the joint’s path at runtime, add the Line script to Hexagon_Sljoint, set its Game Object 1 field to Hexagon_Sljoint and its Game Object 2 field to Square:

30

Play your scene; drop some balls on the hinged platform from the previous section. The platform should spin and bump into Hexagon_Sljoint, which will then slide along the path defined by the joint. The hexagon will move at different speeds depending on how fast you make the platform spin:

31

While you can make rotating objects with hinge joints, you’ll want to use a wheel joint to simulate things such as the wheels on a car.

Wheel Joint 2D

Wheel Joint 2d is the final joint you’ll explore in this tutorial; it simulates a rolling wheel you can connect to another object, complete with a suspension spring to provide some “give” between the wheel and its other anchor point.

This joint exists primarily to simulate the wheels of vehicles. However, in this example you’ll keep it simple and just use it to create a rotating platform.

Add a Wheel Joint 2D component to the Square_WJoint:

32

Most of this component’s fields should look familiar. One difference is that you shouldn’t leave Connected Rigid Body unset; Unity won’t complain if you do, but the wheel joint won’t do anything in that case.

33

To anchor your platform in the scene, set Connected Rigid Body to Hexagon_WJoint:

34

The Suspension section is unique to wheel joints. It includes three fields: Damping Ratio, Frequency and Angle. The first two work just like they did in Spring Joint 2D, while Angle works as it did in Slider Joint 2D.

These three properties work together to describe a spring that keeps the wheel separate from its anchor vehicle and oriented in a specific direction.

Play the scene; drop one of the balls over Square_Wjoint, near the center of the platform. You should see the platform move down and bounce back up along with its spinning motion — the end result of the Suspension settings:

35

To see the Wheel Joint really in action, create a new Scene by selecting File \ New Scene.

From the Sprites folder, drag a square into the Scene view. Set the Transform position to: (-3.6, -7.72, 0). Set the Scale to (14.43, 6.50, 1).

Click the Add Component button and give it a Box Collider 2D component. Set the Size to X: 2.29, Y: 2.31

Screen Shot 2015-05-25 at 5.37.16 PM

Give it the name: Ground. It should look like the following:

Screen Shot 2015-05-25 at 4.14.17 PM

Create a new Empty GameObject. Call it Car. Set the position to: (6.4,1.13,0).

Screen Shot 2015-05-25 at 4.32.42 PM

From the Sprite folder, drag the Car sprite from the Sprites folder and into the Car GameObject. Give it the name: Body. Set the transform to be: (0, 0, 0)

Screen Shot 2015-05-25 at 4.28.40 PM

From the Sprite folder, drag the Wheel sprite from the Sprites folder and into the Car GameObject.Do the same for both the wheels, positioning them in the empty wheel wells. Call them: FrontWheel and BackWheel.

Screen Shot 2015-05-25 at 4.33.45 PM

Next, add Rigidbody 2D components on the Body, Front Wheel, and BackWheel. With your Rigidbodies in place, add a Circle Collider 2D to the FrontWheel and BackWheel. Add a Polygon Collider 2D to the Body.

When you select the Car GameObject, your colliders will look like the following:

Screen Shot 2015-05-25 at 4.39.24 PM

Next, select the Body in the Inspector, and click the Edit Collider button.

Screen Shot 2015-05-25 at 4.46.16 PM

Drag the polygon collider around the wheel wells so that the wheels won’t collider with them.

car-collider

Select the Body in the Inspector. Add a Wheel Joint 2D to it. In the Connected Rigid Body property, add the FrontWheel. In the Anchor property, set X:-0.98 Y:-0.78. Check the Use Motor checkbox and set the Motor Speed to 500.

Screen Shot 2015-05-25 at 5.27.59 PM

With the Body still selected. Add another Wheel Joint 2D to it. In the Connected Rigid Body property, add the BackWheel. In the Anchor property, set X:1.15 Y:-0.84. Check the Use Motor checkbox and set the Motor Speed to 500.

Screen Shot 2015-05-25 at 5.30.09 PM

With your engine ready to go, play your scene. You’ll see your car take a ride!

car-driving

Where to Go From Here?

You can download a copy of the completed project here.

We hope you enjoyed this tutorial about 2D joints! If you’d like to learn more about Unity’s 2D joints, we suggest you check out the following resources:

If you have any comments or questions on this tutorial, feel free to join the discussion in the forums below!

Physics Joints in Unity 2D is a post from: Ray Wenderlich

The post Physics Joints in Unity 2D appeared first on Ray Wenderlich.


Viewing all articles
Browse latest Browse all 4370

Trending Articles