العقبات
الدرس 9 من 20 في دورة لعبة Unity: مسارات السماء على Coddy.
يحتاج الطريق الآن إلى شيءٍ للتفادي. تحتوي كل قطعة على عائق في المنتصف، في مسار عشوائي. تتولى ذلك دالة Fill، ويُستدعى تنفيذها لكل قطعة جديدة في Start، ومرة أخرى كلما عادت قطعة إلى المقدمة.
تبقى أول قطعتين فارغتين، لمنح اللاعب لحظةً للتأهب: يحصي Road القطع التي ملأها في made.
void Fill(Transform chunk)
{
made++;
if (made <= safeChunks) return;
int lane = Random.Range(-1, 2);
Place(chunk, barrierPrefab, lane, 0.5f, 0f);
}تعطي Random.Range(-1, 2) القيمة -1 أو 0 أو 1: عند استخدام الأعداد الصحيحة، لا يُختار العدد الثاني مطلقًا.
تظل العقبة القديمة على القطعة المُعاد استخدامها. تحذف Clear كل ابن يحمل وسمًا. أما الأرضية والخطوط المتقطعة والحواف فوسمها Untagged، لذا تبقى:
void Clear(Transform chunk)
{
foreach (Transform child in chunk)
{
if (!child.CompareTag("Untagged")) Destroy(child.gameObject);
}
}التحدي
سهل- في
Roadأضفpublic GameObject barrierPrefab;وpublic int safeChunks = 2;وprivate int made;. - اكتب
Place(chunk, prefab, lane, y, z): تنشئ الكائن المسبق عندchunk.position + new Vector3(lane * laneWidth, y, z)باستخدامprefab.transform.rotation، بوصفه عنصرًا فرعيًا للقطعة. - اكتب
FillوClearكما سبق. - استدعِ
Fill(chunk)لكل قطعة في Start، واستدعِClear(chunk); Fill(chunk);عندما تنتقل قطعة إلى المقدمة.
جرّب بنفسك
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;
}
}
جميع دروس لعبة Unity: مسارات السماء
تدرّب بنفسك: Playground لـ Unity