Added slow motion when ball is close to final block

I was playing around with my completed code from after this lecture and decided to try to add a slow-motion effect to the ball when it gets close to the last block of the level. If you miss the last block or hit it and move onto the next level the ball will return to its regular speed.

Within Level.cs I added two serialized fields: one that determines how close the ball and block need to be to trigger slow motion, and one that controls how much time slows down:

[SerializeField] public float SlowMotionDistanceTrigger = 1.5f;
[SerializeField] public float SlowMotionFactor = 8;

Then I updated Block.cs to look like this:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Block : MonoBehaviour {
	[SerializeField] AudioClip BreakSound;

	Level Level;
	Ball Ball;
	Vector2 BlockToBallVector;
	Rigidbody2D Rigidbody2D;
	bool SlowMotion = false;
	float SlowMotionFactor;
	float SlowMotionDistanceTrigger;

	private void Start() {
		Level = FindObjectOfType<Level>();
		Level.CountBreakableBlocks();
		SlowMotionFactor = Level.SlowMotionFactor;
		SlowMotionDistanceTrigger = Level.SlowMotionDistanceTrigger;
		Ball = FindObjectOfType<Ball>();
		BlockToBallVector = transform.position - Ball.transform.position;
	}

	private void Update() {
		if (Level.BreakingBlocksRemaining == 1) {
			if (Vector2.Distance(transform.position, Ball.transform.position) < SlowMotionDistanceTrigger) {
				if (SlowMotion == false) {
					Ball.GetComponent<Rigidbody2D>().velocity = new Vector2(Ball.GetComponent<Rigidbody2D>().velocity.x / SlowMotionFactor, Ball.GetComponent<Rigidbody2D>().velocity.y / SlowMotionFactor);
					SlowMotion = true;
				}
			} else {
				if (SlowMotion) {
					Ball.GetComponent<Rigidbody2D>().velocity = new Vector2(Ball.GetComponent<Rigidbody2D>().velocity.x * SlowMotionFactor, Ball.GetComponent<Rigidbody2D>().velocity.y * SlowMotionFactor);
					SlowMotion = false;
				}
			}
		}
	}

	private void OnCollisionEnter2D(Collision2D collision) {
		AudioSource.PlayClipAtPoint(BreakSound, Camera.main.transform.position);
		Level.BlockDestroyed();
		Destroy(gameObject);
	}
}

Looking at the code I added six new variables (Ball, BlockToBallVector, Rigidbody2D, SlowMotion, SlowMotionFactor, and SlowMotionDistanceTrigger) at the top of the class.

Within the Start method, I set SlowMotionFactor and SlowMotionDistanceTrigger to the serialized variables from Level, got Ball with FindObjectOfType, and set BlockToBallVector the same way we set the vector between the paddle and the ball in our Ball class.

All of the fun stuff is within the Update method. First I check if there is only one block remaining. If that’s true then I check if the ball is within the specified distance to the block and if it is I check if we’re already in slow motion mode. If we aren’t I update the Ball’s velocity to be the current velocity divided by my SlowMotionFactor, and then set SlowMotion to true.

If we’re on the last remaining block but the ball is more than one unit away from the block then I’m checking if we’re currently in slow motion; if we are I set the Ball’s velocity to the current velocity multiplied by my SlowMotionFactor, and set SlowMotion to false.

I think the end result turned out pretty cool:

Let me know what you think!

1 Like

Oh wow! That’s sexy!

1 Like