NavMesh working but not allowing me to deal damage to the enemy
I am trying to create a simple unity fps enemy AI system but for some reason after a certain time the enemy can not be damaged anymore? I am using raycasting and have a script that handles damage but I can not seem to get it to work with the NavMesh (It works without navmesh enabled) can anyone help? The enemy damage script is:
using System.Collections; using UnityEngine;
public abstract class Gun : MonoBehaviour { public string gunName; public GameObject gunPickup;
[Header("Stats:")]
public AmmunitionTypes ammunitionType;
public float fireRate;
public int minimumDamage;
public int maximumDamage;
public float maximumRange;
protected float timeOfLastShot;
public float spreadFactor = 0.05f;
public float viewPortX = 0.5f;
public float viewPortY = 0.5f;
public float viewPortZ = 0;
Vector3 viewPort = new Vector3();
[Space()]
public ParticleSystem muzzleFlash;
public ParticleSystem bulletCasing;
public GameObject enemyImpactEffect;
public GameObject groundImpactEffect;
public GameObject wallImpactEffect;
public GameObject bullet;
public AudioSource weaponFiredSound;
private Transform cameraTransform;
public Animator animator;
public GameObject crossHair;
public bool Scoped = false;
void Start()
{
cameraTransform = Camera.main.transform;
}
IEnumerator Anim()
{
animator.SetBool("IsFiring", true);
yield return new WaitForSeconds(0.05f);
animator.SetBool("IsFiring", false);
}
public void FireScoped()
{
if (AmmunitionManager.instance.ConsumeAmmunition(ammunitionType))
{
muzzleFlash.Play();
bulletCasing.Play();
weaponFiredSound.Play();
if (gameObject.tag == "Sniper")
{
GameObject bulletObject = Instantiate(bullet);
bulletObject.transform.position = cameraTransform.transform.position + cameraTransform.transform.forward;
bulletObject.transform.forward = cameraTransform.transform.forward;
}
else
{
StartCoroutine(Anim());
RaycastHit whatIHitScoped;
if (Physics.Raycast(cameraTransform.position, cameraTransform.forward, out whatIHitScoped, Mathf.Infinity))
{
IDamageable damageable = whatIHitScoped.collider.GetComponent<IDamageable>();
if (damageable != null)
{
float normalisedDistance = whatIHitScoped.distance / maximumRange;
if (normalisedDistance <= 1)
{
damageable.DealDamage(Mathf.RoundToInt(Mathf.Lerp(maximumDamage, minimumDamage, normalisedDistance)));
}
}
if (whatIHitScoped.collider.tag == "Enemy")
{
GameObject impactGO = Instantiate(enemyImpactEffect, whatIHitScoped.point, Quaternion.LookRotation(whatIHitScoped.normal));
Destroy(impactGO, 1f);
}
if (whatIHitScoped.collider.tag == "Wall")
{
GameObject impactGO = Instantiate(wallImpactEffect, whatIHitScoped.point, Quaternion.LookRotation(whatIHitScoped.normal));
Destroy(impactGO, 1f);
}
if (whatIHitScoped.collider.tag == "Ground")
{
GameObject impactGO = Instantiate(groundImpactEffect, whatIHitScoped.point, Quaternion.LookRotation(whatIHitScoped.normal));
Destroy(impactGO, 1f);
}
}
}
}
}
public void FireFromHip()
{
if (AmmunitionManager.instance.ConsumeAmmunition(ammunitionType))
{
muzzleFlash.Play();
bulletCasing.Play();
weaponFiredSound.Play();
if (gameObject.tag == "Sniper")
{
GameObject bulletObject = Instantiate(bullet);
bulletObject.transform.position = cameraTransform.transform.position + cameraTransform.transform.forward;
bulletObject.transform.forward = cameraTransform.transform.forward;
}
else
{
StartCoroutine(Anim());
viewPort.x += Random.Range(-spreadFactor, spreadFactor);
viewPort.y += Random.Range(-spreadFactor, spreadFactor);
Ray rayOrigin = Camera.main.ViewportPointToRay(viewPort);
RaycastHit whatIHitHipfire;
if (Physics.Raycast(rayOrigin, out whatIHitHipfire, Mathf.Infinity))
{
IDamageable damageable = whatIHitHipfire.collider.GetComponent<IDamageable>();
if (damageable != null)
{
float normalisedDistance = whatIHitHipfire.distance / maximumRange;
if (normalisedDistance <= 1)
{
damageable.DealDamage(Mathf.RoundToInt(Mathf.Lerp(maximumDamage, minimumDamage, normalisedDistance)));
}
}
if (whatIHitHipfire.collider.tag == "Enemy")
{
GameObject impactGO = Instantiate(enemyImpactEffect, whatIHitHipfire.point, Quaternion.LookRotation(whatIHitHipfire.normal));
Destroy(impactGO, 1f);
}
if (whatIHitHipfire.collider.tag == "Wall")
{
GameObject impactGO = Instantiate(wallImpactEffect, whatIHitHipfire.point, Quaternion.LookRotation(whatIHitHipfire.normal));
Destroy(impactGO, 1f);
}
if (whatIHitHipfire.collider.tag == "Ground")
{
GameObject impactGO = Instantiate(groundImpactEffect, whatIHitHipfire.point, Quaternion.LookRotation(whatIHitHipfire.normal));
Destroy(impactGO, 1f);
}
viewPort.x = viewPortX;
viewPort.y = viewPortY;
viewPort.z = viewPortZ;
}
}
}
}
}
the damageable script is: public interface IDamageable { void DealDamage(int damage); } and the enemy health script is:; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI;
public class EnemyHealth : MonoBehaviour, IDamageable { [SerializeField] private EnemyStats enemyStats; [SerializeField] private Slider healthbarSlider; [SerializeField] private Image healthbarFillImage; [SerializeField] private Color maxHealthColor; [SerializeField] private Color zeroHealthColor; [SerializeField] private GameObject damageTextPrefab;
private int currentHealth;
private void Start()
{
currentHealth = enemyStats.maxHealth;
SetHealthbarUi();
}
public void DealDamage(int damage)
{
currentHealth -= damage;
Instantiate(damageTextPrefab, transform.position, Quaternion.identity).GetComponent<DamageText>().Initialise(damage);
CheckIfDead();
SetHealthbarUi();
}
private void CheckIfDead()
{
if (currentHealth <= 0)
{
EnemyMovement behaviour = GetComponent<EnemyMovement>();
if(behaviour != null)
{
behaviour.setAlive(false);
}
Destroy(gameObject);
}
}
private void SetHealthbarUi()
{
float healthPercentage = CalculateHealthPercentage();
healthbarSlider.value = healthPercentage;
healthbarFillImage.color = Color.Lerp(zeroHealthColor, maxHealthColor, healthPercentage / 100);
}
private float CalculateHealthPercentage()
{
return ((float)currentHealth / (float)enemyStats.maxHealth) * 100;
}
}
and the enenmy ai script is: using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI;
public class EnemyAI : EnemyHealth {
private NavMeshAgent _navMeshAgent;
public GameObject Player;
public float AttackDistance = 10.0f;
public float FollowDistance = 20.0f;
[Range(0.0f, 1.0f)]
public float AttackProbability = 0.5f;
[Range(0.0f, 1.0f)]
public float HitAccuracy = 0.5f;
public float DamagePoints = 2.0f;
protected override void Awake()
{
base.Awake();
_navMeshAgent = GetComponent<NavMeshAgent>();
}
// Update is called once per frame
void Update()
{
if (_navMeshAgent.enabled)
{
float dist = Vector3.Distance(Player.transform.position, this.transform.position);
bool shoot = false;
bool follow = (dist < FollowDistance);
if (follow)
{
float random = Random.Range(0.0f, 1.0f);
if (random > (1.0f - AttackProbability) && dist < AttackDistance)
{
shoot = true;
}
}
if (follow)
{
_navMeshAgent.SetDestination(Player.transform.position);
}
if (!follow || shoot)
_navMeshAgent.SetDestination(transform.position);
}
}
public void ShootEvent()
{
float random = Random.Range(0.0f, 1.0f);
// The higher the accuracy is, the more likely the player will be hit
bool isHit = random > 1.0f - HitAccuracy;
if (isHit)
{
}
}
}
Your answer
Follow this Question
Related Questions
How do I make an animated AI enemy float but still move using NavMesh? 2 Answers
Problem with navagent killing FPS 0 Answers
Nav Mesh Agent destination not lining up with actual target. 1 Answer
Let specific NavMesh Agents ignore some Area costs 0 Answers
Navmesh Agent limited movement to 1 tile 0 Answers