The enemy is not chasing the player... #144772
Replies: 1 comment
-
Parece que você está enfrentando vários problemas com o comportamento da IA inimiga no seu jogo. Vamos analisar o potencial
Adição c sustenido Copiar código { { { { {
-1);
0f; // Reset timer
} Corrigindo o estado "Provocado" :Update()diversãoisProvokedestá definido parafalse, você chama Wander(). |
Beta Was this translation helpful? Give feedback.
-
Hello, I am currently working on creating my own game. This is my first coding project, so I'm struggling with this error due to my lack of coding skills...
I have set up the enemy to wander around randomly when the player is not nearby, and to chase the player when the distance between them becomes shorter than a certain threshold. When the player moves away beyond a certain distance, the enemy stops chasing and resumes wandering.
After adding some additional features, I encountered an issue. The enemy no longer reacts when the player comes close, and when the player collides with the enemy, the enemy suddenly moves a certain distance away (remaining still while the player approaches!). Additionally, the enemy should be wandering when alone, but it only changes direction and does not move.
I'm not sure what part of the code is causing this issue. The Inspector settings appear to be correct.
I'll be really appreciated if someone helps me... 😭
Here is the codes :
Player code(firstpersoncontroller):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class FirstPersonController : MonoBehaviour
{
[SerializeField]
private float walkSpeed;
[SerializeField]
private float runSpeed;
[SerializeField]
private float applySpeed;
[SerializeField]
private float jumpForce;
[SerializeField]
private float maxStamina = 100f;
[SerializeField]
private float currentStamina;
[SerializeField]
private float staminaDrain = 10f;
[SerializeField]
private float staminaRecovery = 5f;
// Variable to check if there is enough stamina
private bool canRun = true;
private bool isWaitingToRun = false;
[SerializeField]
private float waitTime = 5f;
private float waitStartTime;
private bool isWalk = false;
private bool isRun = false;
private bool isGround = true;
// Fields related to sound
[SerializeField]
private AudioSource audioSource;
[SerializeField]
private AudioClip walkSound;
[SerializeField]
private AudioClip runSound;
[SerializeField]
private AudioClip staminaDepletedSound;
private CapsuleCollider capsuleCollider;
[SerializeField]
private float lookSensitivity;
[SerializeField]
private float cameraRotationLimit;
private float currentCameraRotationX = 0;
[SerializeField]
private Camera theCamera;
private Rigidbody myRigid;
[SerializeField]
private Image staminaBar;
[SerializeField]
private Color normalColor = Color.green;
[SerializeField]
private Color warningColor = Color.red;
void Start()
{
capsuleCollider = GetComponent();
myRigid = GetComponent();
applySpeed = walkSpeed;
currentStamina = maxStamina;
}
void Update()
{
CheckIfGrounded();
TryJump();
TryRun();
Move();
RotateCamera();
RotateCharacter();
RecoverStamina();
UpdateStaminaUI();
}
private void CheckIfGrounded()
{
isGround = Physics.Raycast(transform.position, Vector3.down, capsuleCollider.bounds.extents.y + 0.1f);
}
private void TryJump()
{
if (Input.GetKeyDown(KeyCode.Space) && isGround)
{
Jump();
}
}
private void Jump()
{
myRigid.velocity = transform.up * jumpForce;
}
private void TryRun()
{
if (isWalk && Input.GetKey(KeyCode.LeftShift) && canRun)
{
Run();
PlaySound(runSound);
}
else if (Input.GetKeyUp(KeyCode.LeftShift) || !canRun || !isWalk)
{
CancelRun();
if (isWalk) PlaySound(walkSound);
else audioSource.Stop();
}
}
private void Run()
{
if (currentStamina > 0)
{
isRun = true;
applySpeed = runSpeed;
currentStamina -= staminaDrain * Time.deltaTime;
currentStamina = Mathf.Max(currentStamina, 0);
}
else
{
canRun = false;
isWaitingToRun = true;
waitStartTime = Time.time;
PlaySound(staminaDepletedSound);
CancelRun();
}
}
private void CancelRun()
{
isRun = false;
applySpeed = walkSpeed;
}
private void RecoverStamina()
{
if (!isRun && (currentStamina < maxStamina))
{
currentStamina += staminaRecovery * Time.deltaTime;
currentStamina = Mathf.Min(currentStamina, maxStamina);
}
if ((currentStamina > 0) && isWaitingToRun && ((Time.time - waitStartTime) >= waitTime))
{
isWaitingToRun = false;
canRun = true;
}
}
private void UpdateStaminaUI()
{
staminaBar.fillAmount = currentStamina / maxStamina;
if (isWaitingToRun)
{
staminaBar.color = warningColor;
}
else
{
staminaBar.color = normalColor;
}
}
private void PlaySound(AudioClip clip)
{
if (audioSource.clip != clip || !audioSource.isPlaying)
{
audioSource.clip = clip;
audioSource.Play();
}
}
private void Move()
{
float _moveDirX = Input.GetAxisRaw("Horizontal");
float _moveDirZ = Input.GetAxisRaw("Vertical");
if (_moveDirX != 0 || _moveDirZ != 0)
{
isWalk = true;
if (!isRun && !audioSource.isPlaying) PlaySound(walkSound);
}
else
{
isWalk = false;
audioSource.Stop();
}
Vector3 _moveHorizontal = transform.right * _moveDirX;
Vector3 _moveVertical = transform.forward * _moveDirZ;
Vector3 _velocity = (_moveHorizontal + _moveVertical).normalized * applySpeed;
myRigid.MovePosition(transform.position + _velocity * Time.deltaTime);
}
private void RotateCharacter()
{
float _yRotation = Input.GetAxis("Mouse X") * lookSensitivity;
Vector3 _characterRotationY = new Vector3(0f, _yRotation, 0f);
myRigid.MoveRotation(myRigid.rotation * Quaternion.Euler(_characterRotationY));
}
private void RotateCamera()
{
float _xRotation = Input.GetAxis("Mouse Y") * lookSensitivity;
currentCameraRotationX -= _xRotation;
currentCameraRotationX = Mathf.Clamp(currentCameraRotationX, -cameraRotationLimit, cameraRotationLimit);
theCamera.transform.localRotation = Quaternion.Euler(currentCameraRotationX, 0f, 0f);
}
}
---------------------------------------------enemy ai code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class EnemyAI : MonoBehaviour
{
[SerializeField] Transform target;
[SerializeField] float chaseRange = 5f; // Range for chasing the player
[SerializeField] float stopChasingRange = 10f; // Distance to stop chasing
[SerializeField] float wanderRadius = 10f; // Radius for random wandering
[SerializeField] float wanderTime = 5f; // Time interval for moving to a random point
[SerializeField] float turnSpeed = 5f;
NavMeshAgent navMeshAgent;
float distanceToTarget = Mathf.Infinity;
bool isProvoked = false;
bool isWandering = false;
float wanderTimer;
void Start()
{
navMeshAgent = GetComponent();
wanderTimer = wanderTime; // Set the timer for initial random movement
}
void Update()
{
distanceToTarget = Vector3.Distance(target.position, transform.position);
if (isProvoked)
{
EngageTarget();
}
else if (distanceToTarget <= chaseRange)
{
isProvoked = true;
}
else if (distanceToTarget >= stopChasingRange)
{
isProvoked = false;
Wander(); // Stop chasing and start wandering
}
}
private void EngageTarget()
{
FaceTarget();
if (distanceToTarget >= navMeshAgent.stoppingDistance)
{
ChaseTarget();
}
if (distanceToTarget <= navMeshAgent.stoppingDistance)
{
AttackTarget();
}
// Stop chasing if the target is too far away
if (distanceToTarget >= stopChasingRange)
{
isProvoked = false;
Wander(); // Wander randomly when the player is far away
}
}
private void ChaseTarget()
{
GetComponent().SetBool("attack", false);
GetComponent().SetTrigger("move");
navMeshAgent.SetDestination(target.position);
}
private void AttackTarget()
{
GetComponent().SetBool("attack", true);
}
private void FaceTarget()
{
Vector3 direction = (target.position - transform.position).normalized;
Quaternion lookRotation = Quaternion.LookRotation(new Vector3(direction.x, 0, direction.z));
transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * turnSpeed);
}
private void Wander()
{
// Move to a random point at regular intervals
wanderTimer += Time.deltaTime;
if (wanderTimer >= wanderTime)
{
Vector3 newPos = RandomNavSphere(transform.position, wanderRadius, -1);
navMeshAgent.SetDestination(newPos);
wanderTimer = 0f; // Reset timer
}
}
// Find a random point
public static Vector3 RandomNavSphere(Vector3 origin, float dist, int layermask)
{
Vector3 randomDirection = Random.insideUnitSphere * dist;
randomDirection += origin;
NavMeshHit navHit;
NavMesh.SamplePosition(randomDirection, out navHit, dist, layermask);
return navHit.position;
}
}
Beta Was this translation helpful? Give feedback.
All reactions