Physics in Unity

Physics in Unity

Physics in Unity

In this article, I will introduce the reader to the Physics system used in the Unity game engine. First, I will introduce the Physic Material Asset that is used to define physics properties for collider surfaces. I will also introduce Colliders and talk about the different kinds of Collider types you can create. The Rigidbody component is absolutely essential for performing physics simulations on GameObjects. I will show you how you can create a Rigidbody GameObject that can be user controlled. I will also talk about the Character Controller component that is provided by Unity to control upright characters. And finally, I will introduce the different Joints that are available in Unity.

Introduction

There is nothing real or natural about how things behave in computer games. They don’t know anything about the natural physical phenomenon that exists in reality. If you place a bunch of objects in a scene in Unity, these objects will not naturally know what they are supposed to do. They won’t even be affected by gravity unless you explicitly tell them what gravity is. Game engines (like Unity) require Physics to be simulated using a Physics Engine. The Physics Engine tries to simulate physics in your game so that the objects in your game demonstrate natural physical phenomenon.

Physics components in Unity are split into several categories:

  • Physics Material: The Physic Material is an Asset type that describes how a physically controlled object reacts to other physically controlled objects.
  • Collider: The Collider components are used to describe the collision shape of an object.
  • Rigidbody: The Rigidbody component is required to allow your GameObject to be controlled by the physics engine and influence other physics controlled objects.
  • Character Controller: The Character Controller component is most commonly used on up-right character models. It’s used to move the character around the scene without a Rigidbody attached to the GameObject but still performs collision detection on other colliders in your scene.
  • Cloth: Unity provides a few components that can be used to simulate cloth behavior in your game. This is useful for capes or dresses, or simulating flags or banners.
  • Joints: Joints allow you to define a constraint between two Rigidbodies. This is useful for hinges or creating springs between two objects.

In this article, I will introduce you to the physics system in Unity and give you an idea of how it works so that you can implement your physics controlled objects correctly in your own games.

Physics Material

The Physic Material is an Asset type that can be assigned to Colliders. The Physic Material describes both the friction and bounciness of a physics controlled object.

Unity - Physic Material

Unity – Physic Material

The Physic Material has the following properties:

  • Dynamic Friction: The Dynamic Friction property determines the friction that is applied while the object is in motion. This property usually has a value in the range 0 to 1. A value of 0 will cause no friction to be applied to the surface and a value of 1 will cause the object to slow down very quickly when it is in contact with another surface.
  • Static Friction: The Static Friction property determines the friction that is applied while the object is not moving. A value of 0 will allow the object to start moving very easily. A value of 1 will take a lot of force to get the object to start moving.
  • Bounciness: Determines how much the object will bounce when it hits another collider. With a value of 0, the object will not bounce at all (all kinetic energy will be absorbed). With a value of 1, the object will bounce indefinitely (all kinetic energy will be maintained). With a value greater than 1 will cause the object to bounce higher (it will gain kinetic energy).
  • Friction Combine: Determines how the friction of the two colliding objects is combined:
    • Average: The applied friction is the average friction between the two colliders.
    • Multiply: The applied friction is the product of the friction of both colliders.
    • Minimum: The applied friction is the minimum friction of either collider.
    • Maximum: The applied friction is the maximum friction of either collider.
  • Bounce Combine: Determines how the bounciness of the two colliding objects is combined:
    • Average: The applied bounciness is the average bounciness between the two colliders.
    • Multiply: The applied bounciness is the product of the bounciness of both colliders.
    • Minimum: The applied bounciness is the minimum bounciness of either collider.
    • Maximum: The applied bounciness is the maximum bounciness of either collider.
  • Friction Direction 2: The Friction Direction 2 is a vector in object local space that can be used to simulate surfaces that can slide easier in one direction than in the other. For example, a corrugated surface that can slide easily in the direction of the corrugated grooves, but tend to resist motion opposite to the corrugated groves.
  • Dynamic Friction 2: The amount of dynamic friction to apply in the direction of Friction Direction 2 while the object is in motion.
  • Static Friction 2: The ammount of static friction to apply in the direction of Friction Direction 2 while the object is at rest.

Unity provides a few default Physic Materials in the standard packages for Ice, Metal, Rubber, and Wood.

Frictionless Physic Material

To create a completely friction-less material, create a new Physic Material asset in the Project view and set it’s properties to the following values:

  • Dynamic Friction: 0
  • Static Friction: 0
  • Friction Combine: Minimum

Leave the other properties as their defaults.

The Bounciness properties don’t effect friction, so you can set them to anything you want.

We’ll use this frictionless Physic Material later when we start playing with Rigidbody components.

Colliders

Colliders are used to define the collision shape of objects in your scene. Unity provides three primitive collider types: Box, Sphere and Capsule. Unity also provides a Mesh Collider component that can be used to represent a simplified version of your complex meshes. For vehicles, Unity also provides a Wheel Collider component and a Terrain Collider component that can be used on terrains.

Trigger Collider

Any Collider type (Box, Sphere, Capsule, Mesh, and Terrain) can be used as a Trigger by setting the Is Trigger property to true. If the Collider is a Trigger we call it a Trigger Collider. Trigger Colliders will not participate in physics simulations but they will fire the OnTriggerEnter, OnTriggerStay, and OnTriggerExit events on the GameObject they are attached to as long as the collider that intersected with the trigger is a Rigidbody Collider (see below).

If you place a Rigidbody on a Trigger Collider, it will be effected by gravity (if the Use Gravity property is true on the Rigidbody component) but it will not collide with other colliders in your scene. If you have Rigidbody objects in your scene that are falling through the floor, make sure the collider component does not have the Is Trigger property set to true.

Trigger Colliders can be used for many different things. You can place a Trigger Collider near a doorway that opens the door when the player enters the collider and closes the door when the user exits the Trigger Collider.

Unity - Trigger Collider

Unity – Trigger Collider

In the image above, we see a screenshot from the game AngryBots that ships with Unity 3.5. The green box centered on the door is used to play the door opening animation when the player enters the trigger area and plays the door opening animation in reverse when the player exits the trigger area.

Static Collider

A Static Collider is any non-trigger Collider without a Rigidbody component. Without a Rigidbody component, an object will not be influenced by physics. Static Colliders can be used to block GameObjects with Rigidbody components but no matter how hard another Rigidbody component hits a Static Collider, the Static Collider will not move. Static Colliders are ideal for the walls, floors, and other fixed (static) level decoration in your scene.

Rigidbody Collider

A Rigidbody Collider on the other hand, is a Collider with a Rigidbody component. Rigidbody Colliders will be simulated by physics and they will collide with other Static Colliders and Rigidbody Colliders. They will not collide with (be blocked by) Trigger Colliders but they will receive the OnTriggerEnter, OnTriggerStay, and OnTriggerExit events if they move into the area defined by the Trigger Collider.

Kinematic Rigidbody Collider

A Kinematic Rigidbody Collider is a Rigidbody Collider with the Is Kinematic flag set to true on the Rigidbody component. Kinematic Rigidbody Colliders will not be influenced by physics and they must be moved using the GameObject’s Transform component (using the transform.position and transform.rotation). Kinematic Rigidbody Colliders are commonly used on animated characters. While the character is animated, the Rigidbody component will be kinematic but if you want to switch the character to a Ragdoll state, you will disable the Is Kinematic flag and the character will act like a limp doll and fall to the floor.

Kinematic Rigidbody Colliders will only collide with other Rigidbody Colliders. Kinematic Rigidbody Colliders will push other Rigidbody Colliders but they will not react to being pushed by other Rigidbody Colliders.

Kinematic Rigidbody Colliders will not collide with Static Colliders.

Collision Matrix

The following table shows which collider types will perform collision detection. The OnCollisionEnter(), OnCollisionStay(), and OnCollisionExit() messages will also be sent on GameObjects that meet the collision requirements. Also keep in mind that only colliders that also have a Rigidbody will react to collisions, that is, they will be pushed by other Rigidbody colliders.

Collision detection occurs and messages are sent upon collision
  Static Collider Rigidbody Collider Kinematic Rigidbody Collider Static Trigger Collider Rigidbody Trigger Collider Kinematic Rigidbody Trigger Collider
Static Collider   Yes        
Rigidbody Collider Yes Yes Yes      
Kinematic Rigidbody Collider   Yes        
Static Trigger Collider            
Rigidbody Trigger Collider            
Kinematic Rigidbody Trigger Collider            

[Source]

Trigger Matrix

The following table shows which collider types will fire Trigger events. The OnTriggerEnter(), OnTriggerStay(), and OnTriggerExit() events will also be called on colliders that meet the trigger requirements. Keep in mind that trigger events will only be called on Trigger Colliders.

Trigger messages are sent upon collision
  Static Collider Rigidbody Collider Kinematic Rigidbody Collider Static Trigger Collider Rigidbody Trigger Collider Kinematic Rigidbody Trigger Collider
Static Collider         Yes Yes
Rigidbody Collider       Yes Yes Yes
Kinematic Rigidbody Collider       Yes Yes Yes
Static Trigger Collider   Yes Yes   Yes Yes
Rigidbody Trigger Collider Yes Yes Yes Yes Yes Yes
Kinematic Rigidbody Trigger Collider Yes Yes Yes Yes Yes Yes

[Source]

Box Collider

The Box Collider is a basic cube-shaped collision primitive. It is commonly used to mimic the shape of cube like objects such as crates and boxes, the hull of a car, walls, doors, tables, and other level geometry that resembles the shape of a cube.

Unity - Box Collider

Unity – Box Collider

The Box Collider is also a very common primitive collider that is used to create triggers in your game (as shown in the Angry Bots screenshot above).

The Box Collider has the following properties:

Unity - Box Collider Properties

Unity – Box Collider Properties

  • Is Trigger: If true, this collider will be considered a Trigger Collider and will no longer be influenced by physics but it will fire Trigger events on other Rigidbody colliders.
  • Material: The Physics Material that determines the friction and bounce of this object. The Physics Material is irrelevant if this is a Trigger Collider.
  • Center: The X, Y, Z, position of the Collider relative to the GameObject’s Transform.
  • Size: The scale of the collider relative to the GameObjects’s scale.

[Source]

Sphere Collider

The Sphere Collider is similar to a Box Collider except it resembles the shape of a sphere instead of a cube.

Unity - Sphere Collider Properties

Unity – Sphere Collider Properties

The Sphere Collider has the following properties:

  • Is Trigger: If true, this collider will be considered a Trigger Collider and will no longer be influenced by physics but it will fire Trigger events on other Rigidbody colliders.
  • Material: The Physics Material that determines the friction and bounce of this object. The Physics Material is irrelevant if this is a Trigger Collider.
  • Center: The X, Y, Z, position of the Collider relative to the GameObject’s position.
  • Radius: The radius of the collider relative to the GameObjects’s scale.

[Source]

Capsule Collider

The Capsule Collider resembles the shape of a capsule. It is most commonly used to approximate the size and shape of a character. The Capsule Collider is also commonly used on the bones of an animated character. When the character is hit by something, the capsule colliders can be switched from kinematic to physics controlled so the character falls to the floor like a ragdoll.

Unity - Ragdoll

Unity – Ragdoll

Unity - Capsule Collider Properties

Unity – Capsule Collider Properties

The Capsule Collider has the following properties:

  • Is Trigger: If true, this collider will be considered a Trigger Collider and will no longer be influenced by physics but it will fire Trigger events on other Rigidbody colliders.
  • Material: The Physics Material that determines the friction and bounce of this object. The Physics Material is irrelevant if this is a Trigger Collider.
  • Center: The X, Y, Z, position of the Collider relative to the GameObject’s position.
  • Radius: The radius of the capsule’s body.
  • Height: The length of the capsule body.
  • Direction: The axis of the capsule’s lengthwise orientation relative to the the GameObject’s local space.

[Source]

Mesh Collider

The Mesh Collider uses a mesh to define the shape of the collider. Mesh Collider can produce more accurate representations of the collision shape of the object, but it is much more expensive to compute collision detection on complex mesh colliders than using primitive colliders (The Box, Sphere, and Capsule colliders are considered primitive colliders). Don’t use a mesh collider when a primitive collider will work just as well.

Unity - Mesh Collider

Unity – Mesh Collider

The Mesh Collider has the following properties:

  • Is Trigger: If true, this collider will be considered a Trigger Collider and will no longer be influenced by physics but it will fire Trigger events on other Rigidbody colliders.
  • Material: The Physics Material that determines the friction and bounce of this object. The Physics Material is irrelevant if this is a Trigger Collider.
  • Convex: If the Convex property is true, a simplified version of the mesh collider will be generated. Convex mesh colliders will collide with other Mesh Colliders.
  • Smooth Sphere Collision: Collision mesh normals are smoothed across the collision faces. This should be enabled on gradually slopped surfaces such as terrains and roads.
  • Mesh: The Mesh asset that is used to generate the collision mesh for this Mesh Collider.

Primitive Rigidbody Colliders will perform collision detection on Static Mesh Colliders but Rigidbody Mesh Colliders will not collide with other Mesh Colliders unless one of them is set to Convex.

Compound Colliders

Sometimes it is better to combine several primitive colliders to represent an object rather than use a complex mesh collider. Or maybe you want to combine several objects together so they behave as a single object.

To do this, we simply create a parent-child hierarchy of colliders.

Unity - Complex Colliders

Unity – Complex Colliders

The image above shows a Cylinder with a Sphere at each end of it. The Sphere GameObjects are parented to the Cylinder GameObject. As a result, the combination of all three GameObjects will behave as a single object. If you need the GameObject to be physics controlled, then add a Rigidbody component to the top-level object only. Do not add Rigidbody components to the child GameObjects (if you do, they will behave as separate objects and break off the compound shape).

[Source]

Rigidbodies

The Rigidbody component is required for objects to act under the influence of Physics. You can apply forces and torques to the Rigidbody component from scripts or you can directly manipulate the linear and angular velocity of the Rigidbody if you want more control over it’s behavior.

A Rigidbody component requires a Collider component to be present on the GameObject for correct Physics simulation.

A Rigidbody can either be Physics controlled or Kinematic controlled.

Physics Rigidbody

A Physics Rigidbody is fully controlled by the Physics engine. You can apply forces and torques to manipulate the linear and angular velocities but you cannot move the Rigidbody directly by using the GameObject’s Transform component (well, actually you can update the position and orientation of a Physics Rigidbody but it isn’t recommended).

To create a Physics Rigidbody, simply add the Rigidbody component to the GameObject you want to be influenced by physics and make sure the Is Kinematic property is not checked.

Unity - Physics Properties

Unity – Physics Rigidbody

Kinematic Rigidbody

A Kinematic Rigidbody will not act under the influence of the physics engine. You cannot apply forces or torques to to a Kinematic Rigidbody (well, actually you can apply forces and torques to a Kinematic Rigidbody but they just wont do anything). You also cannot rely on the Rigidbody’s linear and angular velocity properties being valid.

The only way you can move a Kinematic Rigidbody around the scene is by directly updating the GameObject’s Transform component.

Unity - Kinematic Rigidbody

Unity – Kinematic Rigidbody

Properties of a Rigidbody

The Rigidbody component has the following properties:

  • Mass: The mass of the Rigidbody. The mass of a Rigidbody should be based on the relative size and density of the object it is attached to. For example, a large feather will have a much lower mass than relatively small rock or stone. The mass has a direct influence on how much force is required to move the Rigidbody. A very large mass will require more force to move it than a similar sized object with less mass. If you remember the formula from your basic physics lessons, then you will know that in order to get am object that weighs 10 kg to a speed of 5 meters per second (m/s) in just one second, you must apply a force of 50 newtons () assuming we neglect all other external forces such as friction, drag, and gravity. An object that has a mass of 5 kg only requires 25 newtons to accelerate it to a speed of 5 meters per second in one second.
  • Drag: The Drag parameters controls how fast the object’s linear velocity is reduced due to air resistance. With a Drag value of 0, the object will not be affected by air resistance (this simulates how Rigidbodies will behave in outer space). A very high drag can be used to make the object slow down very quickly if no external forces are applied to the rigidbody. An object with a mass of 1 requires a Drag value of approximately 998 to resist the force of gravity.
  • Angular Drag: The Angular Drag property is similar to the Linear Drag property in that it is used to slow the angular velocity of the Rigidbody. If you want your Rigidbodies to stop spinning very quickly, set the Angular Drag property to a high value. A value of 0 will allow the Rigidbody to keep spinning indefinitely unless acted upon by an external force (such as friction).
  • Use Gravity: Should this Rigidbody be affected by gravity?
  • Is Kinematic: This property should be set to true if you want to directly control the position and orientation of the Rigidbody using the GameObject’s Transform component. Kinematic Rigid Bodies will not be influenced by physics and will only collide with other non-kinematic Rigidbody Colliders. Kinematic Rigidbodies will not collide with Static Colliders or other Kinematic Rigidbodies.
  • Interpolate: If you find that your Rigidbody is not moving smoothly, you can adjust the interpolation method.
    • None: The position and orientation of the Rigidbody is not smoothed between frames. This is the default value.
    • Interpolate: The position and orientation of the Rigidbody is smoothed based on the position and orientation of the previous frame.
    • Extrapolate: The position and orientation of the Rigidbody is smoothed based on the estimated position and orientation of the next frame.
  • Collision Detection: This property determines how this Rigidbody performs collision detection with other Rigidbodies in the scene.
    • Discreet: This is the simplest form of collision detection. At each frame, the current position and orientation of the object is sampled and collision intersection tests are performed on nearby colliders. Using this method of collision detection, it is possible that small, fast moving objects will appear to pass directly through solid objects.
    • Continuous: This Rigidbody will perform Continuous Collision Detection (CCD) against other Static Colliders and also on Rigidbody Colliders whose Collision Detection method is set to Continuous Dynamic. On all other collider types, it will only perform Discreet collision detection.
    • Continuous Dynamic: You should only set this value on fast moving objects. Rigidbodies whose Collision Detection method is set to Continuous Dynamic will perform CCD on other Rigidbodies that are either set to Continuous or Continuous Dynamic. Continuous Dynamic Rigidbodies will also perform CCD on Static Colliders. For all other collider types, it will only perform Discreet collision detection.
  • Constraints: The position and orientation of the Rigidbody can be constrained so that it doesn’t move or rotate along specific axes. These constraints will not effect Kinematic Rigidbodies.
    • Freeze Position: Constrain the linear motion of the Rigidbody along one or more global axes. This is useful if you are making a 2D game and you don’t want objects to fly towards or away from the viewer. To prevent motion in the depth, you can simply constrain the motion in the Z-axis.
    • Freeze Rotation: To prevent an object from rotation due to Torque forces, you can constrain the rotation of the Rigidbody along one or more global axes. This may be useful if you want to make a 2D game and you only want objects to rotate around the look-at direction. In this case, you would constrain both the X and Y axes and allow free rotation along the Z-axes.

[Source]

Rigidbody Tutorial

In some cases, you may want to represent your main character by another shape other than an upright capsule. Maybe your main character is a cube, or a sphere? The Character Controller component (described in the next section) may not be suitable for you in this case. But how can we get a Rigidbody Collider to act like a Character Controller?

Create a New Scene

Open Unity and either open an existing project or create a new one.

Create a new Scene if you don’t already have one.

Unity - Rigidbody Tutorial (1)

Unity – Rigidbody Tutorial (1)

Create a Plane

Add a Plane GameObject and set it’s properties to:

  • Plane
    • Position
      • X: 0
      • Y: 0
      • Z: 0
    • Rotation
      • X: 0
      • Y: 0
      • Z: 0
    • Scale
      • X: 10
      • Y: 1
      • Z: 10

Create a Rigidbody Collider

Create a Cube GameObject and add a Rigidbody component to it. Place it just above the plane so that it doesn’t fall through. Rename the cube to “Rigidbody Collider

Unity - Rigidbody Tutorial (2)

Unity – Rigidbody Tutorial (2)

Create a red Diffuse material and add it to the newly created cube (to learn about materials, refer to my previous article titled Render and Special Effects in Unity 3.5).

Unity - Rigidbody Tutorial (3)

Unity – Rigidbody Tutorial (3)

Create a Static Collider

Create another cube without a Rigidbody. Make this one blue. Rename the GameObject to “Static Collider“.

Unity - Rigidbody Tutorial (4)

Unity – Rigidbody Tutorial (4)

Create a Trigger Collider

Create another cube without a Rigidbody and set the Is Trigger property on the Box Collider to true. Make it green and rename the GameObject to “Trigger Collider“.

Unity - Rigidbody Tutorial (5)

Unity – Rigidbody Tutorial (5)

Trigger Script

Add the following JavaScript (let’s call the script “TriggerAnimation.js”) to the Trigger Collider GameObject:

#pragma strict

@script RequireComponent(AudioSource)
@script RequireComponent(Animation)

var animationClip : AnimationClip;

var enterAudioClip : AudioClip;
var exitAudioClip : AudioClip;

function Awake()
{
	// Add the animation clip and make it default.
	animation.AddClip( animationClip, animationClip.name );
	animation.clip = animationClip;
}

function OnTriggerEnter( other : Collider )
{
	animation[animationClip.name].speed = 1.0;
	animation[animationClip.name].time = 0.0f;
	animation.Play();
	
	audio.clip = enterAudioClip;
	audio.Play();
}

function OnTriggerExit( other : Collider )
{
	animation[animationClip.name].speed = -1.0;
	animation[animationClip.name].time = animation[animationClip.name].length;
	animation.Play();
	
	audio.clip = exitAudioClip;
	audio.Play();
}

This script simply plays an Animation Clip and Audio Clip when another Rigidbody Collider enters and exits the area defined by the Trigger Collider.

Create a simple Animation Clip using the Animation view and drag-and-drop the animation clip from the Project view on to the the Animation Clip property for Trigger Animation script component in the Inspector view.

Get two Audio Clip assets and drag-and-drop the audio clips from the Project view onto the Enter Audio Clip and Exit Audio Clip properties for the Trigger Animation script component in the Inspector view.

Create a Controllable Rigidbody

Add a fourth cube GameObject to the scene. Rename this GameObject to “Rigidbody Controller“.

Unity - Rigidbody Tutorial (6)

Unity – Rigidbody Tutorial (6)

Add the following JavaScript (let’s call it “RigidbodyController.js”) to the Rigidbody Controller GameObject.

#pragma strict

@script RequireComponent(Rigidbody)

private var isGrounded = false;

enum MotionMethod
{
	VELOCITY_BASED_MOTION,
	MOVE_BASED_MOTION,
}

var motionMethod = MotionMethod.VELOCITY_BASED_MOTION;

// Multiply the velocity when using the velocity based motion.
var velocityMultiplier = 200.0f;

// Multiply the move distance when using move based motion.
var moveMultipler = 5.0f;

// Multiply the force to make the cube jump.
var jumpMultipler = 500.0f;

function FixedUpdate() 
{
	// Calculate the velocity/move direction based on the user input.
	var moveDirection = Vector3( Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical") ) * Time.deltaTime;
	moveDirection = Camera.main.transform.TransformDirection( moveDirection );
	
	if ( rigidbody != null && !rigidbody.isKinematic )
	{
		switch ( motionMethod )
		{
			case MotionMethod.VELOCITY_BASED_MOTION:
				// Speed up the rigidbody in the x-z plane. The velocity in the y-axis is maintained so that gravity still works.
				rigidbody.velocity = Vector3( moveDirection.x * velocityMultiplier, rigidbody.velocity.y, moveDirection.z * velocityMultiplier);
				break;

			case MotionMethod.MOVE_BASED_MOTION:

				rigidbody.MovePosition( rigidbody.position + ( moveDirection * moveMultipler ) );
				// Zero the velocity in the X,Z plane.
				// We could do this by "Freezing" the X, Z position of the rigid body in the inspector, but then it would
				// pass-through other rigid bodies without doing collision.
				rigidbody.velocity = Vector3( 0, rigidbody.velocity.y, 0 );
				break;
		}
	
		if ( Input.GetButtonDown("Jump") && isGrounded )
		{
			rigidbody.AddForce( Vector3.up * jumpMultipler );
		}
	}
	else
	{
		// Static Colliders and Kinematic Rigidbody Colliders manipulate the transform directly.
		transform.position += moveDirection;
	}
}

function  OnCollisionStay(collisionInfo : Collision)
{	
	// To be more accurate, you may want to check if the collision normal 
	// is pointing in the opposite direction as gravity.  Then it is more reasonable to 
	// assume that it is colliding with the ground.
	isGrounded = true;
}

function OnCollisionExit( collisionInfo : Collision )
{
	isGrounded = false;
}

The RequireComponent script attribute ensures that the GameObject that this script is being attached to will have a Rigidbody component attached to it.

We also declare a private variable called isGrounded which is used to check if the character is currently standing on the ground.

The Enumeration called MotionMethod is used to switch between velocity-based motion (where the velocity of the Rigidbody is directly affected in order to make the Rigidbody move, and move-based motion where the rigidbody is moved using the Rigidbody.MovePosition method to move the rigidbody. By default, we will use velocity-based motion.

On lines 16, 19, and 22 a few public variables are declared that will be used to multiply the base veclocity, move speed, and jump height to achieve the desired movement.

Since we are performing motion operations on Physics bodies, we should perform these operations in the FixedUpdate method (as opposed to the Update method). The reason for this was discussed in the article titled “Scripting in Unity“.

In the FixedUpdate method, we first determine the relative direction to move based on the input axes. The moveDirection vector is transformed by the transformation matrix of the main camera. This makes the move direction always relative to whatever direction the main camera is facing (so left is always left and right is always right depending on the direction the camera is facing).

On line 30, we first check to see if the rigidbody component is set to Kinematic. If it isn’t then we will use the rigidbody’s velocity property to move the rigidbody through the scene.

If the motion method property is set to velocity-based motion (the first case) then we will create a vector that will be used to manipulate the velocity of the rigidbody directly. Notice that we don’t change the Y-axis of the velocity vector. We do this because we don’t want to cancel the effect of gravity on the rigidbody.

If the motion method property is set to move-based motion (the second case) then we use the rigidbody’s MovePosition method to move the rigidbody in the scene. If we use this method to move the rigidbody, then we must also zero the veloctiy (line 45). If we don’t do this, the rigidbody will maintain any velocity that may have been introduced by a collision. Notice that I don’t zero the velocity in the Y-axis because I don’t want to remove the effect of gravity.

On line 49, we apply a “Jump” force only if the rigidbody is grounded (we don’t want to allow jumping in mid-air). The jump is applied as an upward force on the rigidbody multiplied by the jumpMultiplier.

The else statement on line 54 will be executed if the rigidbody is set to a Kinematic Rigidbody. In this case, the rigidbody will be moved by manipulating it’s Transform component directly.

The OnCollisionStay and OnCollisionExit functions are used to determine if the rigidbody is on the ground or not.

If you play the game now, you may notice the Rigidbody Controller cube will move, but it rolls… How can we fix this?

Hint: Frictionless Physic Material.

Character Controller

The Character Controller component is commonly used on upright biped characters. Using a Character Controller does not require a Rigidbody to be present on the character to get the character to move. Although collision detection will work correctly on Character Controllers, collision resolution will not work automatically; that is, when a Character Controller hits a Rigidbody Collider, it will not automatically apply forces to the Rigidbody Collider in order to get it to move. If you want a (non-static) Rigidbody Collider to react to the Character Controller colliding with it, you must script this yourself.

Unity - Character Controller

Unity – Character Controller

The image above shows the green capsule around the Constructor character. The green capsule shows the radius and height of the Capsule Collider created by the Character Controller. It is currently not possible to change the collision shape of the Character Controller to something other than a Capsule.

The Character Controller has the following properties:

  • Slope Limit: The maximum slope angle (measured in degrees) the character controller can walk up before he will be pushed back. This is useful for preventing your character from climbing steep slopes on a terrain for example.
  • Step Offset: The maximum height the character controller will step over. If an obstacle is higher than Step Offset above the current height of the character controller (measured from the ground), the Character Controller will be blocked by that obstacle. Otherwise, he will step onto the obstacle. Of course, if you want your character to visually look like he is stepping onto the obstacle, you must create an animation for that and play it at the right time.
  • Skin Width: This value allows the Collider to interpenetrate with other Colliders. If your character motion is jittery or your character is getting stuck in some cases, chances are your Skin Width is too low. A good rule of thumb is the Skin Width should be about 10% of the Radius property.
  • Min Move Distance: If the character is moved less distance than this value, the character will not move at all. Generally, this value should be left at 0.
  • Center: The center point of the Capsule Collider relative to the GameObject’s position.
  • Radius: The width of the Capsule Collider along the Y-axis. If your character seems to be able to walk partially through walls, you may want to increase the Radius value. If you character can’t get close enough to objects, you may want to decrease the Radius value.
  • Height: The height of the Capsule Collider. If the character seems to be floating above the ground, you will want to decrease the Height value. If the character’s feet are sinking into the ground, then you will want to increase the Height value.

Character Controller Tutorial

What do we do if we want our Character Controller to apply forces to other Rigidbody Colliders? The only way we can accomplish this is to apply a force to the other Rigidbody Collider in script.

Create a New Scene

Open Unity with an existing project, or create a new project and create a new Scene.

Unity - Character Controller Tutorial (1)

Unity – Character Controller Tutorial (1)

Add a Plane GameObject and set it’s properties to:

  • Plane
    • Position
      • X: 0
      • Y: 0
      • Z: 0
    • Rotation
      • X: 0
      • Y: 0
      • Z: 0
    • Scale
      • X: 10
      • Y: 1
      • Z: 10
Unity - Character Controller Tutorial (2)

Unity – Character Controller Tutorial (2)

Add a Cube and a Sphere GameObject to your scene. Make sure they are placed just above the Plane so that they are not intersecting with the Plane.

Unity - Character Controller Tutorial (3)

Unity – Character Controller Tutorial (3)

Add a Rigidbody Component to both the Cube and the Sphere GameObject. This will allow them to be influenced by Physics.

Duplicate (Ctrl+D) the Cube and the Sphere objects a few times in your scene and place the duplicates so that they are neither intersecting each other nor the Plane.

Unity - Character Controller Tutorial (4)

Unity – Character Controller Tutorial (4)

Add a light to your scene to illuminate the objects.

Unity - Character Controller Tutorial (5)

Unity – Character Controller Tutorial (5)

Optionally, you can also add various Physic Materials to the GameObjects to see how different values for the Physic Material effect the way the Rigidbody Colliders react to being pushed. If you havn’t done so already, you can import the Physic Material standard package that comes with Unity by selecting Assets -> Import Package -> Physic Material from the main menu. You can also create a frictionless material by following the steps outlined in the section about Physics Materials.

Add a Character Controller

If you haven’t done so already, import the Character Controller standard package into your project (select Assets -> Import Package -> Character Controller from the main menu).

The Character Controller package provides prefabs for a standard first-person controller and a third-person controller.

Drag-and-drop the “3rd Person Controller” prefab from the “Standard Assets\Character Controllers” folder in your project view into the scene. Make sure the character is placed above and not intersecting with the Plane.

Unity - Character Controller Tutorial (6)

Unity – Character Controller Tutorial (6)

In the Third Person Controller script component attached to the 3rd Person Controller prefab you just created, make sure you set the Idle Animation property to the idle Animation Clip, the Walk Animation property to the walk animation clip, the Run Animation property to the run animation clip, and the Jump Pose Animation property to the jump_pose animation clip.

If you play this now, you will notice that the Constructor character will collide with the Rigidbody Colliders in the scene, but will not push any of them out of the way.

Character Controller Push Script

Fortunately, we can create a script that will push the Rigidbody Colliders by applying a force to the Rigidbody when the Character Controller collides with it.

Create a new JavaScript script asset in your project. You can call it whatever you want, but I called mine “CharacterControllerPushRigidbody“.

Open the newly created script in Mono and add the following code:

#pragma strict

var forceMode : ForceMode = ForceMode.VelocityChange;
var pushPower = 2.0f;

function OnControllerColliderHit (hit : ControllerColliderHit) 
{
	// Get the hit rigidbody (if there is one).
    var body : Rigidbody = hit.rigidbody;

    // no rigidbody
    if (body == null || body.isKinematic)
        return;
        
    // We dont want to push objects below us
    if (hit.moveDirection.y < -0.3) 
        return;
    
    // Calculate push direction from move direction, 
    // we only push objects to the sides never up and down
    var pushDir : Vector3 = Vector3 (hit.moveDirection.x, 0, hit.moveDirection.z);

    // Apply the push
	body.AddForceAtPosition( pushDir * pushPower, hit.point, forceMode );
}

The first thing we see in this script (after the "#pragma strict" statement) is a variable called forceMode of type ForceMode. This variable determines how the force is applied to the Rigidbody that we collided with. The ForceMode enumeration has the following values:

  • Force: Adds a force to the Rigidbody taking the Rigidbody's mass into consideration. Using this method, larger forces will be needed in order to accelerate Rigidbodies with greater mass.
  • Acceleration: Adds a continuous acceleration to the Rigidbody, ignoring it's mass. Using this mode, the object will immediately accelerate regardless of it's mass.
  • Impulse: Adds an instatnous force impulse to the Rigidbody taking it's mass into consideration.
  • VelocityChange: Instantly changes the velocity of the Rigidbody regardless of it's mass.

On line 4, we declare a variable called pushPower. This value determines the amount of force, acceleration, impulse, or velocity (depending on the value of the forceMode variable) that will be applied to the Rigidbody we collided with.

On line 6, we declare a function called OnControllerColliderHit. This method is valid on GameObjects with a Character Controller component attached to them. It is invoked when the Character Controller collides with another Collider (Rididbody Collider or Static Collider) while performing a Move. This method takes a single argument called hit of type ControllerColliderHit that is used to determine which other Collider was hit and where it was hit.

On line 9, we extract the Rigidbody component that was hit (if there is one).

If the Collider we hit is a Static Collider (that is, it does not have a Rigidbody) or it is a Kinematic Rigidbody Collider (in which case, it is not physics controlled), then we don't want to do anything.

For this script, we will also ignore collisions that occured while the Character Controller is falling (it's move direction in the Y-axis is less than 0).

On line 21, we create a direction vector which represents the direction the Character Controller was moving (in the XZ-plane) when the collision occured.

And finally on line 24, we apply a force to the Rigidbody at a paticular point in global space. This is done by calling the AddForceAtPosition method on the Rigidbody.

The Rigidbody.AddForceAtPosition function takes the following arguments.

  • force : Vector3: The direction and magnitude of the force to apply to the Rigidbody.
  • position : Vector3: The position in world space to apply the force. If this position is not the same as the current position of the Rigidbody then an angular force as well as a linear force will be applied to the Rigidbody. This could cause the Rigidbody to start spinning.
  • mode : ForceMode: The type of force that will be applied to the Rigidbody (see ForceMode described above).

Now attach this script to your 3rd Person Controller GameObject and run the game again. Your character should be able to push the Rigidbody Colliders out of the way if he tries to walk through them.

Don't forget to save your scene.

Try This...

Assign different Physic Materials to the Rigidbodies to see how it changes the way the Character Controller interacts with them.

Change the value of the Push Power property to change the amount of force that is applied to the Rigidbody.

Change the Force Mode property. Which mode works the best?

Joints

Unity provides several types of Joints that you can use in your scene. A Joint is a constraint that is defined between two Rigidbodies. For example, the Hinge Joint can be used to create a door that can swing open along a particular axis.

A Spring Joint can be used to create an invisible spring that tries to keep two rigid bodies together.

A Fixed Joint can be used to keep two Rigidbody objects together at a constant distance and orientation. This is useful if you need to "parent" a Rigidbody to another Rigidbody and possibly them to break-apart if the force or torque between them exceeds a certain threshold.

The Configurable Joint allows you to create complex joint configuration that can either mimic the Spring and Hinge joint types, but also allow you to create other types of joints as well (such as pivot, ball-and-socket, saddle, and gliding joints).

Hinge Joint

A Hinge Joint component can be used to constrain one Rigidbody to another along a particular axis.

The GameObject that will be used to create a Hinge Joint must have a Rigidbody component. If you don't want the Rigidbody to be influenced by the forces applied by the joint, then make the Rigidbody Kinematic.

When referring to the Rigidbody components that participate in the joint constraint, the Primary body will refer to the Rigidbody that defines the joint and the Connected body will refer to the Rigidbody that is connected to the joint.

Unity - Hinge Joint

Unity - Hinge Joint

The Hinge Joint has the following properties:

  • Connected Body: The other Rigidbody that this hinge joint is dependent on. This parameter is optional. If it is not specified, then it will be connected to a fixed point in space. This is simlar to attaching the joint to a Kinematic Rigidbody.
  • Anchor: The Anchor point defines the position of the joint relative to the primary body. This will be the point at which the primary and connected bodies rotate.
  • Axis: The axis of rotation for the joint relative to the primary body. For a door hinge, this will alsmost always be (0,1,0) (if the primary body isn't rotated).
  • Use Spring: If Use Spring is checked, then the spring properties will be used to apply a spring force on the hinge joint that will try to keep the primary and connected Rigidbodies at a relative angle from eachother.
    • Spring: The spring force constant to apply to the joint to try to get to the target angle. Greater values will create a very strong spring while lower values will create a weak spring.
    • Damper: The damper is used to slow the spring recoil. If you don't want the spring to overshoot when it recoils, set the Damper value high. If you want the spring to overshoot and swing back and forth before it comes to rest, set the damper value to 0.
    • Target Position: This property is actually used determine the relative angle (measured in degrees) where the rest is considered "at rest". This angle can be animated at runtime through scripting to simulate automatic opening doors.
  • Use Motor: If this value is checked, then a motor force will be applied to the hinge joint. The motor joint can be used to simulate propellors, turnstiles, or revolving doors.
    • Target Velocity: The motor will try to maintain this velocity (measured in degrees per second) to keep the hinge rotating around it's Axis.
    • Force: The amount of force to apply to the joint in order to maintain the desired velocity. With a force of 0, the motor will not start working until it is influenced by an outside force and it will stop very easily if something gets in it's way. With a large force, it will start spinning immediatly and it will push other Rigibodies out of the way if they are hit by the Rigidbody attached to the hinge.
    • Free Spin: If enabled, the motor will not be used to slow the joint's rotation velocity (if for example, it starts spinning faster than the Target Velocity because an external force hit the door very hard) but it will only be used to accelerate the door to the Target Velocity if it was spinning slower.
  • Use Limits: If this is checked, then angular limits will be imposed on the hinge joint.
    • Min: The minimum angle (measured in degrees) that this hinge can swing.
    • Max: The maximum angle (measured in degrees) that this hinge can swing.
    • Min Bounce: How much the hinge will bounce when it reaches the minumum limit angle. A bounce value of 0 will cause the hinge not to bounce while a bounce value of 1 will cause the hinge to bounce with no loss of energy.
    • Max Bounce: How much the hinge will bounce when it reaches the maximum limit angle. A bounce value of 0 will cause the hinge not to bounce while a bounce value of 1 will cause the hinge to bounce with no loss of energy.
  • Break Force: If the amount of linear force imposed on the hinge joint is greater than this value, the hinge will break and the participating Rigidbodies will no longer be constratined.
  • Break Torque: If the amount of angular force imposed on the hinge joint is greater than this value, the hinge will break and the participating Rigidbodies will no longer be constratined.

[Source]

Spring Joint

TODO

[Source]

Fixed Joint

TODO

[Source]

Character Joint

TODO

[Source]

Conclusion

References

The Unity Component Reference Manual was used to gather the information required to write this article.

The Unity Component Reference Manual can be accessed here:

http://docs.unity3d.com/Documentation/Components/index.html

6 thoughts on “Physics in Unity

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>