349 lines
11 KiB
Plaintext
349 lines
11 KiB
Plaintext
|
|
using System.Collections.Generic;
|
|
using System.Runtime.Serialization;
|
|
using System.Linq;
|
|
|
|
using UnityEngine;
|
|
using UnityEngine.AddressableAssets;
|
|
using System.Reflection;
|
|
using CommonSerializeDefine;
|
|
using System.Text.RegularExpressions;
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
using UnityEditor;
|
|
using UnityEditor.Build;
|
|
using UnityEditor.Build.Reporting;
|
|
|
|
public class PreBuildScript : IPreprocessBuildWithReport
|
|
{
|
|
// The order in which the callback will be executed relative to other preprocess build callbacks.
|
|
public int callbackOrder => 0;
|
|
|
|
// This method will be called before the build starts.
|
|
public void OnPreprocessBuild(BuildReport report)
|
|
{
|
|
PrefabChecker.CheckAndCreatePrefab();
|
|
}
|
|
}
|
|
|
|
[InitializeOnLoad]
|
|
public static class PrefabChecker
|
|
{
|
|
static PrefabChecker()
|
|
{
|
|
// Subscribe to the event that's called after scripts are recompiled
|
|
//EditorApplication.delayCall += CheckAndCreatePrefab;
|
|
EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
|
|
}
|
|
|
|
private static void OnPlayModeStateChanged(PlayModeStateChange state)
|
|
{
|
|
// Check if the editor is about to enter Play mode
|
|
if (state == PlayModeStateChange.ExitingEditMode)
|
|
{
|
|
CheckAndCreatePrefab();
|
|
}
|
|
}
|
|
|
|
public static void CheckAndCreatePrefab()
|
|
{
|
|
// Path to the folder containing the prefab
|
|
string prefabPath = $"Assets/Resources/{ODUnityObjectMapper.MapperResourcePath}.prefab";
|
|
|
|
// Load the prefab
|
|
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
|
|
|
|
if (prefab == null)
|
|
{
|
|
Debug.LogWarning($"Prefab not found at path: {prefabPath}. Creating a new one.");
|
|
|
|
// Create a new GameObject and add the ODUnitySerializer component
|
|
GameObject newPrefab = new GameObject("ObjectMapper");
|
|
var comp = newPrefab.AddComponent<ODUnityObjectMapper>();
|
|
|
|
try
|
|
{
|
|
GatherUnityObjects(comp);
|
|
|
|
// Create the necessary directories if they don't exist
|
|
string directoryPath = "Assets/Resources/ODUnityExtension/ObjectMapping";
|
|
if (!AssetDatabase.IsValidFolder(directoryPath))
|
|
{
|
|
AssetDatabase.CreateFolder("Assets", "Resources");
|
|
AssetDatabase.CreateFolder("Assets/Resources", "ODUnityExtension");
|
|
AssetDatabase.CreateFolder("Assets/Resources/ODUnityExtension", "ObjectMapping");
|
|
}
|
|
|
|
// Save the new GameObject as a prefab
|
|
PrefabUtility.SaveAsPrefabAsset(newPrefab, prefabPath);
|
|
Debug.Log($"New prefab created at path: {prefabPath}");
|
|
}
|
|
finally
|
|
{
|
|
// Destroy the temporary GameObject
|
|
MonoBehaviour.DestroyImmediate(prefab);
|
|
Debug.Log($"{prefab} prefab destroyed");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Check if the prefab has the ODUnitySerializer component
|
|
if (prefab.GetComponent<ODUnityObjectMapper>() == null)
|
|
{
|
|
Debug.LogWarning($"Prefab at path: {prefabPath} does not contain an ODUnitySerializer component. Adding the component.");
|
|
|
|
// Add the component to the prefab
|
|
var comp = prefab.AddComponent<ODUnityObjectMapper>();
|
|
GatherUnityObjects(comp);
|
|
|
|
EditorUtility.SetDirty(prefab);
|
|
AssetDatabase.SaveAssets();
|
|
}
|
|
else
|
|
{
|
|
GatherUnityObjects(prefab.GetComponent<ODUnityObjectMapper>());
|
|
EditorUtility.SetDirty(prefab);
|
|
AssetDatabase.SaveAssets();
|
|
|
|
Debug.Log("Prefab check passed. ODUnitySerializer component exists.");
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void GatherUnityObjects(ODUnityObjectMapper mapper)
|
|
{
|
|
mapper.AllUnityObjects = new List<Object>();
|
|
mapper.AllUnityObjectGUIDs = new List<string>();
|
|
foreach (var item in GetAllUnityObjects(mapper.WhiteListPath))
|
|
{
|
|
mapper.AllUnityObjects.Add(item.Key);
|
|
mapper.AllUnityObjectGUIDs.Add(item.Value);
|
|
}
|
|
}
|
|
|
|
private static IEnumerable<KeyValuePair<UnityEngine.Object, string>> GetAllUnityObjects(IEnumerable<string> whileList = null)
|
|
{
|
|
string[] guids = AssetDatabase.FindAssets("t:ScriptableObject t:Prefab");
|
|
|
|
foreach (string guid in guids)
|
|
{
|
|
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
|
|
if (whileList != null && whileList.Count() != 0)
|
|
{
|
|
if (!whileList.Any(str => assetPath.StartsWith(str)))
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
Object asset = AssetDatabase.LoadAssetAtPath<Object>(assetPath);
|
|
|
|
if (asset is ScriptableObject scriptableObject)
|
|
{
|
|
yield return new KeyValuePair<UnityEngine.Object, string>(asset, guid);
|
|
}
|
|
else if (asset is GameObject prefab)
|
|
{
|
|
yield return new KeyValuePair<UnityEngine.Object, string>(asset, guid);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
public class ODUnityPrefabSerializer
|
|
{
|
|
public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
|
|
{
|
|
ODUnityObjectMapper mapper = ODUnityObjectMapper.ObjectMapper;
|
|
GameObject prefab = obj as GameObject;
|
|
string guid = mapper.GetObjectGUID(prefab);
|
|
info.AddValue("guid", guid);
|
|
}
|
|
|
|
public IEnumerable<System.Type> GetSerializeTypes()
|
|
{
|
|
yield return typeof(GameObject);
|
|
}
|
|
|
|
public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
|
|
{
|
|
ODUnityObjectMapper mapper = ODUnityObjectMapper.ObjectMapper;
|
|
string guid = info.GetString("guid");
|
|
return mapper.GetObject(guid);
|
|
}
|
|
}
|
|
|
|
public static class UnitySerializerUtils
|
|
{
|
|
public static string RemoveContentInParentheses(string input)
|
|
{
|
|
if (input == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (input.Length == 0)
|
|
{
|
|
return input;
|
|
}
|
|
|
|
// Regular expression to match content inside parentheses including the parentheses
|
|
string pattern = @"\([^)]*\)";
|
|
|
|
// Replace all matches with an empty string
|
|
string result = Regex.Replace(input, pattern, string.Empty);
|
|
|
|
// Return the cleaned-up string
|
|
return result;
|
|
}
|
|
}
|
|
|
|
public class GameObjectSerializer : CommonSerializeDefine.ITypeSerializer
|
|
{
|
|
public bool CanSerialize(System.Type type)
|
|
{
|
|
return type == typeof(GameObject);
|
|
}
|
|
|
|
public object Deserialize(string obj, System.Type type, IDeserializer deserializer)
|
|
{
|
|
obj = UnitySerializerUtils.RemoveContentInParentheses(obj);
|
|
if (XHelper.StringUtils.IsEmpty(obj))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
ODUnityObjectMapper mapper = ODUnityObjectMapper.ObjectMapper;
|
|
GameObject go = mapper.GetObject(obj) as GameObject;
|
|
//return go.GetComponent(info.ObjectType);
|
|
return go;
|
|
}
|
|
|
|
public string Serialize(object obj, System.Type type, ISerializer serializer)
|
|
{
|
|
GameObject go = obj as GameObject;
|
|
ODUnityObjectMapper mapper = ODUnityObjectMapper.ObjectMapper;
|
|
return $"({go.name}){mapper.GetObjectGUID(go)}";
|
|
}
|
|
}
|
|
|
|
public class ComponentSerializer : CommonSerializeDefine.ITypeSerializer
|
|
{
|
|
public bool CanSerialize(System.Type type)
|
|
{
|
|
return type.IsSubclassOf(typeof(MonoBehaviour));
|
|
}
|
|
|
|
public object Deserialize(string obj, System.Type type, IDeserializer deserializer)
|
|
{
|
|
obj = UnitySerializerUtils.RemoveContentInParentheses(obj);
|
|
if (XHelper.StringUtils.IsEmpty(obj))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
ODUnityObjectMapper mapper = ODUnityObjectMapper.ObjectMapper;
|
|
GameObject go = mapper.GetObject(obj) as GameObject;
|
|
return go.GetComponent(type);
|
|
}
|
|
|
|
public string Serialize(object obj, System.Type type, ISerializer serializer)
|
|
{
|
|
MonoBehaviour mono = (MonoBehaviour)obj;
|
|
GameObject go = mono.gameObject;
|
|
|
|
ODUnityObjectMapper mapper = ODUnityObjectMapper.ObjectMapper;
|
|
|
|
return $"({go.name}.{type.Name}){mapper.GetObjectGUID(go)}";
|
|
}
|
|
}
|
|
|
|
public class ScriptableObjectSerializer : CommonSerializeDefine.ITypeSerializer
|
|
{
|
|
public bool CanSerialize(System.Type type)
|
|
{
|
|
return type.IsSubclassOf(typeof(ScriptableObject));
|
|
}
|
|
|
|
public object Deserialize(string obj, System.Type type, IDeserializer deserializer)
|
|
{
|
|
obj = UnitySerializerUtils.RemoveContentInParentheses(obj);
|
|
if (XHelper.StringUtils.IsEmpty(obj))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
ODUnityObjectMapper mapper = ODUnityObjectMapper.ObjectMapper;
|
|
return mapper.GetObject(obj);
|
|
}
|
|
|
|
public string Serialize(object obj, System.Type type, ISerializer serializer)
|
|
{
|
|
ScriptableObject so = obj as ScriptableObject;
|
|
ODUnityObjectMapper mapper = ODUnityObjectMapper.ObjectMapper;
|
|
return $"({so.name}){mapper.GetObjectGUID(so)}";
|
|
}
|
|
}
|
|
|
|
public class AddressableSerializer : CommonSerializeDefine.ITypeSerializer
|
|
{
|
|
public bool CanSerialize(System.Type type)
|
|
{
|
|
if (type == typeof(AssetReference))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(AssetReferenceT<>))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public object Deserialize(string obj, System.Type type, IDeserializer deserializer)
|
|
{
|
|
obj = UnitySerializerUtils.RemoveContentInParentheses(obj);
|
|
if (XHelper.StringUtils.IsEmpty(obj))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
string guid;
|
|
string subObjectName;
|
|
|
|
int index = obj.IndexOf(':');
|
|
if (index == -1)
|
|
{
|
|
guid = obj;
|
|
subObjectName = "";
|
|
}
|
|
else
|
|
{
|
|
guid = obj.Substring(0, index);
|
|
subObjectName = obj.Substring(index + 1);
|
|
}
|
|
|
|
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(AssetReferenceT<>))
|
|
{
|
|
AssetReference asset = System.Activator.CreateInstance(type, guid) as AssetReference;
|
|
asset.SubObjectName = subObjectName;
|
|
return obj;
|
|
}
|
|
else
|
|
{
|
|
AssetReference asset = new AssetReference(guid);
|
|
asset.SubObjectName = subObjectName;
|
|
return asset;
|
|
}
|
|
}
|
|
|
|
public string Serialize(object obj, System.Type type, ISerializer serializer)
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
} |