Menu
CoddyTech
flag Ar iconالعربيةdown icon

صوّب باستخدام المضرب

الدرس 4 من 16 في دورة لعبة Unity: تحطيم الطوب على Coddy.

مع ارتداد مثالي، لا يستطيع اللاعب توجيه الكرة: تغادر الكرة المضرب بالزاوية نفسها التي وصلت بها. أما ألعاب كسر الطوب فتجعل المضرب هو من يحدد ذلك. فالضربة قرب الطرف الأيسر ترسل الكرة إلى أعلى وإلى اليسار، والضربة في المنتصف ترسلها مباشرة إلى أعلى، وكلما ابتعدت الضربة عن المنتصف اتسعت الزاوية.

حوّل موضع الضربة إلى رقم من ‎-1 عند الطرف الأيسر إلى 1 عند الطرف الأيمن: إزاحة الكرة على محور x عن مركز المضرب، مقسومة على نصف عرض المضرب. لنفترض أن عرض المضرب 4 وحدات ومركزه عند x = 2، وأن الكرة اصطدمت عند x = 3. الإزاحة هي 1، ونصف العرض هو 2، لذا فالرقم هو 0.5، والاتجاه الجديد هو 0.5 إلى الجانب و1 إلى أعلى، أي (0.5, 1, 0)، بعد تطبيعه. الضربة عند أحد الطرفين تمامًا تعطي 1 أو ‎-1، أي زاوية قدرها 45 درجة عن الاتجاه العمودي إلى أعلى. احصر الرقم ضمن هذا النطاق، لأن الكرة قد تلامس زاوية المضرب بعد الطرف بقليل.

تُنفَّذ OnCollisionEnter الخاصة بالكرة بعد أن تحسب الفيزياء الارتداد، لذا فإن ضبط السرعة هناك يستبدلها. وترسل الجدران الرسالة نفسها، ويجب أن تحتفظ بارتدادها العادي، لذا تحقّق أولًا مما اصطدمت به. يشير collision.collider.bounds إلى الصندوق الذي يشغله المصادم في العالم، مع احتساب المقياس:

void OnCollisionEnter(Collision collision)
{
    Bounds box = collision.collider.bounds;
    Debug.Log(collision.gameObject.name + " is " + box.size.x + " wide, centered at x = " + box.center.x);
}
challenge icon

التحدي

سهل

أضف OnCollisionEnter(Collision collision) إلى Ball:

  1. لا تفعل شيئًا إلا إذا كان الكائن الذي اصطدمت به الكرة موسومًا بـ Paddle.
  2. احسب x: اطرح إحداثي x للمضرب من إحداثي x للكرة، ثم اقسم الناتج على نصف عرض المضرب (collision.collider.bounds.size.x)، مع حصر القيمة بين -1 و1.
  3. عيّن سرعة Rigidbody إلى new Vector3(x, 1f, 0f) بعد تطبيعها، مضروبةً في speed.

اضغط على Play، والتقط الكرة بالقرب من كل طرف من المضرب، ثم اضغط على Check.

جرّب بنفسك

using UnityEngine;
using UnityEngine.InputSystem;

public class Ball : MonoBehaviour
{
    public Transform paddle;
    public float speed = 9f;

    Rigidbody rb;
    bool launched;

    void Awake()
    {
        rb = GetComponent<Rigidbody>();
        PhysicsMaterial bouncy = new PhysicsMaterial("Bouncy");
        bouncy.bounciness = 1f;
        bouncy.dynamicFriction = 0f;
        bouncy.staticFriction = 0f;
        bouncy.bounceCombine = PhysicsMaterialCombine.Maximum;
        bouncy.frictionCombine = PhysicsMaterialCombine.Minimum;
        GetComponent<Collider>().material = bouncy;
    }

    void Update()
    {
        if (launched) return;
        transform.position = paddle.position + Vector3.up * 0.5f;
        if (Keyboard.current.spaceKey.wasPressedThisFrame) Launch(new Vector3(0.3f, 1f, 0f));
    }

    public void Launch(Vector3 direction)
    {
        launched = true;
        rb.linearVelocity = direction.normalized * speed;
    }

    void FixedUpdate()
    {
        if (!launched) return;
        rb.linearVelocity = rb.linearVelocity.normalized * speed;
    }
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس لعبة Unity: تحطيم الطوب