Menu
CoddyTech

Grow

Lesson 8 of 14 in Coddy's Unity Game: Snake 3D course.

Eating makes the snake one segment longer. The new segment goes where the end of the tail was before the step: the tail moves up, and the new segment fills the cell the end has left, so the snake grows from the back.

That cell is gone once the tail has moved, so remember it first. Then, when the head has reached the food, instantiate a segment there and add it to the list, so it follows from the next step on. A segment that is made but not added never moves. A train adds a wagon at the back the same way:

Vector3 back = wagons[wagons.Count - 1].position;
// ... the train moves on ...
Transform wagon = Instantiate(wagonPrefab, back, Quaternion.identity);
wagons.Add(wagon);

Grow before calling Eat(). Eat() moves the food, and the next lesson makes it look for a cell the snake does not cover, the new segment included.

challenge icon

Challenge

Medium

Each food adds a segment to the tail.

  1. In Snake, add public Transform segmentPrefab; (the scene links it).
  2. In Step(), before the tail moves, keep Vector3 tailEnd: the last segment's cell, or the head's cell when the tail is empty.
  3. On food, add Instantiate(segmentPrefab, tailEnd, Quaternion.identity) to tail, then call Eat().

Press Play and eat a few: the snake grows one cube each time. Then Check.

Try it yourself

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

public class Snake : MonoBehaviour
{
    public float tick = 0.15f;   // seconds between two steps
    public int edge = 7;         // the board's cells run from -edge to edge
    public bool alive = true;
    public List<Transform> tail = new List<Transform>();
    private float timer;
    private Vector3 direction = Vector3.right;       // the way the head moved on its last step
    private Vector3 nextDirection = Vector3.right;   // the turn waiting for the next step

    void Update()
    {
        if (!alive) return;

        Keyboard keyboard = Keyboard.current;
        if (keyboard != null)
        {
            if (keyboard.upArrowKey.wasPressedThisFrame || keyboard.wKey.wasPressedThisFrame) Turn(Vector3.forward);
            if (keyboard.downArrowKey.wasPressedThisFrame || keyboard.sKey.wasPressedThisFrame) Turn(Vector3.back);
            if (keyboard.leftArrowKey.wasPressedThisFrame || keyboard.aKey.wasPressedThisFrame) Turn(Vector3.left);
            if (keyboard.rightArrowKey.wasPressedThisFrame || keyboard.dKey.wasPressedThisFrame) Turn(Vector3.right);
        }

        timer += Time.deltaTime;
        if (timer >= tick)
        {
            timer -= tick;
            Step();
        }
    }

    void Turn(Vector3 newDirection)
    {
        if (newDirection != -direction)
        {
            nextDirection = newDirection;
        }
    }

    void Step()
    {
        direction = nextDirection;
        Vector3 next = transform.position + direction;
        if (Mathf.Abs(next.x) > edge || Mathf.Abs(next.z) > edge)
        {
            Die();
            return;
        }

        for (int i = tail.Count - 1; i > 0; i--)
        {
            tail[i].position = tail[i - 1].position;
        }
        if (tail.Count > 0)
        {
            tail[0].position = transform.position;
        }
        transform.position = next;

        if (GameManager.Instance.IsFood(next))
        {
            GameManager.Instance.Eat();
        }
    }

    void Die()
    {
        alive = false;
    }
}

All lessons in Unity Game: Snake 3D

Practice on your own: Unity playground