Creați un NPC care urmează jucătorul în Unity

Personajele non-jucatoare sau NPC-uri sunt personajele care nu sunt controlate de un jucător uman și, în schimb, sunt controlate de scripturi sau de AI.

Cea mai obișnuită sarcină pe care trebuie să o facă NPC-urile este să urmărească sau să-l urmărească pe Jucător.

În acest tutorial, voi arăta cum să faci un NPC care urmărește jucătorul în Unity.

Pasul 1: Creați controlerul jucătorului

Vom crea un controler de jucător simplu, astfel încât să ne putem plimba și să testăm NPC-ul:

  • Creați un nou GameObject ('GameObject' -> 'Create Empty') și denumiți-l "Player"
  • Creați o nouă capsulă („GameObject” -> '3D Object' -> 'Capsule'), mutați-o în interiorul Player Object și schimbați-i poziția în (0, 1, 0)
  • Scoateți componenta Capsule Collider dintr-o capsulă
  • Mutați camera principală în interiorul obiectului jucător și schimbați-i poziția în (0, 1.64, 0)
  • Creați un nou script, numiți-l 'SC_CharacterController' apoi inserați codul de mai jos în interiorul acestuia:

'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);
        }
    }
}
  • Atașați scriptul 'SC_CharacterController' la obiectul Player și atribuiți o cameră principală copil unei variabile Camera Player
  • Veți observa că a adăugat automat o altă componentă numită Character Controller, schimbându-și poziția centrală în (0, 1, 0)

Pasul 2: Creați NPC-ul

Pentru a crea un NPC, urmați pașii de mai jos:

  • Creează un nou GameObject și numește-l „NPC
  • Creați o nouă capsulă, mutați-o în interiorul NPC Object și schimbați-i poziția în (0, 1, 0)
  • Creați un material nou și denumiți-l "npc_material"
  • Schimbați culoarea npc_material în roșu
  • Atribuiți npc_material la Capsule în interiorul NPC Object (acest lucru este doar pentru a putea distinge NPC de jucător)

Înainte de a continua, trebuie să coacem NavMesh în scena noastră.

NavMesh înseamnă "Navigation Mesh" și este folosit în identificarea căii pentru a permite NPC-urilor să navigheze la nivel fără a se ciocni de obstacole.

Pentru a coace NavMesh, urmați pașii de mai jos:

  • Marcați fiecare obiect static din scenă ca static de navigare

  • Accesați fereastra de navigare („Fereastră” -> 'AI' -> 'Navigation'), selectați fila Coace, apoi faceți clic pe Coace

După ce NavMesh este copt, ar trebui să arate cam așa:

Unity 3D NavMesh Bake

Acum putem trece la programarea mișcării NPC:

  • Atașați componenta 'NavMesh Agent' la obiectul NPC
  • Creați un script nou și denumiți-l 'SC_NPCFollow'
  • Atașați scriptul 'SC_NPCFollow' la obiectul NPC
  • Deschideți scriptul 'SC_NPCFollow'

În primul rând, începem prin a adăuga un spațiu de nume UnityEngine.AI la începutul scriptului:

using UnityEngine.AI;

Apoi definim variabilele necesare:

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

În 'void Start()' începem prin a obține componenta NavMesh Agent atașată acestui obiect:

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

În cele din urmă, în 'void Update()' îi instruim agentului NavMesh să urmărească Playerul:

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

Iată scriptul final '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;
    }
}

Remedierea unor probleme:

Problema 1: După ce apăsați pe Play, capsula NPC plutește deasupra solului:

Soluție: Schimbați variabila Base Offset din NavMesh Agent la o valoare negativă (în cazul meu este -0,08)

Problema 2: NPC-ul se apropie prea mult când îl urmărește pe Jucător:

Soluție: Schimbați distanța de oprire în agentul NavMesh la o valoare mai mare (în cazul meu am setat-o ​​la 5)

NPC-ul este acum gata, haideți să-l testăm:

Sharp Coder Video player

Totul funcționează conform așteptărilor, NPC-ul îl urmărește acum pe Jucător și se oprește la o distanță stabilită.

Articole sugerate
Implementarea IA a unui inamic în Unitate
Cum să faci un FPS cu suportul AI în Unity
Cum să faci un AI al unui cerb în Unity
Unity Adaugă inamici la un platformer 2D
Lucrul cu NavMeshAgent în Unity
Revizuirea pachetului Unity Asset Store - Zombie AI System
Conceptul de AI în dezvoltarea jocurilor