728x90
◈ 플레이어 따라다니는 NPC 만들기
바닥과 플레이어, npc 객체 만들기
플레이어, npc 객체에 Rigidbody 컴포넌트 추가하기
윈도우 > PackageManager > Packages: Unity Registry > AI Navigation 설치
NPC에 Rigidbody 컴포넌트와 Nav Mash Agent 컴포넌트 추가
NPC.cs 를 npc 오브젝트에 추가
더보기
using System.Collections;
using UnityEngine;
using UnityEngine.AI;
public class NPC : MonoBehaviour
{
public LayerMask whatIsTarget;
private Transform targetTransform; // 대상의 Transform
private NavMeshAgent navMeshAgent;
public float detectionRange = 10.0f; // 검출 가능한 최대 거리
private bool hasTarget
{
get { return targetTransform != null; }
}
private void Awake()
{
// 컴포넌트 초기화
navMeshAgent = GetComponent<NavMeshAgent>();
navMeshAgent.enabled = true; // NavMeshAgent를 활성화
}
private void Start()
{
// AI의 추적 루틴 시작
StartCoroutine(UpdatePath());
}
private void Update()
{
// 추적 대상의 존재 여부에 따라 다른 애니메이션 재생
// zombieAnimator.SetBool("HasTarget", hasTarget);
}
private IEnumerator UpdatePath()
{
// 살아 있는 동안 무한 루프
while (true) // !dead)
{
// 추적 대상의 위치 갱신
UpdateTarget();
// 0.25초 주기로 처리 반복
yield return new WaitForSeconds(0.25f);
}
}
private void UpdateTarget()
{
Collider[] colliders = Physics.OverlapSphere(transform.position, detectionRange, whatIsTarget);
if (colliders.Length > 0)
{
float closestDistance = Mathf.Infinity;
Transform closestTarget = null;
foreach (Collider collider in colliders)
{
float distanceToTarget = Vector3.Distance(transform.position, collider.transform.position);
if (distanceToTarget < closestDistance)
{
closestDistance = distanceToTarget;
closestTarget = collider.transform;
}
}
if (closestTarget != null)
{
targetTransform = closestTarget;
navMeshAgent.SetDestination(targetTransform.position);
}
}
else
{
targetTransform = null;
navMeshAgent.ResetPath(); // 대상이 없을 때 경로 초기화
}
}
}
Inspector > Lqyer > ▽ 눌러서 Add Layer > Player 추가
NPC로 돌아와서 NPC 스크립트 컴포넌트의 What Is Target을 Player로 바꾸기
Player의 레이어를 Player로 바꾸기
PlayerMove.cs를 Player 오브젝트에 추가
더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public float moveSpeed = 5.0f;
private Rigidbody playerRigidbody;
private void Awake()
{
playerRigidbody = GetComponent<Rigidbody>();
}
private void Update()
{
// 플레이어 입력 처리
float horizontalInput = Input.GetAxis("Horizontal");
float verticalInput = Input.GetAxis("Vertical");
// 이동 방향 계산
Vector3 movement = new Vector3(horizontalInput, 0.0f, verticalInput) * moveSpeed * Time.deltaTime;
// Rigidbody를 이용해 플레이어 이동
playerRigidbody.MovePosition(transform.position + movement);
}
}
재생했더니
오류가 뜨네요.
네비게이션 영역을 지정하지 않아서 그래요.
네비게이션 영역 설정
Window > AI > Navigation(Obsolete)
하이라키의 Plan을 선택하고
내비게이션 뷰 > Object > Navigation Static을 체크
Navigation Static을 체크하면 해당 메시를 캐릭터가 길을 찾을 수 있는 표면으로 설정됩니다.
Bake 탭
Bake 버튼을 누르면 씬 뷰에서 Plane 위에 파란색 영역이 생깁니다.
이게 캐릭터가 길을 찾아서 이동할 수 있는 영역을 의미하는 NavMesh입니다.
(Bake는 빵이나 과자같은 것을 굽는다는 의미로 이렇게 NavMesh를 만드는 작업 역시 "NavMesh를 굽는다"라고 표현합니다.)
재생해보겠습니다.
플레이어(노랑)가 NPC 주변으로 가면 NPC가 따라오는걸 볼 수 있습니다.
https://youtu.be/2DM3M4FORYA
'UNITY > Unity Study' 카테고리의 다른 글
플레이어 계단 오르내리기(씬 이동) - Unity, 3D (0) | 2023.08.05 |
---|---|
게임 인트로화면 만들기 (2) | 2023.08.03 |
한글 폰트 사용하기 (0) | 2023.08.02 |
버튼 눌러 팝업창 넘기기 (0) | 2023.08.02 |
목표에 도달하면 팝업창 띄우기 (0) | 2023.08.01 |