Unity'de Oyuncuyu Takip Eden bir NPC Oluşturun

Oyuncu olmayan karakterler veya NPC'ler, bir insan oyuncu tarafından kontrol edilmeyen ve bunun yerine komut dosyaları veya AI tarafından kontrol edilen karakterlerdir.

NPC'lerin yapması gereken en yaygın görev, Oyuncuyu takip etmek veya kovalamaktır.

Bu derste Unity'de oyuncuyu takip eden bir NPC'nin nasıl yapılacağını göstereceğim.

1. Adım: Oynatıcı Denetleyicisini Oluşturun

Basit bir Oyuncu Kontrol Cihazı oluşturacağız, böylece etrafta dolaşabilir ve NPC'yi test edebiliriz:

  • Yeni bir GameObject ('GameObject' -> 'Create Empty') oluşturun ve adlandırın "Player"
  • Yeni bir Kapsül oluşturun ('GameObject' -> '3D Object' -> 'Capsule'), onu Oyuncu Nesnesinin içine taşıyın ve konumunu (0, 1, 0) olarak değiştirin
  • Kapsül Çarpıştırıcısı bileşenini Kapsülden kaldırma
  • Ana Kamerayı Oyuncu Nesnesinin içine taşıyın ve konumunu (0, 1,64, 0) olarak değiştirin
  • yeni bir komut dosyası oluşturun, onu 'SC_CharacterController' olarak adlandırın ve içine aşağıdaki kodu yapıştırın:

'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' komut dosyasını Oynatıcı Nesnesine ekleyin ve bir Alt Ana Kamerayı bir Oynatıcı Kamera değişkenine atayın
  • Otomatik olarak Karakter Denetleyicisi adı verilen başka bir bileşen eklediğini ve orta konumunu (0, 1, 0) olarak değiştirdiğini fark edeceksiniz.

Adım 2: NPC'yi oluşturun

Bir NPC oluşturmak için aşağıdaki adımları izleyin:

  • Yeni bir GameObject oluşturun ve adını "NPC" olarak adlandırın
  • Yeni bir Kapsül oluşturun, onu NPC Nesnesinin içine taşıyın ve konumunu (0, 1, 0) olarak değiştirin
  • Yeni bir Materyal oluşturun ve adlandırın "npc_material"
  • Npc_material'in rengini kırmızı olarak değiştirin
  • NPC Nesnesinin içindeki Kapsül'e npc_material atayın (bu sadece NPC'yi Oyuncudan ayırt edebilmemiz içindir)

Devam etmeden önce NavMesh'i Sahnemizde pişirmemiz gerekiyor.

NavMesh "Navigation Mesh" anlamına gelir ve NPC'lerin engellere çarpmadan seviyede gezinmesine olanak sağlamak için yol bulmada kullanılır.

NavMesh'i pişirmek için aşağıdaki adımları izleyin:

  • Sahnedeki her statik Nesneyi Gezinme Statiği olarak işaretleyin

  • Gezinme Penceresine gidin ('Pencere' -> 'AI' -> 'Navigation'), Pişirme Sekmesini seçin ve ardından Pişirmeye tıklayın

NavMesh pişirildikten sonra şöyle görünmelidir:

Unity 3D NavMesh Pişirme

Artık NPC hareketinin programlanmasına geçebiliriz:

  • 'NavMesh Agent' bileşenini NPC Nesnesine ekleyin
  • yeni bir komut dosyası oluşturun ve adlandırın 'SC_NPCFollow'
  • 'SC_NPCFollow' betiğini NPC Nesnesine ekleyin
  • 'SC_NPCFollow' betiğini açın

Öncelikle betiğin başına bir UnityEngine.AI ad alanı ekleyerek başlıyoruz:

using UnityEngine.AI;

Daha sonra gerekli değişkenleri tanımlarız:

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

'void Start()''de NavMesh Agent bileşeninin bu Nesneye eklenmesiyle başlıyoruz:

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

Son olarak 'void Update()''te NavMesh Temsilcisine Oyuncuyu takip etmesi talimatını veriyoruz:

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

İşte son 'SC_NPCFollow.cs' betiği:

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;
    }
}

Bazı sorunları düzeltme:

Sayı 1: Oynat'a bastıktan sonra, NPC kapsülü zeminin üzerinde havada asılı duruyor:

Çözüm: NavMesh Agent'taki Temel Ofset değişkenini negatif bir değere değiştirin (benim durumumda -0,08)

Sorun 2: Oyuncuyu takip ederken NPC çok yaklaşıyor:

Çözüm: NavMesh Agent'taki Durma Mesafesini daha yüksek bir değere değiştirin (benim durumumda bunu 5'e ayarladım)

NPC artık hazır, hadi test edelim:

Sharp Coder Video oynatıcı

Her şey beklendiği gibi çalışıyor, NPC artık Oyuncuyu takip ediyor ve belirli bir mesafede duruyor.