Menu
CoddyTech

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

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

يسير حارس في دورية على مسار حتى يرى اللاعب، فيطارده ويعود إلى مساره عندما يختفي اللاعب. يوجّه السلوكان الحركة بالطريقة نفسها، نحو نقطة، لذا يمكن استخدام طريقة واحدة للمشي في الحالتين. يسير هذا الحارس ذهابًا وإيابًا بين نقطتين، ويطارد اللاعب ضمن 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

التحدي

متوسط

اجعل الروبوت يقوم بدورية بين نقاط مساره ويطارد اللاعب الذي يقترب منه.

  1. اكتب WalkTo(Vector3 target)، واضبط rb.linearVelocity ليتجه نحو الهدف على الأرض بسرعة speed، مع الحفاظ على سرعته في المحور y.
  2. في FixedUpdate()، عندما يكون اللاعب أقرب من chaseRange، استدعِ WalkTo(player.position) ثم return.
  3. وإلا، عندما تكون المسافة أقل من 0.2 عن waypoints[next]، اضبط next = (next + 1) % waypoints.Length;، ثم تحرك نحو waypoints[next].

اضغط على «العب» واعبر مساره. ثم اضغط على «تحقق».

جرّب بنفسك

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()
    {
        // طارد اللاعب عندما يكون قريبًا، وإلا فاتبع مسار الدورية
    }
}

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

تدرّب بنفسك: Playground لـ Unity