Custom classes inside custom class - error

Easy Save 2 has been replaced by Easy Save 3, so is no longer supported.
Locked
drwayyyne
Posts: 5
Joined: Fri Mar 27, 2015 1:01 pm

Custom classes inside custom class - error

Post by drwayyyne »

Hey Moodkie-Team,

I have a custom class "Agency" holding other custom classes, the latter being stored inside Lists. I have added all custom classes to Assets/Easy Save 2/Types, yet Unity tells me "Easy Save does not support loading of type Agency".

Code: Select all

public class ES2UserType_Agency : ES2Type
{
	public override void Write(object obj, ES2Writer writer)
	{
		Agency data = (Agency)obj;
		// Add your writer.Write calls here.
		writer.Write(data.Funds);
		writer.Write(data.Wages);
		writer.Write(data.Expenses);
		writer.Write(data.AgentsList);
		writer.Write(data.SIGINTList);
		writer.Write(data.ApplicantHUMINTList);
		writer.Write(data.ApplicantSIGINTList);
	}
	
	public override void Read(ES2Reader reader, Component c)
	{
		Agency data = (Agency)c;
		// Add your reader.Read calls here to read the data into the Component.
        data.Funds = reader.Read<System.Int32>();
        data.Wages = reader.Read<System.Int32>();
        data.Expenses = reader.Read<System.Int32>();
		data.AgentsList = reader.ReadList<Agent>();
		data.SIGINTList = reader.ReadList<Officer_SIGINT>();
		data.ApplicantHUMINTList = reader.ReadList<Applicant_HUMINT>();
		data.ApplicantSIGINTList = reader.ReadList<Applicant_SIGINT>();
	}
	
	/* ! Don't modify anything below this line ! */
	
	public ES2UserType_Agency():base(typeof(Agency)){}
	
	public override object Read(ES2Reader reader)
	{
		Agency param = GetOrCreate<Agency>();
		Read(reader, param);
		return param;
	}
}

Here is the code for loading, using ES2Reader sequentially.

Code: Select all

		using(ES2Reader reader = ES2Reader.Create(string.Concat (loadName, ".iam")))
		{
			// Read data from the file in any order.
            // 1. LOAD YOUR AGENCY
            this.yourAgency = reader.Read<Agency>();

            // 2. LOAD YOUR HOMESTATE
            this.homeState = reader.Read<State>();

            // 3. LOAD TERRORIST ORGANIZATION
            this.TOList = reader.ReadList<TerroristOrganization>();

            // 4. LOAD INGAME TIME
            clockRef.overall = reader.Read<float>();
            clockRef.hour1 = reader.Read<int>();
            clockRef.hour2 = reader.Read<int>();
            clockRef.minute1 = reader.Read<int>();
            clockRef.minute2 = reader.Read<int>();
            clockRef.ampm = reader.Read<string>();
            clockRef.day = reader.Read<int>();
            clockRef.workingTime = reader.Read<bool>();

            // 5. LOAD PLAYER POSITION
            reader.Read<Transform>(player.transform);
      }
I also get the same error for all my other custom classes. Could this be related to saving without tags and/or having custom classes inside other custom ones?


Thanks a lot in advance,
David
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: Custom classes inside custom class - error

Post by Joel »

Hi David,

Try going to the Assets/Easy Save 2/Manage Types... menu and pressing Refresh ES2Init. If you manually added the ES2Type files, this will register them with the type list.

If this doesn't fix your problem, please could you paste me the ES2Init.cs file found in the Assets/Easy Save 2 folder so I can see that everything is being registered properly.

All the best,
Joel
drwayyyne
Posts: 5
Joined: Fri Mar 27, 2015 1:01 pm

Re: Custom classes inside custom class - error

Post by drwayyyne »

Hi Joel,

thanks for the fast reply. Refresh ES2Init did the trick, thanks!

However, now I get follow-up errors. Upon saving, Unity throws the following message:

Code: Select all

NullReferenceException: Object reference not set to an instance of an object
ES2Writer.Write[Target] (.Target param)
ES2UserType_City.Write (System.Object obj, .ES2Writer writer) (at Assets/Easy Save 2/Types/ES2UserType_City.cs:22)
ES2Writer.Write[Object] (System.Object param, .ES2Type type)
ES2Writer.Write[City] (System.Collections.Generic.List`1 param, .ES2Type type)
ES2Writer.Write[City] (System.Collections.Generic.List`1 param)
ES2UserType_State.Write (System.Object obj, .ES2Writer writer) (at Assets/Easy Save 2/Types/ES2UserType_State.cs:16)
ES2Writer.Write[State] (.State param, .ES2Type type)
ES2Writer.Write[State] (.State param)
LoadSave.Save (System.String saveName) (at Assets/Scripts/LoadSave.cs:82)
PauseMenu.YesOnWarningPanel () (at Assets/Scripts/PauseMenu.cs:114)
UnityEngine.Events.InvokableCall.Invoke (System.Object[] args) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:110)
UnityEngine.Events.InvokableCallList.Invoke (System.Object[] parameters) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:574)
UnityEngine.Events.UnityEventBase.Invoke (System.Object[] parameters) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:716)
UnityEngine.Events.UnityEvent.Invoke () (at C:/buildslave/unity/build/Runtime/Export/UnityEvent_0.cs:53)
UnityEngine.UI.Button.Press () (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:35)
UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:44)
UnityEngine.EventSystems.ExecuteEvents.Execute (IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:52)
UnityEngine.EventSystems.ExecuteEvents.Execute[IPointerClickHandler] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.EventFunction`1 functor) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:269)
UnityEngine.EventSystems.EventSystem:Update()
This is the referenced file, with "writer.Write(data.StockMarket);" being line 22.

Code: Select all

	public override void Write(object obj, ES2Writer writer)
	{
		City data = (City)obj;
		// Add your writer.Write calls here.
		writer.Write(data.Name);
		writer.Write(data.Population);
		writer.Write(data.PoliceStation);
		writer.Write(data.TrainStation);
		writer.Write(data.Mall);
		writer.Write(data.Church);
		writer.Write(data.Airport);
		writer.Write(data.SeatOfGovernment);
		writer.Write(data.Parliament);
		writer.Write(data.StockMarket);

	}
I cannot figure out what is wrong here, especially why Unity is blaming this specific line. Do you have any ideas on this?

David
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: Custom classes inside custom class - error

Post by Joel »

Hi David,

Please could you send/paste me the ES2Type file for the type of your StockMarket variable, and the ES2Init.cs file from Assets/Easy Save 2? This error is characteristic of types not registering properly.

It can also be caused when the value you're saving is set to null, so you might also want to check that data.StockMarket isn't null.

All the best,
Joel
drwayyyne
Posts: 5
Joined: Fri Mar 27, 2015 1:01 pm

Re: Custom classes inside custom class - error

Post by drwayyyne »

Hey Joel,

so I checked that neither data.StockMarket nor any variables of it are null. What I think is weird is that data.StockMarket is of the same type as the seven variables before it, which is "Target". Here is the ES2UserType file for it:

Code: Select all

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


public class ES2UserType_Target : ES2Type
{
	public override void Write(object obj, ES2Writer writer)
	{
		Target data = (Target)obj;
		// Add your writer.Write calls here.
		writer.Write(data.Targettype);
		writer.Write(data.Type);
		writer.Write(data.Security);
		writer.Write(data.Deathrate);
		writer.Write(data.Occupants);
		writer.Write(data.Choose);

	}
	
	public override void Read(ES2Reader reader, Component c)
	{
		Target data = (Target)c;
		// Add your reader.Read calls here to read the data into the Component.
		data.Targettype = reader.Read<System.String>();
		data.Type = reader.Read<System.Int32>();
		data.Security = reader.Read<System.Int32>();
		data.Deathrate = reader.Read<System.Double>();
		data.Occupants = reader.Read<System.Int32>();
		data.Choose = reader.Read<System.Int32>();

	}
	
	/* ! Don't modify anything below this line ! */
	
	public ES2UserType_Target():base(typeof(Target)){}
	
	public override object Read(ES2Reader reader)
	{
		Target param = GetOrCreate<Target>();
		Read(reader, param);
		return param;
	}
}
This is the ES2Init.cs file.

Code: Select all

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

[ExecuteInEditMode]				
public class ES2Init : MonoBehaviour
{
	public void Awake()
	{
		Init();
	}
	
	public void Start()
	{
		if(Application.isEditor)
			GameObject.DestroyImmediate(gameObject);
		else
			GameObject.Destroy(gameObject);
	}

	public static void Init()
	{
		ES2TypeManager.types = new Dictionary<Type, ES2Type>();
				ES2TypeManager.types[typeof(UnityEngine.Vector2)] = new ES2_Vector2();
		ES2TypeManager.types[typeof(UnityEngine.Vector3)] = new ES2_Vector3();
		ES2TypeManager.types[typeof(UnityEngine.Vector4)] = new ES2_Vector4();
		ES2TypeManager.types[typeof(UnityEngine.Texture2D)] = new ES2_Texture2D();
		ES2TypeManager.types[typeof(UnityEngine.Quaternion)] = new ES2_Quaternion();
		ES2TypeManager.types[typeof(UnityEngine.Mesh)] = new ES2_Mesh();
		ES2TypeManager.types[typeof(UnityEngine.Color)] = new ES2_Color();
		ES2TypeManager.types[typeof(UnityEngine.Color32)] = new ES2_Color32();
		ES2TypeManager.types[typeof(UnityEngine.Material)] = new ES2_Material();
		ES2TypeManager.types[typeof(UnityEngine.Rect)] = new ES2_Rect();
		ES2TypeManager.types[typeof(UnityEngine.Bounds)] = new ES2_Bounds();
		ES2TypeManager.types[typeof(UnityEngine.Transform)] = new ES2_Transform();
		ES2TypeManager.types[typeof(UnityEngine.BoxCollider)] = new ES2_BoxCollider();
		ES2TypeManager.types[typeof(UnityEngine.CapsuleCollider)] = new ES2_CapsuleCollider();
		ES2TypeManager.types[typeof(UnityEngine.SphereCollider)] = new ES2_SphereCollider();
		ES2TypeManager.types[typeof(UnityEngine.MeshCollider)] = new ES2_MeshCollider();
		ES2TypeManager.types[typeof(System.Boolean)] = new ES2_bool();
		ES2TypeManager.types[typeof(System.Byte)] = new ES2_byte();
		ES2TypeManager.types[typeof(System.Char)] = new ES2_char();
		ES2TypeManager.types[typeof(System.Decimal)] = new ES2_decimal();
		ES2TypeManager.types[typeof(System.Double)] = new ES2_double();
		ES2TypeManager.types[typeof(System.Single)] = new ES2_float();
		ES2TypeManager.types[typeof(System.Int32)] = new ES2_int();
		ES2TypeManager.types[typeof(System.Int64)] = new ES2_long();
		ES2TypeManager.types[typeof(System.Int16)] = new ES2_short();
		ES2TypeManager.types[typeof(System.String)] = new ES2_string();
		ES2TypeManager.types[typeof(System.UInt32)] = new ES2_uint();
		ES2TypeManager.types[typeof(System.UInt64)] = new ES2_ulong();
		ES2TypeManager.types[typeof(System.UInt16)] = new ES2_ushort();
		ES2TypeManager.types[typeof(System.Enum)] = new ES2_Enum();
		ES2TypeManager.types[typeof(UnityEngine.Matrix4x4)] = new ES2_Matrix4x4();
		ES2TypeManager.types[typeof(UnityEngine.BoneWeight)] = new ES2_BoneWeight();
		ES2TypeManager.types[typeof(UnityEngine.SkinnedMeshRenderer)] = new ES2_SkinnedMeshRenderer();
		ES2TypeManager.types[typeof(System.SByte)] = new ES2_sbyte();
		ES2TypeManager.types[typeof(Agency)] = new ES2UserType_Agency();
		ES2TypeManager.types[typeof(Agent)] = new ES2UserType_Agent();
		ES2TypeManager.types[typeof(Applicant_HUMINT)] = new ES2UserType_Applicant_HUMINT();
		ES2TypeManager.types[typeof(Applicant_SIGINT)] = new ES2UserType_Applicant_SIGINT();
		ES2TypeManager.types[typeof(Bomb)] = new ES2UserType_Bomb();
		ES2TypeManager.types[typeof(City)] = new ES2UserType_City();
		ES2TypeManager.types[typeof(Government)] = new ES2UserType_Government();
		ES2TypeManager.types[typeof(Officer_SIGINT)] = new ES2UserType_Officer_SIGINT();
		ES2TypeManager.types[typeof(Operation)] = new ES2UserType_Operation();
		ES2TypeManager.types[typeof(Politician)] = new ES2UserType_Politician();
		ES2TypeManager.types[typeof(State)] = new ES2UserType_State();
		ES2TypeManager.types[typeof(Target)] = new ES2UserType_Target();
		ES2TypeManager.types[typeof(Terrorist)] = new ES2UserType_Terrorist();
		ES2TypeManager.types[typeof(TerroristBuilder)] = new ES2UserType_TerroristBuilder();
		ES2TypeManager.types[typeof(TerroristLeader)] = new ES2UserType_TerroristLeader();
		ES2TypeManager.types[typeof(TerroristOrganization)] = new ES2UserType_TerroristOrganization();
		ES2TypeManager.types[typeof(TerroristPlan)] = new ES2UserType_TerroristPlan();
		ES2TypeManager.types[typeof(UnityEngine.Sprite)] = new ES2_Sprite();

	}
}

Thanks so much for looking into this.
David


*** EDIT ***

Ahhh, forget about it, I was being stupid. data.StockMarket really is null in the moment ES2 tries to call it for the first time. I think I know how to go on from here, thanks so much for the help!
User avatar
Joel
Moodkie Staff
Posts: 4826
Joined: Wed Nov 07, 2012 10:32 pm

Re: Custom classes inside custom class - error

Post by Joel »

Not a problem David, let me know if you run into any other problems!

- Joel
Locked