- Home /
Can't access script through collision.
Hi all,
I'm having a problem that I cant solve for literally days. I have a bullet with a script that when it collides with an enemy with the tag "Enemy", it should get the DealDamage from that gameobject (the enemy) with the EnemyHealth script.
I've done this before in the past but when im doing the same thing now, I keeps giving me a "NullReferenceException: Object reference not set to an instance of an object" error. I think it should mean that it cannot locate the script that its searching but its not there... but it is? Its giving me a headache!
Please help me :(
It gives me the error on line 38.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerAmmoAssaultRifle : MonoBehaviour
{
PlayerStats playerStats;
private float BulletCount = 30; // Each bullet does the damage of 1 / 30 of total damage.
private float Damage;
private float CritChance;
private float CritChanceRoll;
private float CritChanceMin = 0;
private float CritChanceMax = 101;
public GameObject bloodSplatter;
// EnemyHealth enemyHealth;
void Awake()
{
playerStats = GameObject.FindObjectOfType<PlayerStats>();
Damage = playerStats.damage / BulletCount;
CritChance = playerStats.playerTotalCritChance;
Destroy(gameObject, 3f);
}
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("Enemy"))
{
collision.gameObject.GetComponent<EnemyHealth>().DealDamage(Damage);
Instantiate(bloodSplatter, this.transform.position, this.transform.rotation);
CritChanceRoll = (Random.Range(CritChanceMin, CritChanceMax));
if(CritChanceRoll <= CritChance)
{
Damage *= 2;
Debug.Log("Critical Damage of = " + Damage + " !!!");
}
else
{
Debug.Log(Damage);
Destroy(gameObject);
}
}
else if(collision.gameObject)
{
Destroy(gameObject);
}
}
}
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI;
public class EnemyHealth : MonoBehaviour { public float health; public float maxHealth;
public GameObject healthBarUI;
public Slider slider;
private string enemyTitle;
public Text enemyTitleText;
LootDrop lootDrop;
EnemyStats enemyStats;
Transform player;
private void Start()
{
enemyStats = GetComponent<EnemyStats>();
health = maxHealth;
slider.value = CalculateHealth();
player = GameObject.FindGameObjectWithTag("Player").transform;
enemyTitle = enemyStats.enemyName.ToString();
enemyTitleText.text = enemyTitle.ToString();
lootDrop = GetComponent<LootDrop>();
}
private void Update()
{
slider.transform.LookAt(player);
enemyTitleText.transform.LookAt(2 * enemyTitleText.transform.position - player.transform.position); // (2 * enemyTitleText.transform.position - player.transform.position) <<< this makes the Text go Backwards!!!!!
slider.value = CalculateHealth();
if(health < maxHealth)
{
healthBarUI.SetActive(true);
}
if(health <= 0)
{
lootDrop.OnDeath();
Destroy(gameObject);
}
if(health >= maxHealth)
{
health = maxHealth;
}
}
float CalculateHealth()
{
return health / maxHealth;
}
public void DealDamage(float damage)
{
health -= damage;
}
}
Have you tried collision.collider.gameObject
instead of just collision.gameObject? Also, the enemy might not have an EnemyHealth script, but this in unlikely. @danny_appel
Unfortunately it gives me the same error :(
And yea, the enemy has the script, I can even chance the health in the inspector while testing. I seriously dont understand why its not working.
Ofcourse it works when im using FindObjectOfType but that doesnt work while having more then 1 enemy.
Guessing - There may be other objects with tag "Enemy" that don't have the dealdamage script? (is that what is null). $$anonymous$$gestion - $$anonymous$$ay be debug and see what collision object contains. $$anonymous$$gestion - Retrieve the script instance in to a variable and break point when that is null? Idea - $$anonymous$$ay be place the collision processing on the Enemy, you can then check they are hit by all sorts of things (not just bullets).
You were right, one object didnt had the script but did had the tag. Though this didnt solve it. The thing that is null when colliding, is the EnemyHealth script, eventhough it has the script.
I tried Debug.Log(collision.gameObject) and it gives back the enemy gameobject. But when I tried to do Debug.Log(collision.gameObject.GetComponent() it gives me "Null".
And about your idea, I was thinking that aswell but im so tunnelvisioned about this problem, because I dont see why its not working, as it clearly should, right?
If all else fails, I will do it on the EnemyHealth script.
Debug.Log(collision.gameObject.GetComponent())
Answer by danny_appel · Jan 16, 2021 at 03:53 PM
I found out the problem... My enemy had a Mesh Collider on a child... It didnt even had a collider on the parent! Im so dumb lol. Though when im placing a Mesh Collider on the parent it doesnt work either, so I placed a spherical collider and it works now. And yes, I was stuck for a few days because of this dumb problem.
Thanks all for your input and help!
Answer by logicandchaos · Jan 16, 2021 at 03:39 PM
Make sure your object is set up correctly. They way it's coded your EnemyHealth script should be on the gameObject that is colliding, if it's attached to a child object GetComponentInChildren. Try adding this debug line 35 Debug.Log(collision.gameObject); and Debug.Log(collision.gameObject.GetComponent()); That should let you know if you are getting the right object.
Thanks! This made me look into the child/parent relation with colliders and found the problem!