Skip to content

Instantly share code, notes, and snippets.

@nicloay
Forked from Seneral/ConvertSerializationVersion.cs
Last active August 15, 2017 14:04
Show Gist options
  • Save nicloay/fe3b793feb036efc7cb464c22b8091d8 to your computer and use it in GitHub Desktop.
Save nicloay/fe3b793feb036efc7cb464c22b8091d8 to your computer and use it in GitHub Desktop.
Script to convert files serialized in 5.5 to previous unity versions based on the text format.

Usage

  1. Make sure that you use source control system or make a backup for the whole of your project.
  2. Enable force text serialization in ProjectSettings/Editor
  3. Right click on the asset in the version it was serialized in and select the target version. You can use search patterns to select only required assets in the one folder. like t:Scene and then in the menu below click on the current folder. mostcommon:
  • t:Scene
  • t:Prefab
  • t:ScriptableObject
  1. Move the created file with the _Converted suffix into the target project.

Postprocess

Bash script to move _Converted files to origin location

find . -name '*_Converted*' -print0| while read -d $'\0' file; do dst=$(echo $file|sed "s|_Converted||"); mv "$file" "$dst";done

Troubleshooting

In Case if you face any problem first thing what you have to do is open EditorLog file. See log location here.

Unity may crash at start on conversion process when you first open you downgraded project in previous version, but it will show you the error which cause this crash.

using UnityEngine;
using UnityEditor;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
public static class ConvertSerializationVersion
{
private static Regex objectIDSearch = new Regex("--- !u!(?:[0-9]{1,5}) &([0-9]*)");
[MenuItem("Assets/Convert Serialization Version 5.0", false)]
public static void ConvertSerializationVersion50 () { ConvertSelectedAssetSerializationVersion (1); }
[MenuItem("Assets/Convert Serialization Version 5.3", false)]
public static void ConvertSerializationVersion53 () { ConvertSelectedAssetSerializationVersion (2); }
[MenuItem("Assets/Convert Serialization Version 5.5", false)]
public static void ConvertSerializationVersion55 () { ConvertSelectedAssetSerializationVersion (3); }
[MenuItem("Assets/Convert Serialization Version 5.0", true)]
[MenuItem("Assets/Convert Serialization Version 5.3", true)]
[MenuItem("Assets/Convert Serialization Version 5.5", true)]
public static bool ValidateAsset ()
{
if (Selection.activeObject == null || Selection.activeObject.GetType () == typeof (UnityEditor.DefaultAsset))
return false;
return !string.IsNullOrEmpty (AssetDatabase.GetAssetPath (Selection.activeInstanceID));
}
public static void ConvertSelectedAssetSerializationVersion (int version)
{
foreach (var instanceID in Selection.instanceIDs)
{
string path = AssetDatabase.GetAssetPath (instanceID);
Debug.Log(string.Format("Handling instanceId:{0}, path:{1}", instanceID, path));
if (string.IsNullOrEmpty (path))
throw new System.InvalidOperationException ("Selected object is not an asset!");
// Fetch serialized data
StringBuilder data = new StringBuilder (File.ReadAllText (path));
if (data.Length == 0)
throw new System.FormatException ("Could not read text from asset '" + path + "'! Make sure you have text serialization force on!");
// Convert data to new version
SetSerializationVersion (ref data, version);
// Save converted file
path = Path.GetDirectoryName (path) + Path.AltDirectorySeparatorChar + Path.GetFileNameWithoutExtension (path) + "_Converted" + Path.GetExtension (path);
if (path.StartsWith ("Assets"))
path = Application.dataPath + path.Substring(6);
File.WriteAllText (path, data.ToString ());
AssetDatabase.Refresh ();
}
}
public static bool SetSerializationVersion (ref StringBuilder data, int version)
{
if (version < 2)
{ // Pre 5.3 the file IDs were under 10 chars long (usually 8 or 9 max), Longer IDs, which are used in 5.3+, will corrupt the file
MatchCollection matches = objectIDSearch.Matches (data.ToString ());
foreach (Match match in matches)
{
if (match.Groups.Count != 2)
{
Debug.LogWarning ("Discarding match '" + match.Value + "'!");
continue;
}
string key = match.Groups[0].Value;
string id = match.Groups[1].Value;
if (id.Length > 10)
{ // Cut id string length (TODO: make sure no duplicate IDs are existing when cutting chars, although unlikely)
string cutID = id.Substring (0, 8);
data.Replace (id, cutID);
}
}
}
if (version < 3) // Just lower serialized version for GameObjects only so Unity doesn't mess with the data (fixes empty name field pre-5.5)
data.Replace ("serializedVersion: 5", "serializedVersion: 4");
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment