צור NPC שעוקב אחרי הנגן באחדות

דמויות שאינן שחקנים או NPCs ​​הן הדמויות שאינן נשלטות על ידי שחקן אנושי ובמקום זאת נשלטות על ידי התסריטים או AI.

המשימה הנפוצה ביותר שאנשי NPC צריכים לעשות, היא לעקוב אחר הנגן או לרדוף אחריו.

במדריך זה, אני אראה כיצד ליצור NPC שעוקב אחר הנגן ב-Unity.

שלב 1: צור את בקר הנגן

ניצור בקר נגן פשוט, כדי שנוכל להסתובב ולבדוק את ה-NPC:

  • צור GameObject חדש ('GameObject' -> 'Create Empty') ושם לו "Player"
  • צור קפסולה חדשה ('GameObject' -> '3D Object' -> 'Capsule'), הזז אותה בתוך אובייקט Player, ושנה את מיקומה ל- (0, 1, 0)
  • הסר את רכיב Capsule Collider מקפסולה
  • הזז את המצלמה הראשית בתוך אובייקט הנגן ושנה את מיקומה ל- (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"
  • צור קפסולה חדשה, הזז אותה בתוך אובייקט NPC ושנה את מיקומה ל- (0, 1, 0)
  • צור חומר חדש ושם לו "npc_material"
  • שנה את הצבע של npc_material לאדום
  • הקצה npc_material לקפסולה בתוך אובייקט NPC (זה רק כדי שנוכל להבחין בין NPC לנגן)

לפני שנמשיך, עלינו לאפות את NavMesh בסצנה שלנו.

NavMesh מייצג "Navigation Mesh" ומשמש באיתור נתיבים כדי לאפשר ל-NPCs לנווט ברמה מבלי להיתקל במכשולים.

כדי לאפות את NavMesh, בצע את השלבים הבאים:

  • סמן כל אובייקט סטטי בסצנה כסטטי ניווט

  • עבור אל חלון הניווט ('חלון' -> 'AI' -> 'Navigation'), בחר בכרטיסייה אפייה ולאחר מכן לחץ על אפייה

לאחר אפיית ה-NavMesh, הוא אמור להיראות בערך כך:

Unity 3D NavMesh Bake

כעת נוכל לעבור לתכנות של תנועת 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: לאחר לחיצה על Play, קפסולת ה-NPC מרחפת מעל הקרקע:

פתרון: שנה את המשתנה Base Offset ב-NavMesh Agent לערך שלילי (במקרה שלי זה -0.08)

בעיה 2: ה-NPC מתקרב מדי כאשר עוקב אחר הנגן:

פתרון: שנה את מרחק העצירה ב-NavMesh Agent לערך גבוה יותר (במקרה שלי הגדרתי אותו ל-5)

ה-NPC מוכן כעת, בואו נבדוק אותו:

Sharp Coder נגן וידאו

הכל עובד כמצופה, ה-NPC עוקב כעת אחרי הנגן ועוצר במרחק מוגדר.