Buat NPC yang Mengikuti Pemain di Unity
Karakter non-pemain atau NPCs adalah karakter yang tidak dikendalikan oleh pemain manusia melainkan dikendalikan oleh skrip atau AI.
Tugas paling umum yang harus dilakukan NPC adalah mengikuti atau mengejar Pemain.
Pada tutorial kali ini saya akan menunjukkan cara membuat NPC yang mengikuti pemain di Unity.
Langkah 1: Buat Pengontrol Pemain
Kita akan membuat Player Controller sederhana, sehingga kita bisa berkeliling dan menguji NPC:
- Buat GameObject baru ('GameObject' -> 'Create Empty') dan beri nama "Player"
- Buat Capsule baru ('GameObject' -> '3D Object' -> 'Capsule'), pindahkan ke dalam Player Object, dan ubah posisinya menjadi (0, 1, 0)
- Hapus komponen Capsule Collider dari Kapsul
- Pindahkan Kamera Utama di dalam Objek Pemain dan ubah posisinya menjadi (0, 1.64, 0)
- Buat skrip baru, beri nama 'SC_CharacterController' lalu tempel kode di bawah ini di dalamnya:
'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);
}
}
}
- Lampirkan skrip 'SC_CharacterController' ke Objek Pemain dan tetapkan Kamera Utama anak ke variabel Kamera Pemain
- Anda akan melihat secara otomatis menambahkan komponen lain yang disebut Pengontrol Karakter, mengubah posisi tengahnya menjadi (0, 1, 0)
Langkah 2: Buat NPC
Untuk membuat NPC, ikuti langkah-langkah di bawah ini:
- Buat GameObject baru dan beri nama "NPC"
- Buat Kapsul baru, pindahkan ke dalam Objek NPC, dan ubah posisinya menjadi (0, 1, 0)
- Buat Material baru dan beri nama "npc_material"
- Ubah warna npc_material menjadi merah
- Tetapkan npc_material ke Capsule di dalam Objek NPC (ini hanya agar kita dapat membedakan NPC dari Pemain)
Sebelum melanjutkan, kita perlu memanggang NavMesh di Scene kita.
NavMesh adalah singkatan dari "Navigation Mesh" dan digunakan dalam pencarian jalan untuk memungkinkan NPC menavigasi level tanpa menabrak rintangan.
Untuk memanggang NavMesh, ikuti langkah-langkah di bawah ini:
- Tandai setiap Objek statis di Adegan sebagai Navigasi Statis
- Buka Jendela Navigasi ('Jendela' -> 'AI' -> 'Navigation'), pilih Tab Panggang lalu klik Panggang
Setelah NavMesh dipanggang, tampilannya akan seperti ini:
Sekarang kita bisa beralih ke pemrograman pergerakan NPC:
- Lampirkan komponen 'NavMesh Agent' ke Objek NPC
- Buat skrip baru dan beri nama 'SC_NPCFollow'
- Lampirkan skrip 'SC_NPCFollow' ke Objek NPC
- Buka skrip 'SC_NPCFollow'
Pertama, kita mulai dengan menambahkan namespace UnityEngine.AI di awal skrip:
using UnityEngine.AI;
Kemudian kami mendefinisikan variabel yang diperlukan:
//Transform that NPC has to follow
public Transform transformToFollow;
//NavMesh Agent variable
NavMeshAgent agent;
Di 'void Start()' kita mulai dengan memasang komponen Agen NavMesh ke Objek ini:
// Start is called before the first frame update
void Start()
{
agent = GetComponent<NavMeshAgent>();
}
Terakhir, di 'void Update()' kami menginstruksikan Agen NavMesh untuk mengikuti Pemain:
// Update is called once per frame
void Update()
{
//Follow the player
agent.destination = transformToFollow.position;
}
Berikut ini skrip 'SC_NPCFollow.cs' terakhir:
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;
}
}
Memperbaiki beberapa masalah:
Edisi 1: Setelah menekan Play, kapsul NPC melayang di atas tanah:
Solusi: Ubah variabel Base Offset di NavMesh Agent menjadi nilai negatif (dalam kasus saya -0,08)
Masalah 2: NPC datang terlalu dekat saat mengikuti Pemain:
Solusi: Ubah Jarak Berhenti di Agen NavMesh ke nilai yang lebih tinggi (dalam kasus saya, saya mengaturnya ke 5)
NPC sekarang sudah siap, mari kita uji:
Semuanya berjalan sesuai harapan, NPC sekarang mengikuti Pemain dan berhenti pada jarak yang ditentukan.