Keep the Speed
Lesson 3 of 16 in Coddy's Unity Game: Brick Breaker course.
A Brick Breaker ball never slows down. Its PhysicsMaterial does most of the work: bounciness 1 keeps all of a bounce's speed, and friction 0 stops the walls from dragging or spinning the ball. The walls and bricks have no material of their own, and Unity combines the two colliders' values, by default with Average: the ball's 1 and a wall's default 0 make a bounce at half speed. bounceCombine = Maximum and frictionCombine = Minimum let the ball's own values win against anything it hits.
The physics is still not exact: a moving paddle adds its own speed to a bounce, two balls push each other, and small errors add up over hundreds of bounces. So every FixedUpdate the ball keeps its direction and gets its speed set back. The Ball's Rigidbody also has Freeze Position Z ticked in the Inspector, which keeps it in the play plane.
A different game wants a different rule. An air hockey puck may slow down but never go faster than a limit, and Vector3.ClampMagnitude shortens a vector that is too long and leaves a shorter one alone:
void FixedUpdate()
{
rb.linearVelocity = Vector3.ClampMagnitude(rb.linearVelocity, maxSpeed);
}A cap is not enough for the ball: one slowed to 2 units a second would stay at 2. It needs its speed set exactly, from its direction.
Challenge
EasyIn Ball:
- In
Awake(), make anew PhysicsMaterial("Bouncy")with bounciness 1, dynamic and static friction 0,bounceCombineMaximum andfrictionCombineMinimum, and give it to the ball's collider withGetComponent<Collider>().material. - Add
FixedUpdate(): while the ball is launched, set itslinearVelocityto its current direction timesspeed.
In Unity you can also make the material as an asset (Create > Physics Material) and drag it onto the Sphere Collider's Material slot; here the script makes it.
Press Play, launch the ball and watch it bounce, then Check.
Try it yourself
using UnityEngine;
using UnityEngine.InputSystem;
public class Ball : MonoBehaviour
{
public Transform paddle;
public float speed = 9f;
Rigidbody rb;
bool launched;
void Awake()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
if (launched) return;
transform.position = paddle.position + Vector3.up * 0.5f;
if (Keyboard.current.spaceKey.wasPressedThisFrame) Launch(new Vector3(0.3f, 1f, 0f));
}
public void Launch(Vector3 direction)
{
launched = true;
rb.linearVelocity = direction.normalized * speed;
}
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.