المطاردة ضمن النطاق
جزء من قسم الفيزياء وأسلوب اللعب في رحلة Unity على Coddy. الدرس 51 من 63.
معظم الأعداء يتركونك وشأنك حتى تقترب منهم. قِس المسافة إلى اللاعب في كل خطوة فيزيائية، ولا تطارده إلا ضمن نطاق محدد. يطارد هذا الوحل اللاعب ضمن sightRange ويبقى ساكنًا خارجه:
void FixedUpdate()
{
Vector3 toPlayer = player.position - rb.position;
toPlayer.y = 0f;
if (toPlayer.magnitude < sightRange)
{
Vector3 dir = toPlayer.normalized;
rb.linearVelocity = new Vector3(dir.x * speed, rb.linearVelocity.y, dir.z * speed);
}
else
{
rb.linearVelocity = new Vector3(0f, rb.linearVelocity.y, 0f);
}
}إن else مهمة: يحتفظ Rigidbody بسرعته حتى يغيّرها شيء ما. من دونها، ينزلق الوحل الذي يفقدك مبتعدًا حتى يوقفه الاحتكاك، وعلى الجليد لا يتوقف أبدًا. وبما أن y ضُبطت على 0 أولًا، فإن toPlayer.magnitude هي المسافة على الأرض، لذا يُعد اللاعب الواقف على صندوق بجوار الوحل كأنه بجواره.
لنطاق واحد نقطة ضعف. فاللاعب الواقف عند حافته يدخل نطاقه ويخرج منه، ويبدأ الوحل ويتوقف مرارًا وتكرارًا. يتجنب الأعداء ذلك باستخدام نطاقين: يلاحظون اللاعب داخل نطاق قصير، ولا يستسلمون إلا بعد تجاوزه نطاقًا أطول. يتذكر bool ما إذا كان العدو يطارد اللاعب، وبين النطاقين لا يتغير شيء، لذا يواصل العدو ما كان يفعله.
التحدي
متوسطيطارد ذئبٌ فريسته في الغابة. اكتب سكربت Wolf للذئب. يزوّده Inspector بـ player وspeed (3) وnoticeRange (4) وgiveUpRange (8). سكربت Player جاهز.
- يحدد حقل
boolباسمchasingما إذا كان الذئب يطارد. وتكون قيمته في البدايةfalse. - في كل خطوة فيزيائية، قِس المسافة إلى اللاعب على الأرض (من دون احتساب الارتفاع). إذا كانت المسافة أقل من
noticeRange: تصبح قيمةchasingهيtrue. وإذا كانت أكبر منgiveUpRange: تصبحfalse. أما بينهما، فتبقى كما هي. - أثناء المطاردة، يركض الذئب نحو اللاعب بسرعة
speedباستخدام Rigidbody، مع الإبقاء على سرعته على المحور y. وإلا فإنه يبقى ساكنًا: السرعتان على المحورين x وz تساويان 0.
اضغط Play، واقترب من الذئب ثم اهرب، وبعدها اضغط Check.
جرّب بنفسك
using UnityEngine;
public class Wolf : MonoBehaviour
{
[SerializeField] private Transform player;
[SerializeField] private float speed = 3f;
[SerializeField] private float noticeRange = 4f;
[SerializeField] private float giveUpRange = 8f;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
// اكتشف اللاعب، وتوقف عن ملاحقته، ثم طارده أو ابقَ ثابتًا
}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس الفيزياء وأسلوب اللعب
1الجسم الصلب (Rigidbody)
الجاذبية والكتلةالدفع باستخدام AddForceالقفز باستخدام دفعةFixedUpdate للفيزياءالسرعة المتجهةالأجسام الحركيةمراجعة: منصة الإطلاق