Lớn lên
Bài học 8 trên 14 trong khóa học Game Unity: rắn 3D của Coddy.
Ăn mồi khiến con rắn dài thêm một đốt. Đốt mới nằm ở vị trí đuôi đã ở trước lần di chuyển: đuôi tiến lên, đốt mới lấp vào ô mà đuôi vừa rời đi, nên con rắn dài ra từ phía sau.
Ô đó sẽ biến mất khi đuôi di chuyển, vì vậy hãy ghi nhớ vị trí đó trước. Sau đó, khi đầu rắn đến chỗ thức ăn, hãy tạo một đốt tại đó rồi thêm đốt vào danh sách để nó bắt đầu di chuyển theo từ lần tiếp theo. Một đốt được tạo ra nhưng không được thêm vào sẽ không di chuyển. Đoàn tàu cũng thêm một toa ở phía sau theo cách tương tự:
Vector3 back = wagons[wagons.Count - 1].position;
// ... đoàn tàu tiếp tục di chuyển ...
Transform wagon = Instantiate(wagonPrefab, back, Quaternion.identity);
wagons.Add(wagon);Hãy làm cho rắn dài thêm trước khi gọi Eat(). Eat() di chuyển thức ăn, và bài học tiếp theo sẽ chỉnh sửa hàm này để tìm một ô mà con rắn không chiếm, kể cả ô của đốt mới.
Thử thách
Trung bìnhMỗi miếng thức ăn sẽ thêm một đoạn vào đuôi.
- Trong
Snake, thêmpublic Transform segmentPrefab;(cảnh sẽ liên kết đối tượng này). - Trong
Step(), trước khi đuôi di chuyển, lưuVector3 tailEnd: ô của đoạn cuối cùng hoặc ô của đầu khi đuôi trống. - Khi ăn thức ăn, thêm
Instantiate(segmentPrefab, tailEnd, Quaternion.identity)vàotail, rồi gọiEat().
Nhấn Chơi và ăn vài miếng: mỗi lần, con rắn sẽ dài thêm một khối lập phương. Sau đó nhấn Kiểm tra.
Tự làm thử
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class Snake : MonoBehaviour
{
public float tick = 0.15f; // số giây giữa hai bước di chuyển
public int edge = 7; // các ô trên bảng trải từ -edge đến edge
public bool alive = true;
public List<Transform> tail = new List<Transform>();
private float timer;
private Vector3 direction = Vector3.right; // hướng di chuyển của đầu ở bước trước
private Vector3 nextDirection = Vector3.right; // hướng rẽ chờ đến bước tiếp theo
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;
}
}
Tất cả bài học trong Game Unity: rắn 3D
Tự luyện tập: Playground Unity