الدورية والمطاردة
جزء من قسم الفيزياء وأسلوب اللعب في رحلة 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 وحدة في كل خطوة، ونادرًا ما يصل تمامًا إلى الموقع.
التحدي
متوسطيقوم روبوت أمني بدورية في المستودع. اكتب النص البرمجي 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()
{
// طارد اللاعب عندما يكون قريبًا، وإلا فاتبع مسار الدورية
}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس الفيزياء وأسلوب اللعب
1الجسم الصلب (Rigidbody)
الجاذبية والكتلةالدفع باستخدام AddForceالقفز باستخدام دفعةFixedUpdate للفيزياءالسرعة المتجهةالأجسام الحركيةمراجعة: منصة الإطلاق