Files
ShellosDollhouse/Assets/Udon/Serialization/OdinSerializer/Unity Integration/OdinPrefabSerializationEditorUtility.cs
T

130 lines
5.7 KiB
C#

//-----------------------------------------------------------------------
// <copyright file="OdinPrefabSerializationEditorUtility.cs" company="Sirenix IVS">
// Copyright (c) 2018 Sirenix IVS
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
//-----------------------------------------------------------------------
//#define PREFAB_DEBUG
#if UNITY_EDITOR
namespace VRC.Udon.Serialization.OdinSerializer
{
using System;
using System.Reflection;
using UnityEditor;
using UnityEngine;
public static class OdinPrefabSerializationEditorUtility
{
private static bool? hasNewPrefabWorkflow;
private static MethodInfo PrefabUtility_GetPrefabAssetType_Method = typeof(PrefabUtility).GetMethod("GetPrefabAssetType", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(UnityEngine.Object) }, null);
private static MethodInfo PrefabUtility_GetPrefabParent_Method = typeof(PrefabUtility).GetMethod("GetPrefabParent", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(UnityEngine.Object) }, null);
private static MethodInfo PrefabUtility_GetCorrespondingObjectFromSource_Method = typeof(PrefabUtility).GetMethod("GetCorrespondingObjectFromSource", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(UnityEngine.Object) }, null);
private static MethodInfo PrefabUtility_GetPrefabType_Method = typeof(PrefabUtility).GetMethod("GetPrefabType", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(UnityEngine.Object) }, null);
public static bool HasNewPrefabWorkflow
{
get
{
if (hasNewPrefabWorkflow == null)
{
hasNewPrefabWorkflow = DetectNewPrefabWorkflow();
}
return hasNewPrefabWorkflow.Value;
}
}
private static bool DetectNewPrefabWorkflow()
{
try
{
var method = typeof(PrefabUtility).GetMethod("GetPrefabType", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(UnityEngine.Object) }, null);
if (method == null) return true;
if (method.IsDefined(typeof(ObsoleteAttribute), false))
{
return true;
}
return false;
}
catch
{
return false;
}
}
public static bool ObjectIsPrefabInstance(UnityEngine.Object unityObject)
{
if (PrefabUtility_GetPrefabType_Method != null)
{
try
{
int prefabType = Convert.ToInt32((Enum)PrefabUtility_GetPrefabType_Method.Invoke(null, new object[] { unityObject }));
// PrefabType.PrefabInstance == 3
if (prefabType == 3) return true;
}
catch (Exception) { }
}
if (PrefabUtility_GetPrefabAssetType_Method != null)
{
int prefabAssetType = Convert.ToInt32((Enum)PrefabUtility_GetPrefabAssetType_Method.Invoke(null, new object[] { unityObject }));
// 1 = PrefabAssetType.Regular
// 3 = PrefabAssetType.Variant
return prefabAssetType == 1 || prefabAssetType == 3;
}
if (PrefabUtility_GetPrefabType_Method == null && PrefabUtility_GetPrefabAssetType_Method == null)
{
Debug.LogError("Neither PrefabUtility.GetPrefabType or PrefabUtility.GetPrefabAssetType methods could be located. Prefab functionality will likely be broken in this build of Odin.");
}
return GetCorrespondingObjectFromSource(unityObject) != null;
}
public static bool ObjectHasNestedOdinPrefabData(UnityEngine.Object unityObject)
{
if (!HasNewPrefabWorkflow) return false;
if (!(unityObject is ISupportsPrefabSerialization)) return false;
var prefab = GetCorrespondingObjectFromSource(unityObject);
return IsOdinSerializedPrefabInstance(prefab);
}
private static bool IsOdinSerializedPrefabInstance(UnityEngine.Object unityObject)
{
if (!(unityObject is ISupportsPrefabSerialization)) return false;
return GetCorrespondingObjectFromSource(unityObject) != null;
}
public static UnityEngine.Object GetCorrespondingObjectFromSource(UnityEngine.Object unityObject)
{
if (PrefabUtility_GetCorrespondingObjectFromSource_Method != null)
{
return (UnityEngine.Object)PrefabUtility_GetCorrespondingObjectFromSource_Method.Invoke(null, new object[] { unityObject });
}
if (PrefabUtility_GetPrefabParent_Method != null)
{
return (UnityEngine.Object)PrefabUtility_GetPrefabParent_Method.Invoke(null, new object[] { unityObject });
}
Debug.LogError("Neither PrefabUtility.GetCorrespondingObjectFromSource or PrefabUtility.GetPrefabParent methods could be located. Prefab functionality will be broken in this build of Odin.");
return null;
}
}
}
#endif