Menu
CoddyTech

Rośnij

Lekcja 8 z 14 w kursie Gra w Unity: Wąż 3D w Coddy.

Po zjedzeniu pokarmu wąż wydłuża się o jeden segment. Nowy segment trafia tam, gdzie przed ruchem znajdował się koniec ogona: ogon przesuwa się do przodu, a nowy segment zajmuje komórkę, którą opuścił jego koniec, więc wąż rośnie od tyłu.

Ta komórka znika, gdy ogon się przesunie, więc najpierw ją zapamiętaj. Następnie, gdy głowa dotrze do pokarmu, utwórz tam segment i dodaj go do listy, aby od następnego ruchu podążał za resztą. Utworzony segment, który nie zostanie dodany, nigdy się nie porusza. Pociąg dodaje wagon z tyłu w ten sam sposób:

Vector3 back = wagons[wagons.Count - 1].position;
// ... pociąg jedzie dalej ...
Transform wagon = Instantiate(wagonPrefab, back, Quaternion.identity);
wagons.Add(wagon);

Powiększ węża przed wywołaniem Eat(). Eat() przesuwa pokarm, a w następnej lekcji sprawisz, że będzie szukać komórki, której wąż nie zajmuje, uwzględniając nowy segment.

challenge icon

Wyzwanie

Średni

Każdy zjedzony pokarm dodaje segment do ogona.

  1. W Snake dodaj public Transform segmentPrefab; (scena jest z nim połączona).
  2. W Step(), zanim ogon się przesunie, zachowaj Vector3 tailEnd: komórkę ostatniego segmentu albo komórkę głowy, gdy ogon jest pusty.
  3. Po zjedzeniu pokarmu dodaj Instantiate(segmentPrefab, tailEnd, Quaternion.identity) do tail, a następnie wywołaj Eat().

Naciśnij „Graj” i zjedz kilka pokarmów: za każdym razem wąż urośnie o jeden sześcian. Następnie naciśnij „Sprawdź”.

Spróbuj swoich sił

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

public class Snake : MonoBehaviour
{
    public float tick = 0.15f;   // sekundy między kolejnymi krokami
    public int edge = 7;         // pola planszy rozciągają się od -edge do edge
    public bool alive = true;
    public List<Transform> tail = new List<Transform>();
    private float timer;
    private Vector3 direction = Vector3.right;       // kierunek, w którym głowa poruszyła się w ostatnim kroku
    private Vector3 nextDirection = Vector3.right;   // skręt oczekujący na następny krok

    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;
    }
}

Wszystkie lekcje w sekcji Gra w Unity: Wąż 3D

Poćwicz samodzielnie: Edytor online Unity