Here’s a video that shows what’s happening: Click Here (YouTube)
I don’t know why this is happening. I suspect it might have something to do with using a UnityEvent that Invokes a function within a component attached to the same Game Object as the script that calls that event, but I have no clue on how that works or how I should fix it. I tried disabling the HealthManager script before destroying the Game Object; no luck. Tried calling Destroy(gameObject) every frame if health gets to 0; no luck, got a “GameObject you are trying to access has been destroyed” error. And why does my code work almost every time, but it just randomly fails (that’s what really bugs me out)? Does anyone have an idea of how to fix this?
I got this in the middle of a game jam, so it’s really stressful
Here are the pieces of code highlighted in the video:
(HealthManager.cs)
using System;
using System.Collections;
using System.Collections.Generic;
using System.Security.Cryptography;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
public class HealthManager : MonoBehaviour
{
public float maxHealthPoints;
public float healthPoints;
public float defense = 1;
public GameObject hitParticles;
public GameObject deathParticles;
public bool isDead;
public HealthBar healthBar;
public UnityEvent onDeath;
private void Start()
{
if (maxHealthPoints == 0)
maxHealthPoints = healthPoints;
if (healthBar)
{
healthBar.SetMaxHealth(maxHealthPoints);
healthBar.SetHealth(healthPoints);
}
}
public void ReceiveDamage(float amount)
{
healthPoints -= amount / defense;
if (healthBar)
healthBar.SetHealth(healthPoints);
if (healthPoints <= 0)
{
Destroy(Instantiate(deathParticles, transform.position, Quaternion.identity), 1);
healthPoints = 0;
isDead = true;
onDeath.Invoke();
}
else
Destroy(Instantiate(hitParticles, transform), 1);
}
public void ReceiveHealth(float amount)
{
healthPoints += amount;
if (healthPoints > maxHealthPoints)
healthPoints = maxHealthPoints;
if (healthBar)
healthBar.SetHealth(healthPoints);
}
}
(E2.cs - Enemy Behaviour)
using System;
using System.Collections;
using System.Collections.Generic;
using Pathfinding;
using Pathfinding.Util;
using UnityEngine;
using UnityEngine.Events;
// Enemy 2: Runs towards player with a knife. Low Health, Mid Damage, Mid Speed, Low Defense, Mid Range.
public class E2 : MonoBehaviour
{
public int scorePoints;
public string targetTag;
public float angleOffset;
private Item knifeItem;
private Knife knife;
private AIPath _aiPath;
private AIDestinationSetter _aiDestination;
private GameObject target;
private void Start()
{
_aiPath = GetComponent<AIPath>();
_aiDestination = GetComponent<AIDestinationSetter>();
knifeItem = GetComponentInChildren<Item>();
knife = GetComponentInChildren<Knife>();
}
void Update()
{
target = GameObject.FindWithTag(targetTag);
if (target)
{
if (Vector3.Distance(transform.position, target.transform.position) <=
transform.localScale.y / 2 + knife.range)
{
_aiPath.enabled = false;
Vector3 dir = target.transform.position - transform.position;
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg + angleOffset;
transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
knife.attack = true;
}
else
{
_aiPath.enabled = true;
_aiDestination.target = target.transform; // For when the target changes.
knife.attack = false;
}
}
}
public void OnDeath()
{
PlayerPrefs.SetInt("lastScore", PlayerPrefs.GetInt("lastScore") + scorePoints);
knife.attack = false;
knife.canAttack = true;
Item iog = Instantiate(knifeItem.selfPrefab, transform.position, transform.rotation).GetComponent<Item>();
iog.UpdatePickupbleTrigger(true);
iog.UpdateActionCollider(false);
iog.UpdateMainBehaviour(false);
Destroy(gameObject);
}
}