728x90
개발을 하다가 NavMesh라는 것을 알게 되어서 NavMesh를 조금 공부하고
적 코드를 바꾸었습니다.
NightMareEnemy.cs
using DG.Tweening;
using System.Collections;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.SceneManagement;
public class NightMareEnemy : MonoBehaviour
{
[SerializeField] private Transform player;
[SerializeField] private MonoBehaviour mouseLookScript;
[SerializeField] private NavMeshAgent agent;
[SerializeField] private float stopDistance = 2f;
[SerializeField] private float bulletDetectionRange = 3f;
[SerializeField] private float retreatDistance = 1.5f; // 총에 맞았을 때 뒤로 가는 거리
[SerializeField] private float retreatDuration = 0.3f; // 후퇴 시간
private bool isCutsceneActive = false;
private bool isRetreating = false;
private void Start()
{
if (agent == null)
agent = GetComponent<NavMeshAgent>(); // NavMeshAgent 가져오기
}
void Update()
{
transform.position = new Vector3(transform.position.x, 0.5f, transform.position.z);
if (player == null || isCutsceneActive || isRetreating) return;
DetectNearbyBullets();
float distanceToPlayer = Vector3.Distance(transform.position, player.position);
if (distanceToPlayer > stopDistance)
{
agent.SetDestination(player.position);
}
else
{
// 적이 일정 거리 안으로 들어오면 컷신 실행
StartCoroutine(KillPlayerCutscene());
}
}
private void DetectNearbyBullets()
{
Collider[] hitColliders = Physics.OverlapSphere(transform.position, bulletDetectionRange); // 범위 내 오브젝트 감지
foreach (Collider hitCollider in hitColliders)
{
if (hitCollider.CompareTag("Bullet")) // 감지된 오브젝트가 총알인지 확인
{
RetreatFromPlayer(); // 후퇴 실행
break; // 한 번 감지하면 더 이상 확인할 필요 없음
}
}
}
private void RetreatFromPlayer()
{
if (player == null) return;
isRetreating = true; // 후퇴 상태 활성화
// 플레이어 반대 방향으로 이동
Vector3 retreatDirection = (transform.position - player.position).normalized;
Vector3 retreatPosition = transform.position + retreatDirection * retreatDistance;
// Y축 이동을 완전히 막기 위해 Y값을 유지한 상태로 새로운 벡터 생성
retreatPosition = new Vector3(retreatPosition.x, transform.position.y, retreatPosition.z);
// DOTween을 사용해 XZ 좌표만 이동 (Y값은 그대로 유지)
transform.DOMoveX(retreatPosition.x, retreatDuration);
transform.DOMoveZ(retreatPosition.z, retreatDuration).OnComplete(() =>
{
isRetreating = false; // 후퇴 완료 후 다시 움직일 수 있도록 설정
});
}
private IEnumerator KillPlayerCutscene()
{
isCutsceneActive = true; // 컷신 활성화
// 1. 플레이어 조작 비활성화
if (player.GetComponent<CharacterController>())
player.GetComponent<CharacterController>().enabled = false;
if (mouseLookScript != null) mouseLookScript.enabled = false;
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
Vector3 targetPosition = transform.position - transform.forward * -3f; // 적의 위치 근처로 카메라 이동
Camera.main.transform.DOMove(targetPosition, 0.1f); // 카메라 이동
// 카메라가 적을 바라보도록 회전
Camera.main.transform.DOLookAt(transform.position, 0.3f);
yield return new WaitForSeconds(0.3f); // 카메라 이동과 회전하는 시간
// 3. 적을 흔들기
transform.DOShakePosition(1.5f, 0.2f, 10, 90, false, true);
yield return new WaitForSeconds(1.5f); // 적이 흔들리는 시간
// 3. 플레이어 제거
SceneManager.LoadScene("GameOver");
}
}
NavMeshAgent를 가져오고 총알이 일정 거리에 들어오면 후퇴합니다.
그리고 컷신을 카메라가 적 쪽으로 이동하도록 코드를 수정했습니다.
NavMesh로 벽을 만들고 벽이 있으면 적이 돌아옵니다.
그리고 주황색 손에 총알을 발사하는 코드에 쿨타임을 추가했습니다.
그리고 UI로 손에 띄우도록 했습니다.
OrangeHand.cs
using TMPro;
using UnityEngine;
public class OrangeHand : MonoBehaviour
{
//주황 손, 마우스 오른쪽 클릭 시 총알 발사
[SerializeField] private TextMeshProUGUI text;
public GameObject bulletPrefab;
public Transform bulletSpawnPoint;
public float bulletSpeed = 20f;
public float fireCooldown = 3f; //3초 쿨타임 추가
private float lastFireTime = -3f; //게임 시작 시 바로 발사 가능하도록 설정
private void Update()
{
if (Input.GetMouseButtonDown(1) && Time.time >= lastFireTime + fireCooldown)
{
FireBullet();
lastFireTime = Time.time; //마지막 발사 시간을 현재 시간으로 갱신
}
UpdateCooldownText();
}
private void FireBullet()
{
GameObject bullet = Instantiate(bulletPrefab, bulletSpawnPoint.position, bulletPrefab.transform.rotation);
Rigidbody rb = bullet.GetComponent<Rigidbody>();
rb.velocity = bulletSpawnPoint.forward * bulletSpeed;
}
private void UpdateCooldownText()
{
float remainingTime = Mathf.Max(0, lastFireTime + fireCooldown - Time.time);
text.text = ""+remainingTime.ToString("F1") + "s";
}
}
쿨타임을 UI에 띄우도록 수정했습니다.
+ 컷신이 나오면 손 오브젝트를 제거하도록 만들었습니다.
728x90
'Unity' 카테고리의 다른 글
그랩팩 개발 일지 8 (0) | 2025.02.14 |
---|---|
그랩팩 개발 일지 7 (1) | 2025.02.13 |
그랩팩 개발 일지 5 (0) | 2025.02.11 |
그랩팩 개발 일지 4 (0) | 2025.02.10 |
그랩팩 개발 일지 3 (0) | 2025.02.09 |