NullReferenceException. GetComponent dose not work properly

Hi,
i am kind of new to Unity and i ran into a problem.
I think part of the problem is that GetComponent dosent work the way it should be .

There are 2 Classes that inherit my MoveObjekt Class, those two are the Enemy and the Player Class.
For the enemys the script works (to a certain extent) , but if it is used by the player the start funktion does not seem to get my components.

I am getting the following error , each time i press a key to move the player:
NullReferenceException: Object reference not set to an instance of an object
MovingObjekt.move (Int32 xDir, Int32 yDir, UnityEngine.RaycastHit2D& hit) (at Assets/Scripts/MovingObjekt.cs:42)
MovingObjekt.attemptMove[Wall] (Int32 xDir, Int32 yDir) (at Assets/Scripts/MovingObjekt.cs:87)
Player.attemptMove[Wall] (Int32 xDir, Int32 yDir) (at Assets/Scripts/Player.cs:38)
Player.Update () (at Assets/Scripts/Player.cs:77)

Here are my C# scripts that i think are involved in the problem:

GameManager script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameManager : MonoBehaviour
{

    public float turnDelay = .1f;
    public static GameManager instance = null;
    public BoardManager boardScript;
    public int playerFoodPoints = 100;
    [HideInInspector]
    public bool playersTurn = true;
    public int level = 3;

    private List<Enemy> enemies;
    private bool enemiesMoving;

    private void Awake()
    {
        Debug.Log("inside gamemanager awake

");
if (instance == null)
{
instance = this;
}
else if (instance != this)
{
Destroy(gameObject);
}

        DontDestroyOnLoad(gameObject);

        enemies = new List<Enemy>();
        boardScript = GetComponent<BoardManager>();
        initGame();
    }


    void initGame()
    {
        enemies.Clear();
        boardScript.setupScene(level);
    }

    // Update is called once per frame
    void Update()
    {
        if (playersTurn || enemiesMoving)
        {
            return;
        }

        StartCoroutine(moveEnemies());
    }


    public void addEnemyToList(Enemy script)
    {
        enemies.Add(script);
    }

    public void gameOver()
    {
        enabled = false;
    }


    IEnumerator moveEnemies()
    {
        enemiesMoving = true;
        yield return new WaitForSeconds(turnDelay);
        if (enemies.Count == 0)
        {
            yield return new WaitForSeconds(turnDelay);
        }

        for (int i = 0; i < enemies.Count; i++)
        {
            enemies*.moveEnemy();*

yield return new WaitForSeconds(enemies*.moveTime);*
}

playersTurn = true;
enemiesMoving = false;
}
}
MovingObjekt script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

public abstract class MovingObjekt : MonoBehaviour
{

public float moveTime = 0.1f;
public LayerMask blockingLayer;

private BoxCollider2D boxCollider;
private Rigidbody2D rb2D;
private float inverseMoveTime;

// Use this for initialization
protected virtual void Start()
{
boxCollider = GetComponent();
rb2D = GetComponent();
inverseMoveTime = 1f / moveTime;
Debug.Log(“rb2D:” + rb2D + "
");

Debug.Log(“boxCollider:” + boxCollider + "
");

}

protected bool move(int xDir, int yDir, out RaycastHit2D hit)
{
Debug.Log("in move funktion
");

Vector2 start = transform.position;
Vector2 end = start + new Vector2(xDir, yDir);
if (boxCollider != null)
{
Debug.Log(“in move. boxcollider:” + boxCollider + "
");

}
if (rb2D != null)
{
Debug.Log(“in move. rb2D:” + rb2D + "
");

}
//deactivate the boxcollider of the moving objetkt so that the linecast will not collide with the objekt it self
boxCollider.enabled = false;
Debug.Log(“boxcollider enabled inside move??” + boxCollider.enabled + "
");

//linecast casts an imaginary line between 2 points and checks if there is a collision on the set line
//hit will store informations about the objekt that collided with the linecast
hit = Physics2D.Linecast(start, end, blockingLayer);
boxCollider.enabled = true;

//hit.transform is null if the raycast didnt collide on the blockingLayer
if (hit.transform == null)
{
//start to move the objekt towards its destination
StartCoroutine(smoothMovement(end));
return true;
}
//if the linecast did detect a collision
return false;
}

protected IEnumerator smoothMovement(Vector3 end)
{
//calculate the remaining distance between the start position and the end position
float sqrRemainingDistance = (transform.position - end).sqrMagnitude;

//moves the objekt towards its destination(end) . float.Epsilon has a value near 0.
while (sqrRemainingDistance > float.Epsilon)
{
//calculates the new position for the movement towards its destination(end)
Vector3 newPosition = Vector3.MoveTowards(rb2D.position, end, inverseMoveTime * Time.deltaTime);
//moves the Rigidbody2D to its new Position
rb2D.MovePosition(newPosition);
//calculate the new remaining distance between the objekts Rigidbody2D and its destination(end)
sqrRemainingDistance = (transform.position - end).sqrMagnitude;
yield return null;
}
}

protected virtual void attemptMove(int xDir, int yDir)
where T : Component
{
Debug.Log("inside movingobjekt.player.attemtmove
");

//if the move funktion is detecting a collision , the information about the collision objekt is stored in the hit variable
RaycastHit2D hit;
bool canMove = move(xDir, yDir, out hit);

//no collision detected
if (hit.transform == null)
{
return;
}

T hitComponent = hit.transform.GetComponent();

if (!canMove && hitComponent != null)
{
onCantMove(hitComponent);
}
}

protected abstract void onCantMove(T component)
where T : Component;
}

Player script:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MovingObjekt
{

//damage the player deals to a wall on a single chop
public int wallDamage = 1;
//food points the player gains by picking up food
public int pointsPerFood = 10;
public int pointsPerSoda = 20;
public float restartLevelDelay = 1f;

private Animator animator;
private int food;

// Use this for initialization
protected override void Start()
{
animator = GetComponent();

food = GameManager.instance.playerFoodPoints;
}

private void OnDisable()
{
GameManager.instance.playerFoodPoints = food;
}

protected override void attemptMove(int xDir, int yDir)
{
Debug.Log(“player.attemtmove” + food + "
");

food–;

base.attemptMove(xDir, yDir);

RaycastHit2D hit;

checkIfGameOver();

GameManager.instance.playersTurn = false;
}

private void checkIfGameOver()
{
if (food <= 0)
{
GameManager.instance.gameOver();
}
}

// Update is called once per frame
void Update()
{
if (!GameManager.instance.playersTurn)
{
return;
}

int horizontal = 0;
int vertical = 0;

horizontal = (int)Input.GetAxisRaw(“Horizontal”);
vertical = (int)Input.GetAxisRaw(“Vertical”);

//prevent diagonal movement
if (horizontal != 0)
{
vertical = 0;
}
if (horizontal != 0 || vertical != 0)
{
attemptMove(horizontal, vertical);
}
}

protected override void onCantMove(T component)
{
Wall hitWall = component as Wall;
hitWall.damageWall(wallDamage);
animator.SetTrigger(“playerChop”);
}

private void restart()
{
Application.LoadLevel(Application.loadedLevel);
}

public void loseFood(int loss)
{
animator.SetTrigger(“playerHit”);
food -= loss;
checkIfGameOver();
}

private void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == “Exit”)
{
Invoke(“restart”, restartLevelDelay);
enabled = false;
}
else if (other.tag == “Food”)
{
food += pointsPerFood;
other.gameObject.SetActive(false);
}
else if (other.tag == “Soda”)
{
food += pointsPerSoda;
other.gameObject.SetActive(false);
}
}
}

Enemy script:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Enemy : MovingObjekt
{

public int playerDamage;

private Animator animator;
private Transform target;
private bool skipMove = true;

// Use this for initialization
protected override void Start()
{
GameManager.instance.addEnemyToList(this);
animator = GetComponent();
target = GameObject.FindGameObjectWithTag(“Player”).transform;
base.Start();
}

protected override void attemptMove(int xDir, int yDir)
{
if (skipMove)
{
skipMove = false;
return;
}

base.attemptMove(xDir, yDir);

skipMove = true;
}

public void moveEnemy()
{
int xDir = 0;
int yDir = 0;

if (Mathf.Abs(target.position.x - transform.position.x) < float.Epsilon)
{
//short form of an if{}else{}
yDir = target.position.y > transform.position.y ? 1 : -1;
}
else if (Mathf.Abs(target.position.y - transform.position.y) < float.Epsilon)
{
xDir = target.position.x > transform.position.x ? 1 : -1;
}

//move in the general direktion towards the player
attemptMove(xDir, yDir);
}

protected override void onCantMove(T component)
{
Player hitPlayer = component as Player;

animator.SetTrigger(“EnemyAttack”);

hitPlayer.loseFood(playerDamage);
}
}

Thanks in advance :slight_smile: , i hope i posted enough information to solve this problem.

if(hit.transform == null)

try

if(hit == null)

instead. You can’t talk to a transform if it’s parent is null.

Ok ,
i got it now xD. I forgot to call the base start funktion in my player script so the components wount be referenced in the variable , thats why im getting a null pointer .

Problem solved. But any way thanks for your help guys :slight_smile: