Skip to content

Instantly share code, notes, and snippets.

@Seneral
Last active December 2, 2017 23:03
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Seneral/d88d2079ff17f77f2bd1775aadb8547b to your computer and use it in GitHub Desktop.
Save Seneral/d88d2079ff17f77f2bd1775aadb8547b 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. 1. Enable force text serialization in ProjectSettings/Editor 2. Right click on the asset in the version it was serialized in and select the target version. 3. Move the created file with the _Converted suffix into the target project.
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.activeInstanceID == 0 )
return false;
string path = AssetDatabase.GetAssetPath(Selection.activeInstanceID);
return !string.IsNullOrEmpty(path) && File.Exists (path);
}
public static void ConvertSelectedAssetSerializationVersion(int version)
{
if (EditorSettings.serializationMode != SerializationMode.ForceText)
Debug.LogWarning("Did you forget to set 'ForceText' as serialization mode in 'Edit/Project Settings/Editor'?");
string path = AssetDatabase.GetAssetPath(Selection.activeInstanceID);
if (string.IsNullOrEmpty(path) || !File.Exists(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 = path.Replace("Assets", Application.dataPath);
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 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;
}
}
@nicloay
Copy link

nicloay commented Aug 15, 2017

Does this mean that if you upgrade the scene and prefab used in this scene you have to:

  1. Downgrade the scene
  2. Downgrade prefab
  3. Open project in previous version.
  4. Relink downgraded prefabs manually on downgraded scenes (in all scenes where this prefab used)
  5. Move downgraded scene and prefabs to original location

@Seneral
Copy link
Author

Seneral commented Sep 21, 2017

Sorry for the late answer, don't get notifications for gist.
No, I do not change IDs - it SHOULD work just fine. Just worried, now that you say it, that the prefabs are automatically assigned a new ID by unity as it is imported after converting. So try to only move the converted prefabs and replace the broken prefabs in the old version with it only and leave the meta alone, then the reference should be fine (meta files contain the reference ID I think). Hope that works for you:)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment