قم بإنشاء شخصية غير قابلة للعب (NPC) تتبع اللاعب في Unity

الشخصيات التي ليست لاعبين أو NPCs ​​هي الشخصيات التي لا يتحكم فيها لاعب بشري ويتم التحكم فيها بدلاً من ذلك بواسطة البرامج النصية أو AI.

المهمة الأكثر شيوعًا التي يتعين على الشخصيات غير القابلة للعب القيام بها هي متابعة اللاعب أو مطاردته.

في هذا البرنامج التعليمي، سأوضح كيفية إنشاء شخصية غير قابلة للعب (NPC) تتبع اللاعب في Unity.

الخطوة 1: إنشاء وحدة تحكم المشغل

سنقوم بإنشاء وحدة تحكم بسيطة للمشغل، حتى نتمكن من التجول واختبار الشخصية غير القابلة للعب:

  • قم بإنشاء GameObject جديد ("GameObject" -> 'Create Empty') وقم بتسميته "Player"
  • قم بإنشاء كبسولة جديدة ('GameObject' -> '3D Object' -> 'Capsule')، وحركها داخل Player Object، وقم بتغيير موضعها إلى (0، 1، 0)
  • قم بإزالة مكون مصادم الكبسولة من الكبسولة
  • حرك الكاميرا الرئيسية داخل كائن المشغل وقم بتغيير موضعها إلى (0، 1.64، 0)
  • قم بإنشاء سكريبت جديد، وقم بتسميته 'SC_CharacterController' ثم الصق الكود أدناه داخله:

'SC_CharacterController.cs'

using UnityEngine;

[RequireComponent(typeof(CharacterController))]

public class SC_CharacterController : MonoBehaviour
{
    public float speed = 7.5f;
    public float jumpSpeed = 8.0f;
    public float gravity = 20.0f;
    public Camera playerCamera;
    public float lookSpeed = 2.0f;
    public float lookXLimit = 45.0f;

    CharacterController characterController;
    Vector3 moveDirection = Vector3.zero;
    Vector2 rotation = Vector2.zero;

    [HideInInspector]
    public bool canMove = true;

    void Start()
    {
        characterController = GetComponent<CharacterController>();
        rotation.y = transform.eulerAngles.y;
    }

    void Update()
    {
        if (characterController.isGrounded)
        {
            // We are grounded, so recalculate move direction based on axes
            Vector3 forward = transform.TransformDirection(Vector3.forward);
            Vector3 right = transform.TransformDirection(Vector3.right);
            float curSpeedX = speed * Input.GetAxis("Vertical");
            float curSpeedY = speed * Input.GetAxis("Horizontal");
            moveDirection = (forward * curSpeedX) + (right * curSpeedY);

            if (Input.GetButton("Jump"))
            {
                moveDirection.y = jumpSpeed;
            }
        }

        // Apply gravity. Gravity is multiplied by deltaTime twice (once here, and once below
        // when the moveDirection is multiplied by deltaTime). This is because gravity should be applied
        // as an acceleration (ms^-2)
        moveDirection.y -= gravity * Time.deltaTime;

        // Move the controller
        characterController.Move(moveDirection * Time.deltaTime);

        // Player and Camera rotation
        if (canMove)
        {
            rotation.y += Input.GetAxis("Mouse X") * lookSpeed;
            rotation.x += -Input.GetAxis("Mouse Y") * lookSpeed;
            rotation.x = Mathf.Clamp(rotation.x, -lookXLimit, lookXLimit);
            playerCamera.transform.localRotation = Quaternion.Euler(rotation.x, 0, 0);
            transform.eulerAngles = new Vector2(0, rotation.y);
        }
    }
}
  • قم بإرفاق البرنامج النصي 'SC_CharacterController' بكائن المشغل وقم بتعيين كاميرا رئيسية فرعية لمتغير كاميرا المشغل
  • ستلاحظ أنه أضاف تلقائيًا مكونًا آخر يسمى Character Controller، مع تغيير موضعه المركزي إلى (0، 1، 0)

الخطوة 2: إنشاء NPC

لإنشاء NPC، اتبع الخطوات التالية:

  • قم بإنشاء GameObject جديد وقم بتسميته "NPC"
  • أنشئ كبسولة جديدة، وحركها داخل الكائن غير القابل للعب، وقم بتغيير موضعه إلى (0، 1، 0)
  • قم بإنشاء مادة جديدة وقم بتسميتها "npc_material"
  • قم بتغيير لون npc_material إلى اللون الأحمر
  • قم بتعيين npc_material إلى الكبسولة داخل كائن NPC (وهذا فقط حتى نتمكن من التمييز بين NPC واللاعب)

قبل المتابعة، نحتاج إلى خبز NavMesh في مشهدنا.

يرمز NavMesh إلى "Navigation Mesh" ويستخدم في تحديد المسار للسماح للشخصيات غير القابلة للعب بالتنقل في المستوى دون الاصطدام بالعوائق.

لخبز NavMesh، اتبع الخطوات التالية:

  • قم بتمييز كل كائن ثابت في المشهد باعتباره التنقل الثابت

  • انتقل إلى نافذة التنقل ("نافذة" -> 'AI' -> 'Navigation')، وحدد علامة التبويب "خبز" ثم انقر فوق "خبز"

بعد خبز NavMesh، يجب أن يبدو كما يلي:

الوحدة 3D NavMesh خبز

الآن يمكننا الانتقال إلى برمجة حركة NPC:

  • قم بإرفاق المكون 'NavMesh Agent' بكائن NPC
  • قم بإنشاء برنامج نصي جديد وقم بتسميته 'SC_NPCFollow'
  • أرفق البرنامج النصي 'SC_NPCFollow' بكائن NPC
  • افتح البرنامج النصي 'SC_NPCFollow'

أولاً، نبدأ بإضافة مساحة اسم UnityEngine.AI في بداية البرنامج النصي:

using UnityEngine.AI;

ثم نحدد المتغيرات الضرورية:

    //Transform that NPC has to follow
    public Transform transformToFollow;
    //NavMesh Agent variable
    NavMeshAgent agent;

في 'void Start()' نبدأ بإرفاق مكون NavMesh Agent بهذا الكائن:

    // Start is called before the first frame update
    void Start()
    {
        agent = GetComponent<NavMeshAgent>();
    }

أخيرًا، في 'void Update()' نطلب من وكيل NavMesh متابعة المشغل:

    // Update is called once per frame
    void Update()
    {
        //Follow the player
        agent.destination = transformToFollow.position;
    }

إليك النص النهائي 'SC_NPCFollow.cs':

using UnityEngine;
using UnityEngine.AI;

public class SC_NPCFollow : MonoBehaviour
{
    //Transform that NPC has to follow
    public Transform transformToFollow;
    //NavMesh Agent variable
    NavMeshAgent agent;

    // Start is called before the first frame update
    void Start()
    {
        agent = GetComponent<NavMeshAgent>();
    }

    // Update is called once per frame
    void Update()
    {
        //Follow the player
        agent.destination = transformToFollow.position;
    }
}

إصلاح بعض المشاكل:

المشكلة 1: بعد الضغط على زر التشغيل، تحوم كبسولة NPC فوق الأرض:

الحل: قم بتغيير متغير Base Offset في NavMesh Agent إلى قيمة سالبة (في حالتي هو -0.08)

المشكلة 2: يقترب NPC كثيرًا عند متابعة اللاعب:

الحل: قم بتغيير مسافة التوقف في NavMesh Agent إلى قيمة أعلى (في حالتي قمت بتعيينها على 5)

NPC جاهز الآن، فلنختبره:

Sharp Coder مشغل فديوهات

كل شيء يعمل كما هو متوقع، والشخصية غير القابلة للعب تتبع اللاعب الآن وتتوقف عند مسافة محددة.

المقالات المقترحة
تنفيذ الذكاء الاصطناعي للعدو في الوحدة
كيفية إنشاء لعبة FPS بدعم الذكاء الاصطناعي في Unity
كيفية صنع الذكاء الاصطناعي للغزال في الوحدة
العمل مع NavMeshAgent في الوحدة
مراجعة حزمة Unity Asset Store - نظام Zombie AI
Unity أضف أعداء إلى منصة ثنائية الأبعاد
بناء لعبة إطلاق النار من أعلى إلى أسفل في Unity