Crea un NPC che segue il giocatore in Unity

I personaggi non giocanti o NPC sono i personaggi che non sono controllati da un giocatore umano e sono invece controllati dagli script o dall'AI.

Il compito più comune che devono svolgere gli NPC è seguire o inseguire il giocatore.

In questo tutorial, mostrerò come creare un NPC che segue il giocatore in Unity.

Passaggio 1: crea il controller del lettore

Creeremo un semplice controller del giocatore, così potremo passeggiare e testare l'NPC:

  • Crea un nuovo GameObject ('GameObject' -> 'Create Empty') e dagli un nome "Player"
  • Crea una nuova capsula ('GameObject' -> '3D Object' -> 'Capsule'), spostala all'interno dell'oggetto Player e modifica la sua posizione in (0, 1, 0)
  • Rimuovere il componente Capsule Collider da una capsula
  • Sposta la telecamera principale all'interno dell'oggetto giocatore e cambia la sua posizione in (0, 1.64, 0)
  • Crea un nuovo script, chiamalo 'SC_CharacterController' quindi incolla al suo interno il codice seguente:

'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);
        }
    }
}
  • Allega lo script 'SC_CharacterController' all'oggetto Player e assegna una fotocamera principale secondaria a una variabile Player Camera
  • Noterai che ha aggiunto automaticamente un altro componente chiamato Character Controller, cambiando la sua posizione centrale in (0, 1, 0)

Passaggio 2: crea l'NPC

Per creare un NPC, procedi nel seguente modo:

  • Crea un nuovo GameObject e chiamalo "NPC"
  • Crea una nuova capsula, spostala all'interno dell'oggetto NPC e cambia la sua posizione in (0, 1, 0)
  • Crea un nuovo materiale e dagli un nome "npc_material"
  • Cambia il colore di npc_material in rosso
  • Assegna npc_material alla Capsule all'interno dell'oggetto NPC (questo serve solo per poter distinguere l'NPC dal Giocatore)

Prima di continuare, dobbiamo inserire il NavMesh nella nostra scena.

NavMesh sta per "Navigation Mesh" e viene utilizzato nella ricerca del percorso per consentire agli NPC di navigare nel livello senza scontrarsi con ostacoli.

Per cuocere il NavMesh, seguire i passaggi seguenti:

  • Contrassegna ogni oggetto statico nella scena come navigazione statica

  • Vai alla finestra di navigazione ('Finestra' -> 'AI' -> 'Navigation'), seleziona la scheda Bake quindi fai clic su Bake

Dopo che il NavMesh è stato preparato, dovrebbe assomigliare a questo:

Unità 3D NavMesh Cuocere

Adesso possiamo passare alla programmazione del movimento degli NPC:

  • Collega il componente 'NavMesh Agent' all'oggetto NPC
  • Crea un nuovo script e assegnagli un nome 'SC_NPCFollow'
  • Allega lo script 'SC_NPCFollow' all'oggetto NPC
  • Apri lo script 'SC_NPCFollow'

Innanzitutto, iniziamo aggiungendo uno spazio dei nomi UnityEngine.AI all'inizio dello script:

using UnityEngine.AI;

Quindi definiamo le variabili necessarie:

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

In 'void Start()' iniziamo collegando il componente NavMesh Agent a questo oggetto:

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

Infine, nell''void Update()' ordiniamo al NavMesh Agent di seguire il Player:

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

Ecco lo script finale '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;
    }
}

Risoluzione di alcuni problemi:

Problema 1: Dopo aver premuto Play, la capsula dell'NPC si libra sopra il terreno:

Soluzione: Modificare la variabile Base Offset in NavMesh Agent su un valore negativo (nel mio caso è -0,08)

Problema 2: L'NPC si avvicina troppo quando segue il giocatore:

Soluzione: Modificare la distanza di arresto in NavMesh Agent su un valore più alto (nel mio caso l'ho impostato su 5)

L'NPC è ora pronto, proviamolo:

Sharp Coder Lettore video

Tutto funziona come previsto, l'NPC ora segue il Giocatore e si ferma ad una distanza prestabilita.

Articoli suggeriti
Implementare l'intelligenza artificiale di un nemico in Unity
Come realizzare un FPS con il supporto AI in Unity
Revisione del pacchetto Unity Asset Store - Sistema di intelligenza artificiale Zombie
Lavorare con NavMeshAgent in Unity
Come creare un'intelligenza artificiale di un cervo in unità
Unity aggiunge nemici a un platform 2D
Sistema di dialogo per l'unità