Tạo một NPC theo dõi người chơi trong Unity
Nhân vật không phải người chơi hoặc NPC là những nhân vật không do con người điều khiển mà thay vào đó được điều khiển bởi tập lệnh hoặc AI.
Nhiệm vụ phổ biến nhất mà NPC phải làm là theo dõi hoặc đuổi theo Người chơi.
Trong hướng dẫn này, tôi sẽ hướng dẫn cách tạo một NPC đi theo người chơi trong Unity.
Bước 1: Tạo Trình điều khiển trình phát
Chúng tôi sẽ tạo Trình điều khiển người chơi đơn giản để có thể đi xung quanh và kiểm tra NPC:
- Tạo một GameObject mới ('GameObject' -> 'Create Empty') và đặt tên cho nó "Player"
- Tạo một Capsule mới ('GameObject' -> '3D Object' -> 'Capsule'), di chuyển nó vào trong Player Object và thay đổi vị trí của nó thành (0, 1, 0)
- Loại bỏ thành phần Capsule Collider khỏi Capsule
- Di chuyển Camera chính bên trong Player Object và thay đổi vị trí của nó thành (0, 1.64, 0)
- Tạo một tập lệnh mới, đặt tên là 'SC_CharacterController' rồi dán mã bên dưới vào trong tập lệnh đó:
'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);
}
}
}
- Đính kèm tập lệnh 'SC_CharacterController' vào Đối tượng người chơi và gán Camera chính con cho biến Camera của người chơi
- Bạn sẽ nhận thấy nó tự động thêm một thành phần khác gọi là Bộ điều khiển ký tự, thay đổi vị trí trung tâm của nó thành (0, 1, 0)
Bước 2: Tạo NPC
Để tạo NPC, hãy làm theo các bước dưới đây:
- Tạo một GameObject mới và đặt tên là "NPC"
- Tạo một Capsule mới, di chuyển nó vào trong Đối tượng NPC và thay đổi vị trí của nó thành (0, 1, 0)
- Tạo một Material mới và đặt tên cho nó "npc_material"
- Thay đổi màu của npc_material thành màu đỏ
- Gán npc_material cho Capsule bên trong Đối tượng NPC (điều này chỉ để chúng ta có thể phân biệt NPC với Người chơi)
Trước khi tiếp tục, chúng ta cần xử lý NavMesh trong Scene của mình.
NavMesh là viết tắt của "Navigation Mesh" và được sử dụng trong tính năng tìm đường để cho phép NPC điều hướng cấp độ mà không va vào chướng ngại vật.
Để nướng NavMesh, hãy làm theo các bước dưới đây:
- Đánh dấu mọi đối tượng tĩnh trong Cảnh là Điều hướng tĩnh
- Vào Cửa sổ điều hướng ('Window' -> 'AI' -> 'Navigation'), chọn Tab Bake sau đó nhấp vào Bake
Sau khi NavMesh được tạo, nó sẽ trông giống như thế này:
Bây giờ chúng ta có thể chuyển sang lập trình phong trào NPC:
- Đính kèm thành phần 'NavMesh Agent' vào Đối tượng NPC
- Tạo một tập lệnh mới và đặt tên cho nó 'SC_NPCFollow'
- Đính kèm tập lệnh 'SC_NPCFollow' vào Đối tượng NPC
- Mở tập lệnh 'SC_NPCFollow'
Đầu tiên, chúng tôi bắt đầu bằng cách thêm vùng tên UnityEngine.AI vào đầu tập lệnh:
using UnityEngine.AI;
Sau đó, chúng tôi xác định các biến cần thiết:
//Transform that NPC has to follow
public Transform transformToFollow;
//NavMesh Agent variable
NavMeshAgent agent;
Trong 'void Start()', chúng ta bắt đầu bằng cách gắn thành phần NavMesh Agent vào Đối tượng này:
// Start is called before the first frame update
void Start()
{
agent = GetComponent<NavMeshAgent>();
}
Cuối cùng, trong 'void Update()', chúng tôi hướng dẫn Tác nhân NavMesh theo dõi Người chơi:
// Update is called once per frame
void Update()
{
//Follow the player
agent.destination = transformToFollow.position;
}
Đây là tập lệnh 'SC_NPCFollow.cs' cuối cùng:
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;
}
}
Khắc phục một số vấn đề:
Vấn đề 1: Sau khi nhấn Play, viên nang NPC lơ lửng trên mặt đất:
Giải pháp: Thay đổi biến Base Offset trong NavMesh Agent thành giá trị âm (trong trường hợp của tôi là -0,08)
Vấn đề 2: NPC đến quá gần khi đi theo Người chơi:
Giải pháp: Thay đổi Khoảng cách dừng trong NavMesh Agent thành giá trị cao hơn (trong trường hợp của tôi, tôi đặt nó thành 5)
NPC hiện đã sẵn sàng, hãy kiểm tra nó:
Mọi thứ hoạt động như mong đợi, NPC hiện đi theo Người chơi và dừng lại ở một khoảng cách đã định.