Hi. I wrote this little script for my 3D game. It’s supposed to find the Object with the PlayerController on it and determine if the player is visible with a linecast. However. I always get a NullRefrenceExeption and can’t find out what is causing it. I was able to narrow it down to the linecast methode. I can confirm that the player gameObject has a transform and is beeing found.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyController : TankController
{
GameObject player;
private void Start()
{
player = FindObjectOfType<PlayerController>().gameObject;
}
private void Update()
{
Debug.Log(TargetIsVisible(player, tr.position));
}
private bool TargetIsVisible(GameObject target, Vector3 lookFrom)
{
return !Physics.Linecast(lookFrom, target.transform.position);
}
}
Where in your script do you define what tr is? In your Update method you do Debug.Log(TargetIsVisible(player, tr.position));
but I cannot see anywhere in your script a variable called tr
. Perhaps if you posted the exact error message we might be able to help, if what I mentioned is not the actual issue.
Some notes on how to fix a NullReferenceException error in Unity3D
- also known as: Unassigned Reference Exception
- also known as: Missing Reference Exception
http://plbm.com/?p=221
The basic steps outlined above are:
- Identify what is null
- Identify why it is null
- Fix that.
Expect to see this error a LOT. It’s easily the most common thing to do when working. Learn how to fix it rapidly. It’s easy. See the above link for more tips.
After hours of trying I figured out that the derived methode override the start function of its parent. I didn’t knew that would happen. This is my first time really using C# and Unity but with the help of a friend I managed to fix the problem by turning the parents start methode to public and calling it in the derived class.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyController : TankController
{
GameObject player;
protected override void Start()
{
base.Start();
player = FindObjectOfType<PlayerController>().gameObject;
}
private void Update()
{
Debug.Log(TargetIsVisible(player.transform.position, tr.position, aggroRange));
}
private bool TargetIsVisible(Vector3 target, Vector3 lookFrom, float aggroRange)
{
RaycastHit hit;
if (!Physics.Linecast(lookFrom, target, out hit, 9) && aggroRange > Vector3.Distance(target, lookFrom))
{
Debug.DrawLine(lookFrom, target, Color.green);
return true;
}
else
{
Debug.DrawLine(lookFrom, target, Color.red);
return false;
}
}
I also had to change the start methode from the parent to:
protected virtual void Start() { }
}
Yeah, I was just having a talk about inheritance under Unity two days ago with some coworkers. The fact that important messages are simply silently discarded when you fail to override them like this makes it FAR too dangerous for my tastes.
There’s no real call for inheritance when working in Unity’s component environment. As long as you’re doing it, there is a non-zero chance you will implement a class in the future which simply fails to call base.WhateverMethod()
and you’ll be back with the same mysterious bugs. Not only that but it will have weird failures in the scene serializations when you change inheritance; it’s a steaming hot mess.
In this case I’d make a TankController component, and hand that to the enemy as an object that it can interoperate with to drive the tank, and the same goes for the player. The player would drive the tank controller in the same way the enemy drives his.