WXMC/.svn/pristine/83/83fe535abba547d4ac100441f76113aacd9ad5a6.svn-base

349 lines
11 KiB
Plaintext
Raw Normal View History

2024-12-04 16:18:46 +08:00
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();
}
}