NullReferenceException when reading plugin dataSolved

Hey there,

I'm new to C# and currently developing a simple plugin to enable players to spawn a mini helicopter.

When trying to write/access my pluginData Object (see code below, it's marked), the console responds with

NullReferenceException: Object reference not set to an instance of an object 

I know that my Object aka the reference to it (pluginData) cannot be found there, but I cannot find out why. I started off by simply copy/pasting from an existing plugin where it is being handled the same way, and it works there, so seemingly I'm doing something different but I can't find the error. I'm able to access pluginConfig at the same point w/o any problems, but why can't I access pluginData?

A little push into the right direction would be highly appreciated, also any tips if you find something outdated in my code.

Thanks, pyr0pete

using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Convert = System.Convert;
using System;
using System.Linq;
using System.Collections.Generic;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("MyMozzie", "pyr0pete", "0.3.0")]
	[Description("Players can spawn a mozzie by using either a cooldown timer or a custom crafting recipe")]
    public class MyMozzie : RustPlugin
    {
		private PluginConfig pluginConfig;
		private PluginData pluginData;			
		private const string prefab = "assets/content/vehicles/minicopter/minicopter.entity.prefab";
		private bool onCooldown = false;	
		
		const string myMozzieSpawn = "mymozzie.spawn";
		const string myMozzieRemove = "mymozzie.remove";
				
		public Dictionary<ulong, BaseVehicle > baseplayerMozzie = new Dictionary<ulong, BaseVehicle>();
				
		private class PluginConfig
		{
			public bool enableCooldown;
			public bool enableDecay;
			public bool enableSpawnCheck;
			public bool enableSleeperCheck;
			public double cooldownMinutes;
		}
		
		class PluginData
		{
			public Dictionary<ulong, uint> playerMozzieID = new Dictionary<ulong, uint>();
            public Dictionary<ulong, double> playerMozzieCounter = new Dictionary<ulong, double>();
            public PluginData()
			{
            }			
        }   		
		
		private void Init()
		{
			pluginConfig = Config.ReadObject<PluginConfig>();	
			//pluginData = Interface.Oxide.DataFileSystem.ReadObject<PluginData>(Name);						
		}

		protected override void LoadDefaultConfig()
		{
			Config.WriteObject(GetDefaultConfig(), true);
		}

		private PluginConfig GetDefaultConfig()
		{
			Puts($"No config file found, creating a new one");	
			return new PluginConfig
			{
				enableCooldown = true,
				enableDecay = true,
				enableSpawnCheck = true,
				enableSleeperCheck = true,
				cooldownMinutes = 2						
			};			
		}
				
		void Loaded()
        {	
			if(((pluginConfig.cooldownMinutes * 60) < 120) & pluginConfig.enableCooldown)
            {
                Puts($"Cooldown timer has been reset to 2 minutes");
                pluginConfig.cooldownMinutes = 2;
                return;
            }				
 			permission.RegisterPermission(myMozzieSpawn, this);
			permission.RegisterPermission(myMozzieRemove, this);
			pluginData = Interface.Oxide.DataFileSystem.ReadObject<PluginData>(Name);
        }
		
		private void Unload()
        {
            SaveData();
			baseplayerMozzie = null;
            pluginData = null;            
        }
		
		private void SaveData()
        {
			Interface.Oxide.DataFileSystem.WriteObject(Name, pluginData);
        }
					
		protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                {"haveMozzie", "You already have spawned a mozzie, <i>douche</i>"},
                {"spawnedMozzie", "<color=yellow>You have spawned a mozzie. Happy flying!</color>"},
                {"removedMozzie", "Your mozzie has been removed"},
                {"locatedMozzie", "Your mozzie is located at {0}"},
                {"cooldownMozzie", "You have to wait until you can spawn a new mozzie"},               
                {"blockedMozzie", "You are unable to spawn a mozzie while in a building blocked area"},
				{"nopermMozzie", "You are not allowed to spawn a mozzie"}
            }, this, "en");			
        }		
		
		private string str(string msgID, BasePlayer player, params object[] args)
        {
            var msg = lang.GetMessage(msgID, this, player?.UserIDString);
            return args.Length > 0 ? string.Format(msg, args) : msg;
        }

        private void PrintMsgL(BasePlayer player, string msgID, params object[] args)
        {
            if(player == null) return;
            PrintMsg(player, str(msgID, player, args));
        }
	
        private void PrintMsg(BasePlayer player, string msg)
        {
            if(player == null) return;
            SendReply(player, $"{msg}");
		}			 
		
		// spawn 		
        [ChatCommand("mozzie")]
		private void ChatMyMozzieSpawn(BasePlayer player, string command, string[] args)
        {
			if(pluginData.playerMozzieID.ContainsKey(player.userID)) // <-- this fails, pluginData cannot be found
            {
				PrintMsgL(player, "haveMozzie");				
                return;
            }
			if(player.IsBuildingBlocked() & pluginConfig.enableSpawnCheck)
            {
                PrintMsgL(player, "blockedMozzie");
                return;
            }				
			MyMozzieSpawn(player);			
        }
		// remove 
        [ChatCommand("removemozzie")]
        private void ChatMyMozzieRemove(BasePlayer player, string command, string[] args)
        {
			MyMozzieRemove(player);
        }
		
		private void MyMozzieSpawn(BasePlayer player)
        {
			Quaternion rotation = player.GetNetworkRotation();
            Vector3 forward = rotation * Vector3.forward;
            Vector3 straight = Vector3.Cross(Vector3.Cross(Vector3.up, forward), Vector3.up).normalized;
            Vector3 position = player.transform.position + straight * 4f;
            position.y = player.transform.position.y + 1.5f;

            if(position == null) return;
            BaseVehicle vehicleMozzie = (BaseVehicle)GameManager.server.CreateEntity(prefab, position, new Quaternion());
            if(vehicleMozzie == null) return;
            BaseEntity mozzieEntity = vehicleMozzie as BaseEntity;
            mozzieEntity.OwnerID = player.userID;

            MiniCopter mozzie = vehicleMozzie as MiniCopter;
            vehicleMozzie.Spawn();
			
            PrintMsgL(player, "spawnedMozzie");
            uint mozzieuint = vehicleMozzie.net.ID;
			//#if DEBUG
			Puts($"Player {player.displayName} spawned a new mozzie");
			//#endif
            pluginData.playerMozzieID.Remove(player.userID);
            pluginData.playerMozzieID.Add(player.userID, mozzieuint);
			
            SaveData();
			
            baseplayerMozzie.Remove(player.userID);
            baseplayerMozzie.Add(player.userID, vehicleMozzie);
			
            mozzieEntity = null;
            mozzie = null;
	
        }
		
        private void MyMozzieRemove(BasePlayer player)
        {          
			if(pluginData.playerMozzieID.ContainsKey(player.userID))
            {
                uint deluint;
                pluginData.playerMozzieID.TryGetValue(player.userID, out deluint);
                var entity = BaseNetworkable.serverEntities.Find(deluint);
                if(entity != null)
                {
                    entity.Kill();
					PrintMsgL(player, "removedMozzie");
                }
                pluginData.playerMozzieID.Remove(player.userID);
                baseplayerMozzie.Remove(player.userID);

                if(pluginData.playerMozzieCounter.ContainsKey(player.userID))
                {
                    pluginData.playerMozzieCounter.Remove(player.userID);
                }
                SaveData();
            }
		}	

	}
}
You need to check for null after you read the json, if it is - instantiate pluginData and then save.
Also there are no need to set variables to null, .net will automatically determine when the object has no references left to it. 
Hey, thanks a lot, I managed to make it work!
Locked automatically