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

الدورية والمطاردة

جزء من قسم الفيزياء وأسلوب اللعب في رحلة Unity على Coddy. الدرس 52 من 63.

يتحرك حارس في دورية على مسار حتى يرى اللاعب، فيطارده، ثم يعود إلى مساره عندما يختفي اللاعب. كلا السلوكين يوجّه الحركة بالطريقة نفسها، نحو نقطة، لذا يمكن لطريقة واحدة تولّي الحركة في الحالتين. يتحرك هذا الحارس ذهابًا وإيابًا بين موقعين، ويطارد اللاعب ضمن chaseRange:

[SerializeField] private Transform pointA;
[SerializeField] private Transform pointB;
[SerializeField] private Transform player;
[SerializeField] private float speed = 2f;
[SerializeField] private float chaseRange = 5f;
private Rigidbody rb;
private Transform goal;

void Start()
{
    rb = GetComponent<Rigidbody>();
    goal = pointA;
}

void FixedUpdate()
{
    if (Flat(player.position - rb.position).magnitude < chaseRange)
    {
        WalkTo(player.position);
        return;
    }
    if (Flat(goal.position - rb.position).magnitude < 0.2f)
    {
        goal = goal == pointA ? pointB : pointA;
    }
    WalkTo(goal.position);
}

void WalkTo(Vector3 target)
{
    Vector3 dir = Flat(target - rb.position).normalized;
    rb.linearVelocity = new Vector3(dir.x * speed, rb.linearVelocity.y, dir.z * speed);
}

Vector3 Flat(Vector3 v)
{
    return new Vector3(v.x, 0f, v.z);
}

يأتي اختبار المطاردة أولًا، وتتخطى تعليمة return الخاصة به كود الدورية، لذا تكون الأولوية للمطاردة كلما كان اللاعب قريبًا. إن goal حقل، لذلك يتذكر الحارس وجهته أثناء المطاردة: ما إن يختفي اللاعب، يواصل السير نحو الموقع الذي كان متجهًا إليه.

يقيس اختبار الوصول المسافة على الأرض. فالموقعان علامتان على الأرض، ومركز الحارس أعلى منهما بوحدة واحدة، لذا فإن المسافة التي تتضمن الارتفاع لا تنخفض أبدًا عن 1، ولن يستدير الحارس أبدًا. يشترط الاختبار أن تكون المسافة أقل من 0.2، لا أن تساوي 0 تمامًا: فعند سرعة وحدتين في الثانية، يتحرك الحارس مسافة 0.04 وحدة في كل خطوة، ونادرًا ما يصل تمامًا إلى الموقع.

challenge icon

التحدي

متوسط

يقوم روبوت أمني بدورية في المستودع. اكتب النص البرمجي Robot. يزوّده Inspector بـ waypoints (العلامات الصفراء الأربع W0 إلى W3، بالترتيب)، وplayer، وspeed (4)، وchaseRange (4). النص البرمجي Player جاهز.

  • حقل int اسمه next، وتكون قيمته الابتدائية 0، وهو فهرس نقطة المسار التي يتجه إليها الروبوت.
  • الدورية: تحرّك إلى waypoints[next]. عندما يصبح الروبوت على بُعد أقل من 0.2 منها على الأرض، انتقل بـ next إلى نقطة المسار التالية، وبعد الأخيرة عُد إلى 0.
  • المطاردة: ما دام اللاعب على بُعد أقل من chaseRange على الأرض، تحرّك إلى اللاعب بدلًا من ذلك.
  • عندما يبتعد اللاعب، واصل السير نحو waypoints[next]، نقطة المسار التي كان الروبوت متجهًا إليها.
  • تحرّك بضبط سرعة Rigidbody على speed على الأرض، مع الإبقاء على سرعة y.

اضغط Play، وشاهد جولة من الدورية واعبر مسارها، ثم اضغط Check.

جرّب بنفسك

using UnityEngine;

public class Robot : MonoBehaviour
{
    [SerializeField] private Transform[] waypoints;
    [SerializeField] private Transform player;
    [SerializeField] private float speed = 4f;
    [SerializeField] private float chaseRange = 4f;
    private Rigidbody rb;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    void FixedUpdate()
    {
        // طارد اللاعب عندما يكون قريبًا، وإلا فاتبع مسار الدورية
    }
}
quiz iconاختبر نفسك

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

جميع دروس الفيزياء وأسلوب اللعب