169 lines
3.9 KiB
C#
169 lines
3.9 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.SceneManagement;
|
|
|
|
public class CarPatrol : MonoBehaviour
|
|
{
|
|
[Header("Waypoints")]
|
|
[SerializeField] private Transform[] waypoints;
|
|
|
|
[Header("Movement")]
|
|
[SerializeField] private float patrolSpeed = 5f;
|
|
[SerializeField] private float chaseSpeed = 12f;
|
|
[SerializeField] private float acceleration = 3f;
|
|
[SerializeField] private float rotationSpeed = 6f;
|
|
|
|
[Header("Detection")]
|
|
[SerializeField] private float detectionDistance = 20f;
|
|
|
|
[Header("Siren Reference")]
|
|
[SerializeField] private PoliceSiren siren;
|
|
|
|
private Transform _player;
|
|
private int _currentWaypointIndex;
|
|
private float _currentSpeed;
|
|
private bool _isChasing;
|
|
|
|
void Start()
|
|
{
|
|
_player = GameObject.FindGameObjectWithTag("Player")?.transform;
|
|
|
|
_currentSpeed = patrolSpeed;
|
|
|
|
if (siren != null)
|
|
siren.isSirenOn = false;
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (_player == null || waypoints.Length == 0) return;
|
|
|
|
DetectPlayer();
|
|
|
|
if (_isChasing)
|
|
ChasePlayer();
|
|
else
|
|
Patrol();
|
|
}
|
|
|
|
private void Patrol()
|
|
{
|
|
_currentSpeed = patrolSpeed;
|
|
|
|
Vector3 target = waypoints[_currentWaypointIndex].position;
|
|
|
|
MoveTowards(target);
|
|
RotateTowards(target);
|
|
|
|
if (Vector3.Distance(transform.position, target) < 0.5f)
|
|
{
|
|
_currentWaypointIndex++;
|
|
if (_currentWaypointIndex >= waypoints.Length)
|
|
_currentWaypointIndex = 0;
|
|
}
|
|
}
|
|
|
|
private void ChasePlayer()
|
|
{
|
|
_currentSpeed = Mathf.MoveTowards(
|
|
_currentSpeed,
|
|
chaseSpeed,
|
|
acceleration * Time.deltaTime
|
|
);
|
|
|
|
MoveTowards(_player.position);
|
|
RotateTowards(_player.position);
|
|
}
|
|
|
|
private void DetectPlayer()
|
|
{
|
|
if (_player == null) return;
|
|
|
|
Vector3 toPlayer = _player.position - transform.position;
|
|
|
|
float distance = toPlayer.magnitude;
|
|
if (distance > detectionDistance)
|
|
{
|
|
StopChase();
|
|
return;
|
|
}
|
|
|
|
Vector3 direction = toPlayer.normalized;
|
|
float dot = Vector3.Dot(transform.forward, direction);
|
|
if (dot < 0.5f)
|
|
{
|
|
StopChase();
|
|
return;
|
|
}
|
|
|
|
float lateralDistance = Vector3.Cross(transform.forward, toPlayer).magnitude;
|
|
|
|
if (lateralDistance > 2f)
|
|
{
|
|
StopChase();
|
|
return;
|
|
}
|
|
|
|
StartChase();
|
|
}
|
|
|
|
private void StartChase()
|
|
{
|
|
if (_isChasing) return;
|
|
|
|
_isChasing = true;
|
|
|
|
if (siren != null)
|
|
siren.isSirenOn = true;
|
|
}
|
|
|
|
private void StopChase()
|
|
{
|
|
if (!_isChasing) return;
|
|
|
|
_isChasing = false;
|
|
_currentSpeed = patrolSpeed;
|
|
|
|
if (siren != null)
|
|
siren.isSirenOn = false;
|
|
}
|
|
|
|
private void MoveTowards(Vector3 target)
|
|
{
|
|
Vector3 targetPos = new Vector3(target.x, transform.position.y, target.z);
|
|
Vector3 direction = (targetPos - transform.position).normalized;
|
|
|
|
transform.position += direction * _currentSpeed * Time.deltaTime;
|
|
}
|
|
|
|
private void RotateTowards(Vector3 target)
|
|
{
|
|
Vector3 direction = new Vector3(
|
|
target.x - transform.position.x,
|
|
0f,
|
|
target.z - transform.position.z
|
|
);
|
|
|
|
if (direction == Vector3.zero) return;
|
|
|
|
Quaternion targetRotation = Quaternion.LookRotation(direction);
|
|
|
|
transform.rotation = Quaternion.Slerp(
|
|
transform.rotation,
|
|
targetRotation,
|
|
rotationSpeed * Time.deltaTime
|
|
);
|
|
}
|
|
|
|
private void OnCollisionEnter(Collision collision)
|
|
{
|
|
|
|
if (collision.gameObject.CompareTag("Player"))
|
|
{
|
|
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
|
|
}
|
|
}
|
|
|
|
}
|