Crash
Lesson 11 of 20 in Coddy's Unity Game: Sky Lanes course.
The obstacles are triggers: they detect the runner without pushing it. When the runner's CharacterController and a trigger meet, Unity calls OnTriggerEnter on the runner's scripts, with the trigger's collider:
void OnTriggerEnter(Collider other)
{
if (game.over) return;
if (other.CompareTag("Obstacle"))
{
game.GameOver();
}
}GameOver ends the run: over becomes true, the speed goes to 0 so the road stops, and the message in the middle of the screen says so. While over is true the GameManager stops counting the distance and the Runner stops reading the keys.
Challenge
Medium- In
GameManageraddpublic TMP_Text messageText;andpublic bool over;. - Add
public void GameOver(): if alreadyover, return; otherwise setover = true,speed = 0fandmessageText.text = "Game over". - At the top of GameManager's Update,
if (over) return;. - In
Runner, find the GameManager in Start, read the keys only while!game.over, and addOnTriggerEnteras above.
Try it yourself
using UnityEngine;
public class Runner : MonoBehaviour
{
public float laneWidth = 2.5f;
public float laneSpeed = 16f;
public float jumpHeight = 1.6f;
public float gravity = -40f;
public float slideTime = 0.7f;
public int lane;
private CharacterController controller;
private float fallSpeed;
private float slide;
void Start()
{
controller = GetComponent<CharacterController>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.A) || Input.GetKeyDown(KeyCode.LeftArrow)) lane = Mathf.Max(-1, lane - 1);
if (Input.GetKeyDown(KeyCode.D) || Input.GetKeyDown(KeyCode.RightArrow)) lane = Mathf.Min(1, lane + 1);
bool jump = Input.GetKeyDown(KeyCode.W) || Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.Space);
if (jump && controller.isGrounded)
{
fallSpeed = Mathf.Sqrt(jumpHeight * -2f * gravity);
StopSlide();
}
if ((Input.GetKeyDown(KeyCode.S) || Input.GetKeyDown(KeyCode.DownArrow)) && controller.isGrounded)
{
slide = slideTime;
Resize(0.5f);
}
if (slide > 0f)
{
slide -= Time.deltaTime;
if (slide <= 0f) StopSlide();
}
if (controller.isGrounded && fallSpeed < 0f) fallSpeed = -2f;
fallSpeed += gravity * Time.deltaTime;
float targetX = lane * laneWidth;
float x = Mathf.MoveTowards(transform.position.x, targetX, laneSpeed * Time.deltaTime);
Vector3 move = new Vector3(x - transform.position.x, fallSpeed * Time.deltaTime, 0f);
controller.Move(move);
}
void StopSlide()
{
if (transform.localScale.y < 1f) Resize(1f);
slide = 0f;
}
void Resize(float height)
{
controller.enabled = false;
transform.position += Vector3.up * (height - transform.localScale.y);
transform.localScale = new Vector3(1f, height, 1f);
controller.enabled = true;
}
}
All lessons in Unity Game: Sky Lanes
Practice on your own: Unity playground