Creating Custom Type

You can create custom types Manually or Automatically using Type Creator.

Automatically using Type Creator

In the Unity Editor, at the Toolbar, Go to Window > Save Game Pro > Type Creator to open Type Creator window.

Save Game Pro - Window Menu

now in this window you can search for the desired type and create it at the specified path, if the Type you are looking for is a custom type that is created by you, you can find it at Assembly-CSharpassembly, and searching in the Types panel for the type name.

Save Game Pro - Type Creator Window

Manually

Create a new C# script and name it SaveGameType_{Your Type Name Here} and open it.

Now, place this template code in the script and replace the Type name and script name with your own values:

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

namespace BayatGames.SaveGamePro.Serialization.Types
{

	/// <summary>
	/// Save Game Type MyCustomType serialization implementation.
	/// </summary>
	public class SaveGameType_MyCustomType : SaveGameType
	{

		/// <summary>
		/// Gets the associated type for this custom type.
		/// </summary>
		/// <value>The type of the associated.</value>
		public override Type AssociatedType
		{
			get
			{
				return typeof ( MyCustomType );
			}
		}

		/// <summary>
		/// Write the specified value using the writer.
		/// </summary>
		/// <param name="value">Value.</param>
		/// <param name="writer">Writer.</param>
		public override void Write ( object value, ISaveGameWriter writer )
		{
                    base.Write ( value, writer );
		}

		/// <summary>
		/// Read the data using the reader.
		/// </summary>
		/// <param name="reader">Reader.</param>
		public override object Read ( ISaveGameReader reader )
		{
                    base.Read ( reader );
		}

		/// <summary>
		/// Read the data into the specified value.
		/// </summary>
		/// <param name="value">Value.</param>
		/// <param name="reader">Reader.</param>
		public override void ReadInto ( object value, ISaveGameReader reader )
		{
                    base.ReadInto ( value, reader );
		}

	}

}

Now, replace the MyCustomType with your own desired type.

Here is a example type that helps you make your desired type:

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

namespace BayatGames.SaveGamePro.Serialization.Types
{

	/// <summary>
	/// Save Game Type Vector3 serialization implementation.
	/// </summary>
	public class SaveGameType_Vector3 : SaveGameType
	{

		/// <summary>
		/// Gets the associated type for this custom type.
		/// </summary>
		/// <value>The type of the associated.</value>
		public override Type AssociatedType
		{
			get
			{
				return typeof ( UnityEngine.Vector3 );
			}
		}

		/// <summary>
		/// Write the specified value using the writer.
		/// </summary>
		/// <param name="value">Value.</param>
		/// <param name="writer">Writer.</param>
		public override void Write ( object value, ISaveGameWriter writer )
		{
			UnityEngine.Vector3 vector3 = ( UnityEngine.Vector3 )value;
			writer.WriteProperty ( "x", vector3.x );
			writer.WriteProperty ( "y", vector3.y );
			writer.WriteProperty ( "z", vector3.z );
		}

		/// <summary>
		/// Read the data using the reader.
		/// </summary>
		/// <param name="reader">Reader.</param>
		public override object Read ( ISaveGameReader reader )
		{
			UnityEngine.Vector3 vector3 = new UnityEngine.Vector3 ();
			foreach ( string property in reader.Properties )
			{
				switch ( property )
				{
					case "x":
						vector3.x = reader.ReadProperty<System.Single> ();
						break;
					case "y":
						vector3.y = reader.ReadProperty<System.Single> ();
						break;
					case "z":
						vector3.z = reader.ReadProperty<System.Single> ();
						break;
				}
			}
			return vector3;
		}

		/// <summary>
		/// Read the data into the specified value.
		/// </summary>
		/// <param name="value">Value.</param>
		/// <param name="reader">Reader.</param>
		public override void ReadInto ( object value, ISaveGameReader reader )
		{
			base.ReadInto ( value, reader );
		}

	}

}

Now, use the same approach to make your custom type savable.

Note: The ReadInto is used for classes and not for structs, that means if your custom type is a class, you should use both Read and ReadInto.

Note: If your type is a Component, you can SaveGameType.CreateComponent to initialize the component with a game object, we use this inside Read method, here is an example of Component type:

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

namespace BayatGames.SaveGamePro.Serialization.Types
{

	/// <summary>
	/// Save Game Type BoxCollider2D serialization implementation.
	/// </summary>
	public class SaveGameType_BoxCollider2D : SaveGameType
	{

		/// <summary>
		/// Gets the associated type for this custom type.
		/// </summary>
		/// <value>The type of the associated.</value>
		public override Type AssociatedType
		{
			get
			{
				return typeof ( UnityEngine.BoxCollider2D );
			}
		}

		/// <summary>
		/// Write the specified value using the writer.
		/// </summary>
		/// <param name="value">Value.</param>
		/// <param name="writer">Writer.</param>
		public override void Write ( object value, ISaveGameWriter writer )
		{
			UnityEngine.BoxCollider2D boxCollider2D = ( UnityEngine.BoxCollider2D )value;
			writer.WriteProperty ( "size", boxCollider2D.size );
			writer.WriteProperty ( "edgeRadius", boxCollider2D.edgeRadius );
			writer.WriteProperty ( "autoTiling", boxCollider2D.autoTiling );
			writer.WriteProperty ( "density", boxCollider2D.density );
			writer.WriteProperty ( "isTrigger", boxCollider2D.isTrigger );
			writer.WriteProperty ( "usedByEffector", boxCollider2D.usedByEffector );
			writer.WriteProperty ( "usedByComposite", boxCollider2D.usedByComposite );
			writer.WriteProperty ( "offset", boxCollider2D.offset );
			writer.WriteProperty ( "sharedMaterial", boxCollider2D.sharedMaterial );
			writer.WriteProperty ( "enabled", boxCollider2D.enabled );
			writer.WriteProperty ( "tag", boxCollider2D.tag );
			writer.WriteProperty ( "name", boxCollider2D.name );
			writer.WriteProperty ( "hideFlags", boxCollider2D.hideFlags );
		}

		/// <summary>
		/// Read the data using the reader.
		/// </summary>
		/// <param name="reader">Reader.</param>
		public override object Read ( ISaveGameReader reader )
		{
			UnityEngine.BoxCollider2D boxCollider2D = SaveGameType.CreateComponent<UnityEngine.BoxCollider2D> ();
			ReadInto ( boxCollider2D, reader );
			return boxCollider2D;
		}

		/// <summary>
		/// Read the data into the specified value.
		/// </summary>
		/// <param name="value">Value.</param>
		/// <param name="reader">Reader.</param>
		public override void ReadInto ( object value, ISaveGameReader reader )
		{
			UnityEngine.BoxCollider2D boxCollider2D = ( UnityEngine.BoxCollider2D )value;
			foreach ( string property in reader.Properties )
			{
				switch ( property )
				{
					case "size":
						boxCollider2D.size = reader.ReadProperty<UnityEngine.Vector2> ();
						break;
					case "edgeRadius":
						boxCollider2D.edgeRadius = reader.ReadProperty<System.Single> ();
						break;
					case "autoTiling":
						boxCollider2D.autoTiling = reader.ReadProperty<System.Boolean> ();
						break;
					case "density":
						boxCollider2D.density = reader.ReadProperty<System.Single> ();
						break;
					case "isTrigger":
						boxCollider2D.isTrigger = reader.ReadProperty<System.Boolean> ();
						break;
					case "usedByEffector":
						boxCollider2D.usedByEffector = reader.ReadProperty<System.Boolean> ();
						break;
					case "usedByComposite":
						boxCollider2D.usedByComposite = reader.ReadProperty<System.Boolean> ();
						break;
					case "offset":
						boxCollider2D.offset = reader.ReadProperty<UnityEngine.Vector2> ();
						break;
					case "sharedMaterial":
						if ( boxCollider2D.sharedMaterial == null )
						{
							boxCollider2D.sharedMaterial = reader.ReadProperty<UnityEngine.PhysicsMaterial2D> ();
						}
						else
						{
							reader.ReadIntoProperty<UnityEngine.PhysicsMaterial2D> ( boxCollider2D.sharedMaterial );
						}
						break;
					case "enabled":
						boxCollider2D.enabled = reader.ReadProperty<System.Boolean> ();
						break;
					case "tag":
						boxCollider2D.tag = reader.ReadProperty<System.String> ();
						break;
					case "name":
						boxCollider2D.name = reader.ReadProperty<System.String> ();
						break;
					case "hideFlags":
						boxCollider2D.hideFlags = reader.ReadProperty<UnityEngine.HideFlags> ();
						break;
				}
			}
		}

	}

}