Added Unity project files
This commit is contained in:
@ -0,0 +1,766 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="AOTSupportScanner.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
using VRC.Core;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer.Editor
|
||||
{
|
||||
using Utilities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using System.Reflection;
|
||||
using UnityEngine.SceneManagement;
|
||||
using System.Collections;
|
||||
|
||||
public sealed class AOTSupportScanner : IDisposable
|
||||
{
|
||||
private bool scanning;
|
||||
private bool allowRegisteringScannedTypes;
|
||||
private HashSet<Type> seenSerializedTypes = new HashSet<Type>();
|
||||
private HashSet<string> scannedPathsNoDependencies = new HashSet<string>();
|
||||
private HashSet<string> scannedPathsWithDependencies = new HashSet<string>();
|
||||
|
||||
private static System.Diagnostics.Stopwatch smartProgressBarWatch = System.Diagnostics.Stopwatch.StartNew();
|
||||
private static int smartProgressBarDisplaysSinceLastUpdate = 0;
|
||||
|
||||
private static readonly MethodInfo PlayerSettings_GetPreloadedAssets_Method = typeof(PlayerSettings).GetMethod("GetPreloadedAssets", BindingFlags.Public | BindingFlags.Static, null, Type.EmptyTypes, null);
|
||||
private static readonly PropertyInfo Debug_Logger_Property = typeof(Debug).GetProperty("unityLogger") ?? typeof(Debug).GetProperty("logger");
|
||||
|
||||
public void BeginScan()
|
||||
{
|
||||
this.scanning = true;
|
||||
allowRegisteringScannedTypes = false;
|
||||
|
||||
this.seenSerializedTypes.Clear();
|
||||
this.scannedPathsNoDependencies.Clear();
|
||||
this.scannedPathsWithDependencies.Clear();
|
||||
|
||||
FormatterLocator.OnLocatedEmittableFormatterForType += this.OnLocatedEmitType;
|
||||
FormatterLocator.OnLocatedFormatter += this.OnLocatedFormatter;
|
||||
Serializer.OnSerializedType += this.OnSerializedType;
|
||||
}
|
||||
|
||||
public bool ScanPreloadedAssets(bool showProgressBar)
|
||||
{
|
||||
// The API does not exist in this version of Unity
|
||||
if (PlayerSettings_GetPreloadedAssets_Method == null) return true;
|
||||
|
||||
UnityEngine.Object[] assets = (UnityEngine.Object[])PlayerSettings_GetPreloadedAssets_Method.Invoke(null, null);
|
||||
|
||||
if (assets == null) return true;
|
||||
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < assets.Length; i++)
|
||||
{
|
||||
if (showProgressBar && DisplaySmartUpdatingCancellableProgressBar("Scanning preloaded assets for AOT support", (i + 1) + " / " + assets.Length, (float)i / assets.Length))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var asset = assets[i];
|
||||
|
||||
if (asset == null) continue;
|
||||
|
||||
if (AssetDatabase.Contains(asset))
|
||||
{
|
||||
// Scan the asset and all its dependencies
|
||||
var path = AssetDatabase.GetAssetPath(asset);
|
||||
this.ScanAsset(path, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just scan the asset
|
||||
this.ScanObject(asset);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (showProgressBar)
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool ScanAssetBundle(string bundle)
|
||||
{
|
||||
string[] assets = AssetDatabase.GetAssetPathsFromAssetBundle(bundle);
|
||||
|
||||
foreach (var asset in assets)
|
||||
{
|
||||
this.ScanAsset(asset, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool ScanAllAssetBundles(bool showProgressBar)
|
||||
{
|
||||
try
|
||||
{
|
||||
string[] bundles = AssetDatabase.GetAllAssetBundleNames();
|
||||
|
||||
for (int i = 0; i < bundles.Length; i++)
|
||||
{
|
||||
var bundle = bundles[i];
|
||||
|
||||
if (showProgressBar && DisplaySmartUpdatingCancellableProgressBar("Scanning asset bundles for AOT support", bundle, (float)i / bundles.Length))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
this.ScanAssetBundle(bundle);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (showProgressBar)
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool ScanAllAddressables(bool includeAssetDependencies, bool showProgressBar)
|
||||
{
|
||||
// We don't know whether the addressables package is installed or not. So... needs must.
|
||||
// Our only real choice is to utilize reflection that's stocked to the brim with failsafes
|
||||
// and error logging.
|
||||
//
|
||||
// Truly, the code below should not have needed to be written.
|
||||
|
||||
// The following section is the code as it would be without reflection. Please modify this
|
||||
// code reference to be accurate if the reflection code is changed.
|
||||
|
||||
/*
|
||||
|
||||
var settings = UnityEditor.AddressableAssets.AddressableAssetSettingsDefaultObject.Settings;
|
||||
|
||||
if (settings != null && settings.groups != null)
|
||||
{
|
||||
foreach (AddressableAssetGroup group in settings.groups)
|
||||
{
|
||||
if (group.HasSchema(typeof(PlayerDataGroupSchema))) continue;
|
||||
|
||||
List<AddressableAssetEntry> results = new List<AddressableAssetEntry>();
|
||||
|
||||
group.GatherAllAssets(results, true, true, true, null);
|
||||
|
||||
foreach (var result in results)
|
||||
{
|
||||
this.ScanAsset(result.AssetPath, includeAssetDependencies);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
bool progressBarWasDisplayed = false;
|
||||
|
||||
try
|
||||
{
|
||||
Type AddressableAssetSettingsDefaultObject_Type = TwoWaySerializationBinder.Default.BindToType("UnityEditor.AddressableAssets.AddressableAssetSettingsDefaultObject");
|
||||
if (AddressableAssetSettingsDefaultObject_Type == null) return true;
|
||||
PropertyInfo AddressableAssetSettingsDefaultObject_Settings = AddressableAssetSettingsDefaultObject_Type.GetProperty("Settings");
|
||||
if (AddressableAssetSettingsDefaultObject_Settings == null) throw new NotSupportedException("AddressableAssetSettingsDefaultObject.Settings property not found");
|
||||
ScriptableObject settings = (ScriptableObject)AddressableAssetSettingsDefaultObject_Settings.GetValue(null, null);
|
||||
|
||||
if (settings == null) return true;
|
||||
|
||||
Type AddressableAssetSettings_Type = settings.GetType();
|
||||
PropertyInfo AddressableAssetSettings_groups = AddressableAssetSettings_Type.GetProperty("groups");
|
||||
if (AddressableAssetSettings_groups == null) throw new NotSupportedException("AddressableAssetSettings.groups property not found");
|
||||
|
||||
IList groups = (IList)AddressableAssetSettings_groups.GetValue(settings, null);
|
||||
|
||||
if (groups == null) return true;
|
||||
|
||||
Type PlayerDataGroupSchema_Type = TwoWaySerializationBinder.Default.BindToType("UnityEditor.AddressableAssets.Settings.GroupSchemas.PlayerDataGroupSchema");
|
||||
if (PlayerDataGroupSchema_Type == null) throw new NotSupportedException("PlayerDataGroupSchema type not found");
|
||||
|
||||
Type AddressableAssetGroup_Type = null;
|
||||
MethodInfo AddressableAssetGroup_HasSchema = null;
|
||||
MethodInfo AddressableAssetGroup_GatherAllAssets = null;
|
||||
|
||||
Type AddressableAssetEntry_Type = TwoWaySerializationBinder.Default.BindToType("UnityEditor.AddressableAssets.Settings.AddressableAssetEntry");
|
||||
if (AddressableAssetEntry_Type == null) throw new NotSupportedException("AddressableAssetEntry type not found");
|
||||
Type List_AddressableAssetEntry_Type = typeof(List<>).MakeGenericType(AddressableAssetEntry_Type);
|
||||
Type Func_AddressableAssetEntry_bool_Type = typeof(Func<,>).MakeGenericType(AddressableAssetEntry_Type, typeof(bool));
|
||||
PropertyInfo AddressableAssetEntry_AssetPath = AddressableAssetEntry_Type.GetProperty("AssetPath");
|
||||
if (AddressableAssetEntry_AssetPath == null) throw new NotSupportedException("AddressableAssetEntry.AssetPath property not found");
|
||||
|
||||
foreach (object groupObj in groups)
|
||||
{
|
||||
ScriptableObject group = (ScriptableObject)groupObj;
|
||||
if (group == null) continue;
|
||||
|
||||
string groupName = group.name;
|
||||
|
||||
if (AddressableAssetGroup_Type == null)
|
||||
{
|
||||
AddressableAssetGroup_Type = group.GetType();
|
||||
AddressableAssetGroup_HasSchema = AddressableAssetGroup_Type.GetMethod("HasSchema", Flags.InstancePublic, null, new Type[] { typeof(Type) }, null);
|
||||
if (AddressableAssetGroup_HasSchema == null) throw new NotSupportedException("AddressableAssetGroup.HasSchema(Type type) method not found");
|
||||
AddressableAssetGroup_GatherAllAssets = AddressableAssetGroup_Type.GetMethod("GatherAllAssets", Flags.InstancePublic, null, new Type[] { List_AddressableAssetEntry_Type, typeof(bool), typeof(bool), typeof(bool), Func_AddressableAssetEntry_bool_Type }, null);
|
||||
if (AddressableAssetGroup_GatherAllAssets == null) throw new NotSupportedException("AddressableAssetGroup.GatherAllAssets(List<AddressableAssetEntry> results, bool includeSelf, bool recurseAll, bool includeSubObjects, Func<AddressableAssetEntry, bool> entryFilter) method not found");
|
||||
}
|
||||
|
||||
bool hasPlayerDataGroupSchema = (bool)AddressableAssetGroup_HasSchema.Invoke(group, new object[] { PlayerDataGroupSchema_Type });
|
||||
if (hasPlayerDataGroupSchema) continue; // Skip this group, since it contains all the player data such as resources and build scenes, and we're scanning that separately
|
||||
|
||||
IList results = (IList)Activator.CreateInstance(List_AddressableAssetEntry_Type);
|
||||
|
||||
AddressableAssetGroup_GatherAllAssets.Invoke(group, new object[] { results, true, true, true, null });
|
||||
|
||||
for (int i = 0; i < results.Count; i++)
|
||||
{
|
||||
object entry = (object)results[i];
|
||||
if (entry == null) continue;
|
||||
string assetPath = (string)AddressableAssetEntry_AssetPath.GetValue(entry, null);
|
||||
|
||||
if (showProgressBar)
|
||||
{
|
||||
progressBarWasDisplayed = true;
|
||||
|
||||
if (DisplaySmartUpdatingCancellableProgressBar("Scanning addressables for AOT support", groupName + ": " + assetPath, (float)i / results.Count))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Finally!
|
||||
this.ScanAsset(assetPath, includeAssetDependencies);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NotSupportedException ex)
|
||||
{
|
||||
Debug.LogWarning("Could not AOT scan Addressables assets due to missing APIs: " + ex.Message);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError("Scanning addressables failed with the following exception...");
|
||||
Debug.LogException(ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (progressBarWasDisplayed)
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool ScanAllResources(bool includeResourceDependencies, bool showProgressBar, List<string> resourcesPaths = null)
|
||||
{
|
||||
if (resourcesPaths == null)
|
||||
{
|
||||
resourcesPaths = new List<string>() {""};
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (showProgressBar && DisplaySmartUpdatingCancellableProgressBar("Scanning resources for AOT support", "Loading resource assets", 0f))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var resourcesPathsSet = new HashSet<string>();
|
||||
|
||||
for (int i = 0; i < resourcesPaths.Count; i++)
|
||||
{
|
||||
var resourcesPath = resourcesPaths[i];
|
||||
|
||||
if (showProgressBar && DisplaySmartUpdatingCancellableProgressBar("Listing resources for AOT support", resourcesPath, (float)i / resourcesPaths.Count))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var resources = Resources.LoadAll(resourcesPath);
|
||||
|
||||
foreach (var resource in resources)
|
||||
{
|
||||
try
|
||||
{
|
||||
var assetPath = AssetDatabase.GetAssetPath(resource);
|
||||
|
||||
if (assetPath != null)
|
||||
{
|
||||
resourcesPathsSet.Add(assetPath);
|
||||
}
|
||||
}
|
||||
catch (MissingReferenceException ex)
|
||||
{
|
||||
Debug.LogError("A resource threw a missing reference exception when scanning. Skipping resource and continuing scan.", resource);
|
||||
Debug.LogException(ex, resource);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string[] resourcePaths = resourcesPathsSet.ToArray();
|
||||
|
||||
for (int i = 0; i < resourcePaths.Length; i++)
|
||||
{
|
||||
if (resourcePaths[i] == null) continue;
|
||||
|
||||
try
|
||||
{
|
||||
if (showProgressBar && DisplaySmartUpdatingCancellableProgressBar("Scanning resource " + i + " for AOT support", resourcePaths[i], (float)i / resourcePaths.Length))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var assetPath = resourcePaths[i];
|
||||
|
||||
// Exclude editor-only resources
|
||||
if (assetPath.ToLower().Contains("/editor/")) continue;
|
||||
|
||||
this.ScanAsset(assetPath, includeAssetDependencies: includeResourceDependencies);
|
||||
}
|
||||
catch (MissingReferenceException ex)
|
||||
{
|
||||
Debug.LogError("A resource '" + resourcePaths[i] + "' threw a missing reference exception when scanning. Skipping resource and continuing scan.");
|
||||
Debug.LogException(ex);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (showProgressBar)
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool ScanBuildScenes(bool includeSceneDependencies, bool showProgressBar)
|
||||
{
|
||||
var scenePaths = EditorBuildSettings.scenes
|
||||
.Where(n => n.enabled)
|
||||
.Select(n => n.path)
|
||||
.ToArray();
|
||||
|
||||
return this.ScanScenes(scenePaths, includeSceneDependencies, showProgressBar);
|
||||
}
|
||||
|
||||
public bool ScanScenes(string[] scenePaths, bool includeSceneDependencies, bool showProgressBar)
|
||||
{
|
||||
if (scenePaths.Length == 0) return true;
|
||||
|
||||
bool formerForceEditorModeSerialization = UnitySerializationUtility.ForceEditorModeSerialization;
|
||||
|
||||
try
|
||||
{
|
||||
UnitySerializationUtility.ForceEditorModeSerialization = true;
|
||||
|
||||
bool hasDirtyScenes = false;
|
||||
|
||||
for (int i = 0; i < EditorSceneManager.sceneCount; i++)
|
||||
{
|
||||
if (EditorSceneManager.GetSceneAt(i).isDirty)
|
||||
{
|
||||
hasDirtyScenes = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasDirtyScenes && !EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var oldSceneSetup = EditorSceneManager.GetSceneManagerSetup();
|
||||
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < scenePaths.Length; i++)
|
||||
{
|
||||
var scenePath = scenePaths[i];
|
||||
|
||||
if (showProgressBar && DisplaySmartUpdatingCancellableProgressBar("Scanning scenes for AOT support", "Scene " + (i + 1) + "/" + scenePaths.Length + " - " + scenePath, (float)i / scenePaths.Length))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!System.IO.File.Exists(scenePath))
|
||||
{
|
||||
Debug.LogWarning("Skipped AOT scanning scene '" + scenePath + "' for a file not existing at the scene path.");
|
||||
continue;
|
||||
}
|
||||
|
||||
Scene openScene = default(Scene);
|
||||
|
||||
try
|
||||
{
|
||||
openScene = EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Single);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.LogWarning("Skipped AOT scanning scene '" + scenePath + "' for throwing exceptions when trying to load it.");
|
||||
continue;
|
||||
}
|
||||
|
||||
var sceneGOs = Resources.FindObjectsOfTypeAll<GameObject>();
|
||||
|
||||
foreach (var go in sceneGOs)
|
||||
{
|
||||
if (go.scene != openScene) continue;
|
||||
|
||||
if ((go.hideFlags & HideFlags.DontSaveInBuild) == 0)
|
||||
{
|
||||
#if VRC_CLIENT
|
||||
using (go.GetComponentsPooled(out List<ISerializationCallbackReceiver> components))
|
||||
#else
|
||||
ISerializationCallbackReceiver[] components = go.GetComponents<ISerializationCallbackReceiver>();
|
||||
#endif
|
||||
{
|
||||
foreach (var component in components)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.allowRegisteringScannedTypes = true;
|
||||
component.OnBeforeSerialize();
|
||||
|
||||
var prefabSupporter = component as ISupportsPrefabSerialization;
|
||||
|
||||
if (prefabSupporter != null)
|
||||
{
|
||||
// Also force a serialization of the object's prefab modifications, in case there are unknown types in there
|
||||
|
||||
List<UnityEngine.Object> objs = null;
|
||||
var mods = UnitySerializationUtility.DeserializePrefabModifications(prefabSupporter.SerializationData.PrefabModifications, prefabSupporter.SerializationData.PrefabModificationsReferencedUnityObjects);
|
||||
UnitySerializationUtility.SerializePrefabModifications(mods, ref objs);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.allowRegisteringScannedTypes = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load a new empty scene that will be unloaded immediately, just to be sure we completely clear all changes made by the scan
|
||||
// Sometimes this fails for unknown reasons. In that case, swallow any exceptions, and just soldier on and hope for the best!
|
||||
// Additionally, also eat any debug logs that happen here, because logged errors can stop the build process, and we don't want
|
||||
// that to happen.
|
||||
|
||||
UnityEngine.ILogger logger = null;
|
||||
|
||||
if (Debug_Logger_Property != null)
|
||||
{
|
||||
logger = (UnityEngine.ILogger)Debug_Logger_Property.GetValue(null, null);
|
||||
}
|
||||
|
||||
bool previous = true;
|
||||
|
||||
try
|
||||
{
|
||||
if (logger != null)
|
||||
{
|
||||
previous = logger.logEnabled;
|
||||
logger.logEnabled = false;
|
||||
}
|
||||
|
||||
EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
|
||||
}
|
||||
catch { }
|
||||
finally
|
||||
{
|
||||
if (logger != null)
|
||||
{
|
||||
logger.logEnabled = previous;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (oldSceneSetup != null && oldSceneSetup.Length > 0)
|
||||
{
|
||||
if (showProgressBar)
|
||||
{
|
||||
EditorUtility.DisplayProgressBar("Restoring scene setup", "", 1.0f);
|
||||
}
|
||||
EditorSceneManager.RestoreSceneManagerSetup(oldSceneSetup);
|
||||
}
|
||||
}
|
||||
|
||||
if (includeSceneDependencies)
|
||||
{
|
||||
for (int i = 0; i < scenePaths.Length; i++)
|
||||
{
|
||||
var scenePath = scenePaths[i];
|
||||
if (showProgressBar && DisplaySmartUpdatingCancellableProgressBar("Scanning scene dependencies for AOT support", "Scene " + (i + 1) + "/" + scenePaths.Length + " - " + scenePath, (float)i / scenePaths.Length))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string[] dependencies = AssetDatabase.GetDependencies(scenePath, recursive: true);
|
||||
|
||||
foreach (var dependency in dependencies)
|
||||
{
|
||||
this.ScanAsset(dependency, includeAssetDependencies: false); // All dependencies of this asset were already included recursively by Unity
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (showProgressBar)
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
}
|
||||
|
||||
UnitySerializationUtility.ForceEditorModeSerialization = formerForceEditorModeSerialization;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ScanAsset(string assetPath, bool includeAssetDependencies)
|
||||
{
|
||||
if (includeAssetDependencies)
|
||||
{
|
||||
if (this.scannedPathsWithDependencies.Contains(assetPath)) return true; // Already scanned this asset
|
||||
|
||||
this.scannedPathsWithDependencies.Add(assetPath);
|
||||
this.scannedPathsNoDependencies.Add(assetPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.scannedPathsNoDependencies.Contains(assetPath)) return true; // Already scanned this asset
|
||||
|
||||
this.scannedPathsNoDependencies.Add(assetPath);
|
||||
}
|
||||
|
||||
if (assetPath.EndsWith(".unity"))
|
||||
{
|
||||
return this.ScanScenes(new string[] { assetPath }, includeAssetDependencies, false);
|
||||
}
|
||||
|
||||
if (!(assetPath.EndsWith(".asset") || assetPath.EndsWith(".prefab")))
|
||||
{
|
||||
// ScanAsset can only scan .unity, .asset and .prefab assets.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool formerForceEditorModeSerialization = UnitySerializationUtility.ForceEditorModeSerialization;
|
||||
|
||||
try
|
||||
{
|
||||
UnitySerializationUtility.ForceEditorModeSerialization = true;
|
||||
|
||||
var assets = AssetDatabase.LoadAllAssetsAtPath(assetPath);
|
||||
|
||||
if (assets == null || assets.Length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var asset in assets)
|
||||
{
|
||||
if (asset == null) continue;
|
||||
|
||||
this.ScanObject(asset);
|
||||
}
|
||||
|
||||
if (includeAssetDependencies)
|
||||
{
|
||||
string[] dependencies = AssetDatabase.GetDependencies(assetPath, recursive: true);
|
||||
|
||||
foreach (var dependency in dependencies)
|
||||
{
|
||||
this.ScanAsset(dependency, includeAssetDependencies: false); // All dependencies were already included recursively by Unity
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
UnitySerializationUtility.ForceEditorModeSerialization = formerForceEditorModeSerialization;
|
||||
}
|
||||
}
|
||||
|
||||
public void ScanObject(UnityEngine.Object obj)
|
||||
{
|
||||
if (obj is ISerializationCallbackReceiver)
|
||||
{
|
||||
bool formerForceEditorModeSerialization = UnitySerializationUtility.ForceEditorModeSerialization;
|
||||
|
||||
try
|
||||
{
|
||||
UnitySerializationUtility.ForceEditorModeSerialization = true;
|
||||
this.allowRegisteringScannedTypes = true;
|
||||
(obj as ISerializationCallbackReceiver).OnBeforeSerialize();
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.allowRegisteringScannedTypes = false;
|
||||
UnitySerializationUtility.ForceEditorModeSerialization = formerForceEditorModeSerialization;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<Type> EndScan()
|
||||
{
|
||||
if (!this.scanning) throw new InvalidOperationException("Cannot end a scan when scanning has not begun.");
|
||||
|
||||
var result = this.seenSerializedTypes.ToList();
|
||||
this.Dispose();
|
||||
return result;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (this.scanning)
|
||||
{
|
||||
FormatterLocator.OnLocatedEmittableFormatterForType -= this.OnLocatedEmitType;
|
||||
FormatterLocator.OnLocatedFormatter -= this.OnLocatedFormatter;
|
||||
Serializer.OnSerializedType -= this.OnSerializedType;
|
||||
|
||||
this.scanning = false;
|
||||
this.seenSerializedTypes.Clear();
|
||||
this.allowRegisteringScannedTypes = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnLocatedEmitType(Type type)
|
||||
{
|
||||
if (!AllowRegisterType(type)) return;
|
||||
|
||||
this.RegisterType(type);
|
||||
}
|
||||
|
||||
private void OnSerializedType(Type type)
|
||||
{
|
||||
if (!AllowRegisterType(type)) return;
|
||||
|
||||
this.RegisterType(type);
|
||||
}
|
||||
|
||||
private void OnLocatedFormatter(IFormatter formatter)
|
||||
{
|
||||
var type = formatter.SerializedType;
|
||||
|
||||
if (type == null) return;
|
||||
if (!AllowRegisterType(type)) return;
|
||||
this.RegisterType(type);
|
||||
}
|
||||
|
||||
public static bool AllowRegisterType(Type type)
|
||||
{
|
||||
if (IsEditorOnlyAssembly(type.Assembly))
|
||||
return false;
|
||||
|
||||
if (type.IsGenericType)
|
||||
{
|
||||
foreach (var parameter in type.GetGenericArguments())
|
||||
{
|
||||
if (!AllowRegisterType(parameter)) return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool IsEditorOnlyAssembly(Assembly assembly)
|
||||
{
|
||||
return EditorAssemblyNames.Contains(assembly.GetName().Name);
|
||||
}
|
||||
|
||||
private static HashSet<string> EditorAssemblyNames = new HashSet<string>()
|
||||
{
|
||||
"Assembly-CSharp-Editor",
|
||||
"Assembly-UnityScript-Editor",
|
||||
"Assembly-Boo-Editor",
|
||||
"Assembly-CSharp-Editor-firstpass",
|
||||
"Assembly-UnityScript-Editor-firstpass",
|
||||
"Assembly-Boo-Editor-firstpass",
|
||||
typeof(Editor).Assembly.GetName().Name
|
||||
};
|
||||
|
||||
private void RegisterType(Type type)
|
||||
{
|
||||
if (!this.allowRegisteringScannedTypes) return;
|
||||
//if (type.IsAbstract || type.IsInterface) return;
|
||||
if (type.IsGenericType && (type.IsGenericTypeDefinition || !type.IsFullyConstructedGenericType())) return;
|
||||
|
||||
//if (this.seenSerializedTypes.Add(type))
|
||||
//{
|
||||
// Debug.Log("Added " + type.GetNiceFullName());
|
||||
//}
|
||||
|
||||
this.seenSerializedTypes.Add(type);
|
||||
|
||||
if (type.IsGenericType)
|
||||
{
|
||||
foreach (var arg in type.GetGenericArguments())
|
||||
{
|
||||
this.RegisterType(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool DisplaySmartUpdatingCancellableProgressBar(string title, string details, float progress, int updateIntervalByMS = 200, int updateIntervalByCall = 50)
|
||||
{
|
||||
bool updateProgressBar =
|
||||
smartProgressBarWatch.ElapsedMilliseconds >= updateIntervalByMS
|
||||
|| ++smartProgressBarDisplaysSinceLastUpdate >= updateIntervalByCall;
|
||||
|
||||
if (updateProgressBar)
|
||||
{
|
||||
smartProgressBarWatch.Stop();
|
||||
smartProgressBarWatch.Reset();
|
||||
smartProgressBarWatch.Start();
|
||||
|
||||
smartProgressBarDisplaysSinceLastUpdate = 0;
|
||||
|
||||
if (EditorUtility.DisplayCancelableProgressBar(title, details, progress))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 94a6cc2044fcd2cb317b1cdb1e8fcdaf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,418 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="AOTSupportUtilities.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer.Editor
|
||||
{
|
||||
using VRC.Udon.Serialization.OdinSerializer.Utilities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Scripting;
|
||||
|
||||
public static class AOTSupportUtilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Scans the project's build scenes and resources, plus their dependencies, for serialized types to support. Progress bars are shown during the scan.
|
||||
/// </summary>
|
||||
/// <param name="serializedTypes">The serialized types to support.</param>
|
||||
/// <param name="scanBuildScenes">Whether to scan the project's build scenes.</param>
|
||||
/// <param name="scanAllAssetBundles">Whether to scan all the project's asset bundles.</param>
|
||||
/// <param name="scanPreloadedAssets">Whether to scan the project's preloaded assets.</param>
|
||||
/// <param name="scanResources">Whether to scan the project's resources.</param>
|
||||
/// <param name="resourcesToScan">An optional list of the resource paths to scan. Only has an effect if the scanResources argument is true. All the resources will be scanned if null.</param>
|
||||
/// <returns>true if the scan succeeded, false if the scan failed or was cancelled</returns>
|
||||
public static bool ScanProjectForSerializedTypes(out List<Type> serializedTypes, bool scanBuildScenes = true, bool scanAllAssetBundles = true, bool scanPreloadedAssets = true, bool scanResources = true, List<string> resourcesToScan = null, bool scanAddressables = true)
|
||||
{
|
||||
using (var scanner = new AOTSupportScanner())
|
||||
{
|
||||
scanner.BeginScan();
|
||||
|
||||
if (scanBuildScenes && !scanner.ScanBuildScenes(includeSceneDependencies: true, showProgressBar: true))
|
||||
{
|
||||
Debug.Log("Project scan canceled while scanning scenes and their dependencies.");
|
||||
serializedTypes = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (scanResources && !scanner.ScanAllResources(includeResourceDependencies: true, showProgressBar: true, resourcesPaths: resourcesToScan))
|
||||
{
|
||||
Debug.Log("Project scan canceled while scanning resources and their dependencies.");
|
||||
serializedTypes = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (scanAllAssetBundles && !scanner.ScanAllAssetBundles(showProgressBar: true))
|
||||
{
|
||||
Debug.Log("Project scan canceled while scanning asset bundles and their dependencies.");
|
||||
serializedTypes = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (scanPreloadedAssets && !scanner.ScanPreloadedAssets(showProgressBar: true))
|
||||
{
|
||||
Debug.Log("Project scan canceled while scanning preloaded assets and their dependencies.");
|
||||
serializedTypes = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (scanAddressables && !scanner.ScanAllAddressables(includeAssetDependencies: true, showProgressBar: true))
|
||||
{
|
||||
Debug.Log("Project scan canceled while scanning addressable assets and their dependencies.");
|
||||
serializedTypes = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
serializedTypes = scanner.EndScan();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates an AOT DLL, using the given parameters.
|
||||
/// </summary>
|
||||
public static void GenerateDLL(string dirPath, string assemblyName, List<Type> supportSerializedTypes, bool generateLinkXml = true)
|
||||
{
|
||||
#if UNITY_EDITOR && NET_4_6
|
||||
if (!dirPath.EndsWith("/")) dirPath += "/";
|
||||
|
||||
var newDllPath = dirPath + assemblyName;
|
||||
var fullDllPath = newDllPath + ".dll";
|
||||
|
||||
var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName() { Name = assemblyName }, AssemblyBuilderAccess.Save, dirPath);
|
||||
var module = assembly.DefineDynamicModule(assemblyName);
|
||||
|
||||
assembly.SetCustomAttribute(new CustomAttributeBuilder(typeof(EmittedAssemblyAttribute).GetConstructor(new Type[0]), new object[0]));
|
||||
|
||||
// VRChat Edit: Add the UnityAPICompatibilityVersion Attribute for the current version of Unity to skip API Updating.
|
||||
#if UNITY_2019
|
||||
assembly.SetCustomAttribute(new CustomAttributeBuilder(
|
||||
typeof(UnityAPICompatibilityVersionAttribute).GetConstructor(new[]{typeof(string), typeof(bool)}),
|
||||
new object[]{Application.unityVersion, true})
|
||||
);
|
||||
#else
|
||||
assembly.SetCustomAttribute(new CustomAttributeBuilder(
|
||||
typeof(UnityAPICompatibilityVersionAttribute).GetConstructor(new[]{typeof(string)}),
|
||||
new object[]{Application.unityVersion})
|
||||
);
|
||||
#endif
|
||||
|
||||
// The following is a fix for Unity's crappy Mono runtime that doesn't know how to do this sort
|
||||
// of stuff properly
|
||||
//
|
||||
// We must manually remove the "Default Dynamic Assembly" module that is automatically defined,
|
||||
// otherwise a reference to that non-existent module will be saved into the assembly's IL, and
|
||||
// that will cause a multitude of issues.
|
||||
//
|
||||
// We do this by forcing there to be only one module - the one we just defined, and we set the
|
||||
// manifest module to be that module as well.
|
||||
{
|
||||
var modulesField = assembly.GetType().GetField("modules", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
var manifestModuleField = assembly.GetType().GetField("manifest_module", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
if (modulesField != null)
|
||||
{
|
||||
modulesField.SetValue(assembly, new ModuleBuilder[] { module });
|
||||
}
|
||||
|
||||
if (manifestModuleField != null)
|
||||
{
|
||||
manifestModuleField.SetValue(assembly, module);
|
||||
}
|
||||
}
|
||||
|
||||
const int serializedTypesPerType = 100;
|
||||
for(int typeIndex = 0; typeIndex < Mathf.CeilToInt(supportSerializedTypes.Count / (float)serializedTypesPerType); typeIndex++)
|
||||
{
|
||||
var type = module.DefineType($"{assemblyName}.PreventCodeStrippingViaReferences{typeIndex:D4}", TypeAttributes.Abstract | TypeAttributes.Sealed | TypeAttributes.NotPublic);
|
||||
|
||||
CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(typeof(PreserveAttribute).GetConstructor(Type.EmptyTypes), new object[0]);
|
||||
type.SetCustomAttribute(attributeBuilder);
|
||||
|
||||
var staticConstructor = type.DefineTypeInitializer();
|
||||
var il = staticConstructor.GetILGenerator();
|
||||
|
||||
var falseLocal = il.DeclareLocal(typeof(bool));
|
||||
|
||||
il.Emit(OpCodes.Ldc_I4_0); // Load false
|
||||
il.Emit(OpCodes.Stloc, falseLocal); // Set to falseLocal
|
||||
|
||||
HashSet<Type> seenTypes = new HashSet<Type>();
|
||||
|
||||
if(UnityVersion.Major == 2019 && UnityVersion.Minor == 2)
|
||||
{
|
||||
// This here is a hack that fixes Unity's assembly updater triggering faultily in Unity 2019.2
|
||||
// (and in early 2019.3 alphas/betas, but we're not handling those). When it triggers, it edits
|
||||
// the generated AOT assembly such that it immediately causes Unity to hard crash. Having this
|
||||
// type reference present in the assembly prevents that from happening. (Any concrete type in
|
||||
// the serialization assembly would work, this one is just a random pick.)
|
||||
//
|
||||
// Unity should have fixed this in 2019.3, but said that a backport to 2019.2 is not guaranteed
|
||||
// to occur, though it might.
|
||||
|
||||
supportSerializedTypes.Add(typeof(DateTimeFormatter));
|
||||
}
|
||||
|
||||
//var endPoint = il.DefineLabel();
|
||||
//il.Emit(OpCodes.Br, endPoint);
|
||||
|
||||
for(int offset = 0; offset < serializedTypesPerType && offset + typeIndex * serializedTypesPerType < supportSerializedTypes.Count; offset++)
|
||||
{
|
||||
var serializedType = supportSerializedTypes[offset + typeIndex * serializedTypesPerType];
|
||||
if(serializedType == null) continue;
|
||||
|
||||
bool isAbstract = serializedType.IsAbstract || serializedType.IsInterface;
|
||||
|
||||
if(serializedType.IsGenericType && (serializedType.IsGenericTypeDefinition || !serializedType.IsFullyConstructedGenericType()))
|
||||
{
|
||||
Debug.LogError(
|
||||
"Skipping type '" + serializedType.GetNiceFullName() +
|
||||
"'! Type is a generic type definition, or its arguments contain generic parameters; type must be a fully constructed generic type.");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if(seenTypes.Contains(serializedType)) continue;
|
||||
|
||||
seenTypes.Add(serializedType);
|
||||
|
||||
// Reference serialized type
|
||||
{
|
||||
if(serializedType.IsValueType)
|
||||
{
|
||||
var local = il.DeclareLocal(serializedType);
|
||||
|
||||
il.Emit(OpCodes.Ldloca, local);
|
||||
il.Emit(OpCodes.Initobj, serializedType);
|
||||
}
|
||||
else if(!isAbstract)
|
||||
{
|
||||
var constructor = serializedType.GetConstructor(Type.EmptyTypes);
|
||||
|
||||
if(constructor != null)
|
||||
{
|
||||
il.Emit(OpCodes.Newobj, constructor);
|
||||
il.Emit(OpCodes.Pop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reference and/or create formatter type
|
||||
if(!FormatterUtilities.IsPrimitiveType(serializedType) && !typeof(UnityEngine.Object).IsAssignableFrom(serializedType) && !isAbstract)
|
||||
{
|
||||
var actualFormatter = FormatterLocator.GetFormatter(serializedType, SerializationPolicies.Unity);
|
||||
|
||||
if(actualFormatter.GetType().IsDefined<EmittedFormatterAttribute>())
|
||||
{
|
||||
//TODO: Make emitted formatter code compatible with IL2CPP
|
||||
//// Emit an actual AOT formatter into the generated assembly
|
||||
|
||||
//if (this.emitAOTFormatters)
|
||||
//{
|
||||
// var emittedFormatter = FormatterEmitter.EmitAOTFormatter(typeEntry.Type, module, SerializationPolicies.Unity);
|
||||
// var emittedFormatterConstructor = emittedFormatter.GetConstructor(Type.EmptyTypes);
|
||||
|
||||
// il.Emit(OpCodes.Newobj, emittedFormatterConstructor);
|
||||
// il.Emit(OpCodes.Pop);
|
||||
//}
|
||||
}
|
||||
|
||||
var formatters = FormatterLocator.GetAllCompatiblePredefinedFormatters(serializedType, SerializationPolicies.Unity);
|
||||
|
||||
foreach(var formatter in formatters)
|
||||
{
|
||||
// Reference the pre-existing formatter
|
||||
|
||||
var formatterConstructor = formatter.GetType().GetConstructor(Type.EmptyTypes);
|
||||
|
||||
if(formatterConstructor != null)
|
||||
{
|
||||
il.Emit(OpCodes.Newobj, formatterConstructor);
|
||||
il.Emit(OpCodes.Pop);
|
||||
}
|
||||
}
|
||||
|
||||
//// Make sure we have a proper reflection formatter variant if all else goes wrong
|
||||
//il.Emit(OpCodes.Newobj, typeof(ReflectionFormatter<>).MakeGenericType(serializedType).GetConstructor(Type.EmptyTypes));
|
||||
//il.Emit(OpCodes.Pop);
|
||||
}
|
||||
|
||||
ConstructorInfo serializerConstructor;
|
||||
|
||||
// Reference serializer variant
|
||||
if(serializedType.IsValueType)
|
||||
{
|
||||
serializerConstructor = Serializer.Get(serializedType).GetType().GetConstructor(Type.EmptyTypes);
|
||||
|
||||
il.Emit(OpCodes.Newobj, serializerConstructor);
|
||||
|
||||
// The following section is a fix for an issue on IL2CPP for PS4, where sometimes bytecode isn't
|
||||
// generated for methods in base types of needed types - FX, Serializer<T>.ReadValueWeak()
|
||||
// may be missing. This only seems to happen in a relevant way for value types.
|
||||
{
|
||||
var endLabel = il.DefineLabel();
|
||||
|
||||
// Load a false local value, then jump to the end of this segment of code due to that
|
||||
// false value. This is an attempt to trick any potential code flow analysis made
|
||||
// by IL2CPP that checks whether this segment of code is actually run.
|
||||
//
|
||||
// We don't run the code because if we did, that would actually throw a bunch of
|
||||
// exceptions from invalid calls to ReadValueWeak and WriteValueWeak.
|
||||
il.Emit(OpCodes.Ldloc, falseLocal);
|
||||
il.Emit(OpCodes.Brfalse, endLabel);
|
||||
|
||||
var baseSerializerType = typeof(Serializer<>).MakeGenericType(serializedType);
|
||||
|
||||
var readValueWeakMethod = baseSerializerType.GetMethod(
|
||||
"ReadValueWeak",
|
||||
BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
|
||||
null,
|
||||
new Type[] { typeof(IDataReader) },
|
||||
null);
|
||||
|
||||
var writeValueWeakMethod = baseSerializerType.GetMethod(
|
||||
"WriteValueWeak",
|
||||
BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
|
||||
null,
|
||||
new Type[] { typeof(string), typeof(object), typeof(IDataWriter) },
|
||||
null);
|
||||
|
||||
il.Emit(OpCodes.Dup); // Duplicate serializer instance
|
||||
il.Emit(OpCodes.Ldnull); // Load null argument for IDataReader reader
|
||||
il.Emit(OpCodes.Callvirt, readValueWeakMethod); // Call ReadValueWeak on serializer instance
|
||||
il.Emit(OpCodes.Pop); // Pop result of ReadValueWeak
|
||||
|
||||
il.Emit(OpCodes.Dup); // Duplicate serializer instance
|
||||
il.Emit(OpCodes.Ldnull); // Load null argument for string name
|
||||
il.Emit(OpCodes.Ldnull); // Load null argument for object value
|
||||
il.Emit(OpCodes.Ldnull); // Load null argument for IDataWriter writer
|
||||
il.Emit(OpCodes.Callvirt, writeValueWeakMethod); // Call WriteValueWeak on serializer instance
|
||||
|
||||
il.MarkLabel(endLabel); // This is where the code always jumps to, skipping the above
|
||||
}
|
||||
|
||||
il.Emit(OpCodes.Pop); // Pop the serializer instance
|
||||
}
|
||||
else
|
||||
{
|
||||
serializerConstructor = typeof(ComplexTypeSerializer<>).MakeGenericType(serializedType).GetConstructor(Type.EmptyTypes);
|
||||
il.Emit(OpCodes.Newobj, serializerConstructor);
|
||||
il.Emit(OpCodes.Pop);
|
||||
}
|
||||
}
|
||||
|
||||
//il.MarkLabel(endPoint);
|
||||
il.Emit(OpCodes.Ret);
|
||||
|
||||
type.CreateType();
|
||||
}
|
||||
|
||||
if (!Directory.Exists(dirPath))
|
||||
{
|
||||
Directory.CreateDirectory(dirPath);
|
||||
}
|
||||
|
||||
if (File.Exists(fullDllPath))
|
||||
{
|
||||
File.Delete(fullDllPath);
|
||||
}
|
||||
|
||||
if (File.Exists(fullDllPath + ".meta"))
|
||||
{
|
||||
File.Delete(fullDllPath + ".meta");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Sigh, Unity 5.3.0
|
||||
}
|
||||
|
||||
assembly.Save(assemblyName);
|
||||
|
||||
File.Move(newDllPath, fullDllPath);
|
||||
|
||||
if (generateLinkXml)
|
||||
{
|
||||
File.WriteAllText(dirPath + "link.xml",
|
||||
@"<linker>
|
||||
<assembly fullname=""" + assemblyName + @""" preserve=""all""/>
|
||||
</linker>");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Sigh, Unity 5.3.0
|
||||
}
|
||||
|
||||
var pluginImporter = PluginImporter.GetAtPath(fullDllPath) as PluginImporter;
|
||||
|
||||
if (pluginImporter != null)
|
||||
{
|
||||
//pluginImporter.ClearSettings();
|
||||
|
||||
pluginImporter.SetCompatibleWithEditor(false);
|
||||
pluginImporter.SetCompatibleWithAnyPlatform(true);
|
||||
|
||||
// Disable for all standalones
|
||||
pluginImporter.SetCompatibleWithPlatform(BuildTarget.StandaloneLinux64, false);
|
||||
|
||||
if (!UnityVersion.IsVersionOrGreater(2019, 2))
|
||||
{
|
||||
pluginImporter.SetCompatibleWithPlatform((BuildTarget)17, false); // StandaloneLinux
|
||||
pluginImporter.SetCompatibleWithPlatform((BuildTarget)25, false); // StandaloneLinuxUniversal
|
||||
}
|
||||
|
||||
// StandaloneOSXUniversal (<= 2017.2) / StandaloneOSX (>= 2017.3)
|
||||
pluginImporter.SetCompatibleWithPlatform((BuildTarget)2, false);
|
||||
|
||||
if (!UnityVersion.IsVersionOrGreater(2017, 3))
|
||||
{
|
||||
pluginImporter.SetCompatibleWithPlatform((BuildTarget)4, false); // StandaloneOSXIntel
|
||||
pluginImporter.SetCompatibleWithPlatform((BuildTarget)27, false); // StandaloneOSXIntel64
|
||||
}
|
||||
|
||||
pluginImporter.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows, false);
|
||||
//pluginImporter.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows64, false);
|
||||
|
||||
//pluginImporter.SetCompatibleWithPlatform(BuildTarget.Android, false);
|
||||
|
||||
pluginImporter.SaveAndReimport();
|
||||
}
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f5fe153775edbadfa2b659e0e35dc881
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 55ffebf7dee93e24a93effecc78ad42e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,70 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="BaseDictionaryKeyPathProvider.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>
|
||||
//-----------------------------------------------------------------------
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// Not yet documented.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Not yet documented.</typeparam>
|
||||
public abstract class BaseDictionaryKeyPathProvider<T> : IDictionaryKeyPathProvider<T>, IComparer<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Not yet documented.
|
||||
/// </summary>
|
||||
public abstract string ProviderID { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Not yet documented.
|
||||
/// </summary>
|
||||
/// <param name="pathStr">Not yet documented.</param>
|
||||
/// <returns>Not yet documented.</returns>
|
||||
public abstract T GetKeyFromPathString(string pathStr);
|
||||
|
||||
/// <summary>
|
||||
/// Not yet documented.
|
||||
/// </summary>
|
||||
/// <param name="key">Not yet documented.</param>
|
||||
/// <returns>Not yet documented.</returns>
|
||||
public abstract string GetPathStringFromKey(T key);
|
||||
|
||||
/// <summary>
|
||||
/// Not yet documented.
|
||||
/// </summary>
|
||||
/// <param name="x">Not yet documented.</param>
|
||||
/// <param name="y">Not yet documented.</param>
|
||||
/// <returns>Not yet documented.</returns>
|
||||
public abstract int Compare(T x, T y);
|
||||
|
||||
int IDictionaryKeyPathProvider.Compare(object x, object y)
|
||||
{
|
||||
return this.Compare((T)x, (T)y);
|
||||
}
|
||||
|
||||
object IDictionaryKeyPathProvider.GetKeyFromPathString(string pathStr)
|
||||
{
|
||||
return this.GetKeyFromPathString(pathStr);
|
||||
}
|
||||
|
||||
string IDictionaryKeyPathProvider.GetPathStringFromKey(object key)
|
||||
{
|
||||
return this.GetPathStringFromKey((T)key);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 864fb1c011715f9df2998d71ac8716f6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,467 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="DictionaryKeyUtility.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using System.Globalization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using System.Reflection;
|
||||
|
||||
/// <summary>
|
||||
/// Provides utility methods for handling dictionary keys in the prefab modification system.
|
||||
/// </summary>
|
||||
public static class DictionaryKeyUtility
|
||||
{
|
||||
private static readonly Dictionary<Type, bool> GetSupportedDictionaryKeyTypesResults = new Dictionary<Type, bool>();
|
||||
|
||||
private static readonly HashSet<Type> BaseSupportedDictionaryKeyTypes = new HashSet<Type>()
|
||||
{
|
||||
typeof(string),
|
||||
typeof(char),
|
||||
typeof(byte),
|
||||
typeof(sbyte),
|
||||
typeof(ushort),
|
||||
typeof(short),
|
||||
typeof(uint),
|
||||
typeof(int),
|
||||
typeof(ulong),
|
||||
typeof(long),
|
||||
typeof(float),
|
||||
typeof(double),
|
||||
typeof(decimal),
|
||||
typeof(Guid)
|
||||
};
|
||||
|
||||
private static readonly HashSet<char> AllowedSpecialKeyStrChars = new HashSet<char>()
|
||||
{
|
||||
',', '(', ')', '\\', '|', '-', '+'
|
||||
};
|
||||
|
||||
private static readonly Dictionary<Type, IDictionaryKeyPathProvider> TypeToKeyPathProviders = new Dictionary<Type, IDictionaryKeyPathProvider>();
|
||||
private static readonly Dictionary<string, IDictionaryKeyPathProvider> IDToKeyPathProviders = new Dictionary<string, IDictionaryKeyPathProvider>();
|
||||
private static readonly Dictionary<IDictionaryKeyPathProvider, string> ProviderToID = new Dictionary<IDictionaryKeyPathProvider, string>();
|
||||
|
||||
private static readonly Dictionary<object, string> ObjectsToTempKeys = new Dictionary<object, string>();
|
||||
private static readonly Dictionary<string, object> TempKeysToObjects = new Dictionary<string, object>();
|
||||
private static long tempKeyCounter = 0;
|
||||
|
||||
private class UnityObjectKeyComparer<T> : IComparer<T>
|
||||
{
|
||||
public int Compare(T x, T y)
|
||||
{
|
||||
var a = (UnityEngine.Object)(object)x;
|
||||
var b = (UnityEngine.Object)(object)y;
|
||||
|
||||
if (a == null && b == null) return 0;
|
||||
|
||||
if (a == null) return 1;
|
||||
if (b == null) return -1;
|
||||
|
||||
return a.name.CompareTo(b.name);
|
||||
}
|
||||
}
|
||||
|
||||
private class FallbackKeyComparer<T> : IComparer<T>
|
||||
{
|
||||
public int Compare(T x, T y)
|
||||
{
|
||||
return GetDictionaryKeyString(x).CompareTo(GetDictionaryKeyString(y));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A smart comparer for dictionary keys, that uses the most appropriate available comparison method for the given key types.
|
||||
/// </summary>
|
||||
public class KeyComparer<T> : IComparer<T>
|
||||
{
|
||||
public readonly static KeyComparer<T> Default = new KeyComparer<T>();
|
||||
|
||||
private readonly IComparer<T> actualComparer;
|
||||
|
||||
public KeyComparer()
|
||||
{
|
||||
IDictionaryKeyPathProvider provider;
|
||||
|
||||
if (TypeToKeyPathProviders.TryGetValue(typeof(T), out provider))
|
||||
{
|
||||
this.actualComparer = (IComparer<T>)provider;
|
||||
}
|
||||
else if (typeof(IComparable).IsAssignableFrom(typeof(T)) || typeof(IComparable<T>).IsAssignableFrom(typeof(T)))
|
||||
{
|
||||
this.actualComparer = Comparer<T>.Default;
|
||||
}
|
||||
else if (typeof(UnityEngine.Object).IsAssignableFrom(typeof(T)))
|
||||
{
|
||||
this.actualComparer = new UnityObjectKeyComparer<T>();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.actualComparer = new FallbackKeyComparer<T>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Not yet documented.
|
||||
/// </summary>
|
||||
/// <param name="x">Not yet documented.</param>
|
||||
/// <param name="y">Not yet documented.</param>
|
||||
/// <returns>Not yet documented.</returns>
|
||||
public int Compare(T x, T y)
|
||||
{
|
||||
return this.actualComparer.Compare(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
static DictionaryKeyUtility()
|
||||
{
|
||||
var attributes = AppDomain.CurrentDomain.GetAssemblies()
|
||||
.SelectMany(ass =>
|
||||
{
|
||||
return ass.SafeGetCustomAttributes(typeof(RegisterDictionaryKeyPathProviderAttribute), false)
|
||||
.Select(attr => new { Assembly = ass, Attribute = (RegisterDictionaryKeyPathProviderAttribute)attr });
|
||||
})
|
||||
.Where(n => n.Attribute.ProviderType != null);
|
||||
|
||||
foreach (var entry in attributes)
|
||||
{
|
||||
var assembly = entry.Assembly;
|
||||
var providerType = entry.Attribute.ProviderType;
|
||||
|
||||
if (providerType.IsAbstract)
|
||||
{
|
||||
LogInvalidKeyPathProvider(providerType, assembly, "Type cannot be abstract");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (providerType.IsInterface)
|
||||
{
|
||||
LogInvalidKeyPathProvider(providerType, assembly, "Type cannot be an interface");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!providerType.ImplementsOpenGenericInterface(typeof(IDictionaryKeyPathProvider<>)))
|
||||
{
|
||||
LogInvalidKeyPathProvider(providerType, assembly, "Type must implement the " + typeof(IDictionaryKeyPathProvider<>).GetNiceName() + " interface");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (providerType.IsGenericType)
|
||||
{
|
||||
LogInvalidKeyPathProvider(providerType, assembly, "Type cannot be generic");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (providerType.GetConstructor(Type.EmptyTypes) == null)
|
||||
{
|
||||
LogInvalidKeyPathProvider(providerType, assembly, "Type must have a public parameterless constructor");
|
||||
continue;
|
||||
}
|
||||
|
||||
var keyType = providerType.GetArgumentsOfInheritedOpenGenericInterface(typeof(IDictionaryKeyPathProvider<>))[0];
|
||||
|
||||
if (!keyType.IsValueType)
|
||||
{
|
||||
LogInvalidKeyPathProvider(providerType, assembly, "Key type to support '" + keyType.GetNiceFullName() + "' must be a value type - support for extending dictionaries with reference type keys may come at a later time");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (TypeToKeyPathProviders.ContainsKey(keyType))
|
||||
{
|
||||
Debug.LogWarning("Ignoring dictionary key path provider '" + providerType.GetNiceFullName() + "' registered on assembly '" + assembly.GetName().Name + "': A previous provider '" + TypeToKeyPathProviders[keyType].GetType().GetNiceFullName() + "' was already registered for the key type '" + keyType.GetNiceFullName() + "'.");
|
||||
continue;
|
||||
}
|
||||
|
||||
IDictionaryKeyPathProvider provider;
|
||||
string id;
|
||||
|
||||
try
|
||||
{
|
||||
provider = (IDictionaryKeyPathProvider)Activator.CreateInstance(providerType);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogException(ex);
|
||||
Debug.LogWarning("Ignoring dictionary key path provider '" + providerType.GetNiceFullName() + "' registered on assembly '" + assembly.GetName().Name + "': An exception of type '" + ex.GetType() + "' was thrown when trying to instantiate a provider instance.");
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
id = provider.ProviderID;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogException(ex);
|
||||
Debug.LogWarning("Ignoring dictionary key path provider '" + providerType.GetNiceFullName() + "' registered on assembly '" + assembly.GetName().Name + "': An exception of type '" + ex.GetType() + "' was thrown when trying to get the provider ID string.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (id == null)
|
||||
{
|
||||
LogInvalidKeyPathProvider(providerType, assembly, "Provider ID is null");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (id.Length == 0)
|
||||
{
|
||||
LogInvalidKeyPathProvider(providerType, assembly, "Provider ID is an empty string");
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < id.Length; i++)
|
||||
{
|
||||
if (!char.IsLetterOrDigit(id[i]))
|
||||
{
|
||||
LogInvalidKeyPathProvider(providerType, assembly, "Provider ID '" + id + "' cannot contain characters which are not letters or digits");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (IDToKeyPathProviders.ContainsKey(id))
|
||||
{
|
||||
LogInvalidKeyPathProvider(providerType, assembly, "Provider ID '" + id + "' is already in use for the provider '" + IDToKeyPathProviders[id].GetType().GetNiceFullName() + "'");
|
||||
continue;
|
||||
}
|
||||
|
||||
TypeToKeyPathProviders[keyType] = provider;
|
||||
IDToKeyPathProviders[id] = provider;
|
||||
ProviderToID[provider] = id;
|
||||
}
|
||||
}
|
||||
|
||||
private static void LogInvalidKeyPathProvider(Type type, Assembly assembly, string reason)
|
||||
{
|
||||
Debug.LogError("Invalid dictionary key path provider '" + type.GetNiceFullName() + "' registered on assembly '" + assembly.GetName().Name + "': " + reason);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Not yet documented.
|
||||
/// </summary>
|
||||
public static IEnumerable<Type> GetPersistentPathKeyTypes()
|
||||
{
|
||||
foreach (var type in BaseSupportedDictionaryKeyTypes)
|
||||
{
|
||||
yield return type;
|
||||
}
|
||||
|
||||
foreach (var type in TypeToKeyPathProviders.Keys)
|
||||
{
|
||||
yield return type;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Not yet documented.
|
||||
/// </summary>
|
||||
public static bool KeyTypeSupportsPersistentPaths(Type type)
|
||||
{
|
||||
bool result;
|
||||
if (!GetSupportedDictionaryKeyTypesResults.TryGetValue(type, out result))
|
||||
{
|
||||
result = PrivateIsSupportedDictionaryKeyType(type);
|
||||
GetSupportedDictionaryKeyTypesResults.Add(type, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static bool PrivateIsSupportedDictionaryKeyType(Type type)
|
||||
{
|
||||
return type.IsEnum || BaseSupportedDictionaryKeyTypes.Contains(type) || TypeToKeyPathProviders.ContainsKey(type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Not yet documented.
|
||||
/// </summary>
|
||||
public static string GetDictionaryKeyString(object key)
|
||||
{
|
||||
if (key == null)
|
||||
{
|
||||
throw new ArgumentNullException("key");
|
||||
}
|
||||
|
||||
Type type = key.GetType();
|
||||
|
||||
if (!KeyTypeSupportsPersistentPaths(type))
|
||||
{
|
||||
string keyString;
|
||||
|
||||
if (!ObjectsToTempKeys.TryGetValue(key, out keyString))
|
||||
{
|
||||
keyString = (tempKeyCounter++).ToString();
|
||||
var str = "{temp:" + keyString + "}";
|
||||
ObjectsToTempKeys[key] = str;
|
||||
TempKeysToObjects[str] = key;
|
||||
}
|
||||
|
||||
return keyString;
|
||||
}
|
||||
|
||||
IDictionaryKeyPathProvider keyPathProvider;
|
||||
|
||||
if (TypeToKeyPathProviders.TryGetValue(type, out keyPathProvider))
|
||||
{
|
||||
var keyStr = keyPathProvider.GetPathStringFromKey(key);
|
||||
string error = null;
|
||||
|
||||
bool validPath = true;
|
||||
|
||||
if (keyStr == null || keyStr.Length == 0)
|
||||
{
|
||||
validPath = false;
|
||||
error = "String is null or empty";
|
||||
}
|
||||
|
||||
if (validPath)
|
||||
{
|
||||
for (int i = 0; i < keyStr.Length; i++)
|
||||
{
|
||||
var c = keyStr[i];
|
||||
|
||||
if (char.IsLetterOrDigit(c) || AllowedSpecialKeyStrChars.Contains(c)) continue;
|
||||
|
||||
validPath = false;
|
||||
error = "Invalid character '" + c + "' at index " + i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!validPath)
|
||||
{
|
||||
throw new ArgumentException("Invalid key path '" + keyStr + "' given by provider '" + keyPathProvider.GetType().GetNiceFullName() + "': " + error);
|
||||
}
|
||||
|
||||
return "{id:" + ProviderToID[keyPathProvider] + ":" + keyStr + "}";
|
||||
}
|
||||
|
||||
if (type.IsEnum)
|
||||
{
|
||||
Type backingType = Enum.GetUnderlyingType(type);
|
||||
|
||||
if (backingType == typeof(ulong))
|
||||
{
|
||||
ulong value = Convert.ToUInt64(key);
|
||||
return "{" + value.ToString("D", CultureInfo.InvariantCulture) + "eu}";
|
||||
}
|
||||
else
|
||||
{
|
||||
long value = Convert.ToInt64(key);
|
||||
return "{" + value.ToString("D", CultureInfo.InvariantCulture) + "es}";
|
||||
}
|
||||
}
|
||||
|
||||
if (type == typeof(string)) return "{\"" + key + "\"}";
|
||||
if (type == typeof(char)) return "{'" + ((char)key).ToString(CultureInfo.InvariantCulture) + "'}";
|
||||
if (type == typeof(byte)) return "{" + ((byte)key).ToString("D", CultureInfo.InvariantCulture) + "ub}";
|
||||
if (type == typeof(sbyte)) return "{" + ((sbyte)key).ToString("D", CultureInfo.InvariantCulture) + "sb}";
|
||||
if (type == typeof(ushort)) return "{" + ((ushort)key).ToString("D", CultureInfo.InvariantCulture) + "us}";
|
||||
if (type == typeof(short)) return "{" + ((short)key).ToString("D", CultureInfo.InvariantCulture) + "ss}";
|
||||
if (type == typeof(uint)) return "{" + ((uint)key).ToString("D", CultureInfo.InvariantCulture) + "ui}";
|
||||
if (type == typeof(int)) return "{" + ((int)key).ToString("D", CultureInfo.InvariantCulture) + "si}";
|
||||
if (type == typeof(ulong)) return "{" + ((ulong)key).ToString("D", CultureInfo.InvariantCulture) + "ul}";
|
||||
if (type == typeof(long)) return "{" + ((long)key).ToString("D", CultureInfo.InvariantCulture) + "sl}";
|
||||
if (type == typeof(float)) return "{" + ((float)key).ToString("R", CultureInfo.InvariantCulture) + "fl}";
|
||||
if (type == typeof(double)) return "{" + ((double)key).ToString("R", CultureInfo.InvariantCulture) + "dl}";
|
||||
if (type == typeof(decimal)) return "{" + ((decimal)key).ToString("G", CultureInfo.InvariantCulture) + "dc}";
|
||||
if (type == typeof(Guid)) return "{" + ((Guid)key).ToString("N", CultureInfo.InvariantCulture) + "gu}";
|
||||
|
||||
throw new NotImplementedException("Support has not been implemented for the supported dictionary key type '" + type.GetNiceName() + "'.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Not yet documented.
|
||||
/// </summary>
|
||||
public static object GetDictionaryKeyValue(string keyStr, Type expectedType)
|
||||
{
|
||||
const string InvalidKeyString = "Invalid key string: ";
|
||||
|
||||
if (keyStr == null) throw new ArgumentNullException("keyStr");
|
||||
if (keyStr.Length < 4 || keyStr[0] != '{' || keyStr[keyStr.Length - 1] != '}') throw new ArgumentException(InvalidKeyString + keyStr);
|
||||
|
||||
if (keyStr[1] == '"')
|
||||
{
|
||||
if (keyStr[keyStr.Length - 2] != '"') throw new ArgumentException(InvalidKeyString + keyStr);
|
||||
return keyStr.Substring(2, keyStr.Length - 4);
|
||||
}
|
||||
|
||||
if (keyStr[1] == '\'')
|
||||
{
|
||||
if (keyStr.Length != 5 || keyStr[keyStr.Length - 2] != '\'') throw new ArgumentException(InvalidKeyString + keyStr);
|
||||
return keyStr[2];
|
||||
}
|
||||
|
||||
if (keyStr.StartsWith("{temp:"))
|
||||
{
|
||||
object key;
|
||||
|
||||
if (!TempKeysToObjects.TryGetValue(keyStr, out key))
|
||||
{
|
||||
throw new ArgumentException("The temp dictionary key '" + keyStr + "' has not been allocated yet.");
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
if (keyStr.StartsWith("{id:"))
|
||||
{
|
||||
int secondColon = keyStr.IndexOf(':', 4);
|
||||
|
||||
if (secondColon == -1 || secondColon > keyStr.Length - 3) throw new ArgumentException(InvalidKeyString + keyStr);
|
||||
|
||||
string id = keyStr.FromTo(4, secondColon);
|
||||
string key = keyStr.FromTo(secondColon + 1, keyStr.Length - 1);
|
||||
|
||||
IDictionaryKeyPathProvider provider;
|
||||
|
||||
if (!IDToKeyPathProviders.TryGetValue(id, out provider))
|
||||
{
|
||||
throw new ArgumentException("No provider found for provider ID '" + id + "' in key string '" + keyStr + "'.");
|
||||
}
|
||||
|
||||
return provider.GetKeyFromPathString(key);
|
||||
}
|
||||
|
||||
// Handle enums
|
||||
|
||||
if (keyStr.EndsWith("ub}")) return byte.Parse(keyStr.Substring(1, keyStr.Length - 4), NumberStyles.Any);
|
||||
if (keyStr.EndsWith("sb}")) return sbyte.Parse(keyStr.Substring(1, keyStr.Length - 4), NumberStyles.Any);
|
||||
if (keyStr.EndsWith("us}")) return ushort.Parse(keyStr.Substring(1, keyStr.Length - 4), NumberStyles.Any);
|
||||
if (keyStr.EndsWith("ss}")) return short.Parse(keyStr.Substring(1, keyStr.Length - 4), NumberStyles.Any);
|
||||
if (keyStr.EndsWith("ui}")) return uint.Parse(keyStr.Substring(1, keyStr.Length - 4), NumberStyles.Any);
|
||||
if (keyStr.EndsWith("si}")) return int.Parse(keyStr.Substring(1, keyStr.Length - 4), NumberStyles.Any);
|
||||
if (keyStr.EndsWith("ul}")) return ulong.Parse(keyStr.Substring(1, keyStr.Length - 4), NumberStyles.Any);
|
||||
if (keyStr.EndsWith("sl}")) return long.Parse(keyStr.Substring(1, keyStr.Length - 4), NumberStyles.Any);
|
||||
if (keyStr.EndsWith("fl}")) return float.Parse(keyStr.Substring(1, keyStr.Length - 4), NumberStyles.Any);
|
||||
if (keyStr.EndsWith("dl}")) return double.Parse(keyStr.Substring(1, keyStr.Length - 4), NumberStyles.Any);
|
||||
if (keyStr.EndsWith("dc}")) return decimal.Parse(keyStr.Substring(1, keyStr.Length - 4), NumberStyles.Any);
|
||||
if (keyStr.EndsWith("gu}")) return new Guid(keyStr.Substring(1, keyStr.Length - 4));
|
||||
if (keyStr.EndsWith("es}")) return Enum.ToObject(expectedType, long.Parse(keyStr.Substring(1, keyStr.Length - 4), NumberStyles.Any));
|
||||
if (keyStr.EndsWith("eu}")) return Enum.ToObject(expectedType, ulong.Parse(keyStr.Substring(1, keyStr.Length - 4), NumberStyles.Any));
|
||||
|
||||
throw new ArgumentException(InvalidKeyString + keyStr);
|
||||
}
|
||||
|
||||
private static string FromTo(this string str, int from, int to)
|
||||
{
|
||||
return str.Substring(from, to - from);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ef6f699f176c2dfdea788982526f989a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,75 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="IDictionaryKeyPathProvider.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
/// <summary>
|
||||
/// Not yet documented.
|
||||
/// </summary>
|
||||
public interface IDictionaryKeyPathProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the provider identifier.
|
||||
/// </summary>
|
||||
string ProviderID { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path string from key.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
string GetPathStringFromKey(object key);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the key from path string.
|
||||
/// </summary>
|
||||
/// <param name="pathStr">The path string.</param>
|
||||
object GetKeyFromPathString(string pathStr);
|
||||
|
||||
/// <summary>
|
||||
/// Compares the specified x.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
int Compare(object x, object y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Not yet documented.
|
||||
/// </summary>
|
||||
public interface IDictionaryKeyPathProvider<T> : IDictionaryKeyPathProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the path string from key.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
string GetPathStringFromKey(T key);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the key from path string.
|
||||
/// </summary>
|
||||
/// <param name="pathStr">The path string.</param>
|
||||
new T GetKeyFromPathString(string pathStr);
|
||||
|
||||
/// <summary>
|
||||
/// Compares the specified x.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
int Compare(T x, T y);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b513c156933d8b833ccd40d717bf7e2b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,33 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="RegisterDictionaryKeyPathProviderAttribute.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using System;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
|
||||
public sealed class RegisterDictionaryKeyPathProviderAttribute : Attribute
|
||||
{
|
||||
public readonly Type ProviderType;
|
||||
|
||||
public RegisterDictionaryKeyPathProviderAttribute(Type providerType)
|
||||
{
|
||||
this.ProviderType = providerType;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 54f653ed4a4e15c07057283c11dce4d9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,76 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="Vector2DictionaryKeyPathProvider.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
using VRC.Udon.Serialization.OdinSerializer;
|
||||
|
||||
[assembly: RegisterDictionaryKeyPathProvider(typeof(Vector2DictionaryKeyPathProvider))]
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using System.Globalization;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Not yet documented.
|
||||
/// </summary>
|
||||
public sealed class Vector2DictionaryKeyPathProvider : BaseDictionaryKeyPathProvider<Vector2>
|
||||
{
|
||||
/// <summary>
|
||||
/// Not yet documented.
|
||||
/// </summary>
|
||||
public override string ProviderID { get { return "v2"; } }
|
||||
|
||||
/// <summary>
|
||||
/// Not yet documented.
|
||||
/// </summary>
|
||||
public override int Compare(Vector2 x, Vector2 y)
|
||||
{
|
||||
int result = x.x.CompareTo(y.x);
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
result = x.y.CompareTo(y.y);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Not yet documented.
|
||||
/// </summary>
|
||||
public override Vector2 GetKeyFromPathString(string pathStr)
|
||||
{
|
||||
int sep = pathStr.IndexOf('|');
|
||||
|
||||
string x = pathStr.Substring(1, sep - 1).Trim();
|
||||
string y = pathStr.Substring(sep + 1, pathStr.Length - (sep + 2)).Trim();
|
||||
|
||||
return new Vector2(float.Parse(x), float.Parse(y));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Not yet documented.
|
||||
/// </summary>
|
||||
public override string GetPathStringFromKey(Vector2 key)
|
||||
{
|
||||
var x = key.x.ToString("R", CultureInfo.InvariantCulture);
|
||||
var y = key.y.ToString("R", CultureInfo.InvariantCulture);
|
||||
return ("(" + x + "|" + y + ")").Replace('.', ',');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0405ef103432161dff609e75f71f3f55
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,72 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="Vector3DictionaryKeyPathProvider.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
using VRC.Udon.Serialization.OdinSerializer;
|
||||
|
||||
[assembly: RegisterDictionaryKeyPathProvider(typeof(Vector3DictionaryKeyPathProvider))]
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using System.Globalization;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Dictionary key path provider for <see cref="UnityEngine.Vector3"/>
|
||||
/// </summary>
|
||||
public sealed class Vector3DictionaryKeyPathProvider : BaseDictionaryKeyPathProvider<Vector3>
|
||||
{
|
||||
public override string ProviderID { get { return "v3"; } }
|
||||
|
||||
public override int Compare(Vector3 x, Vector3 y)
|
||||
{
|
||||
int result = x.x.CompareTo(y.x);
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
result = x.y.CompareTo(y.y);
|
||||
}
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
result = x.z.CompareTo(y.z);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public override Vector3 GetKeyFromPathString(string pathStr)
|
||||
{
|
||||
int sep1 = pathStr.IndexOf('|');
|
||||
int sep2 = pathStr.IndexOf('|', sep1 + 1);
|
||||
|
||||
string x = pathStr.Substring(1, sep1 - 1).Trim();
|
||||
string y = pathStr.Substring(sep1 + 1, sep2 - (sep1 + 1)).Trim();
|
||||
string z = pathStr.Substring(sep2 + 1, pathStr.Length - (sep2 + 2)).Trim();
|
||||
|
||||
return new Vector3(float.Parse(x), float.Parse(y), float.Parse(z));
|
||||
}
|
||||
|
||||
public override string GetPathStringFromKey(Vector3 key)
|
||||
{
|
||||
var x = key.x.ToString("R", CultureInfo.InvariantCulture);
|
||||
var y = key.y.ToString("R", CultureInfo.InvariantCulture);
|
||||
var z = key.z.ToString("R", CultureInfo.InvariantCulture);
|
||||
return ("(" + x + "|" + y + "|" + z + ")").Replace('.', ',');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1d61e235c606c1c9d7269f7e68471e38
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,78 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="Vector4DictionaryKeyPathProvider.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
using VRC.Udon.Serialization.OdinSerializer;
|
||||
|
||||
[assembly: RegisterDictionaryKeyPathProvider(typeof(Vector4DictionaryKeyPathProvider))]
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using System.Globalization;
|
||||
using UnityEngine;
|
||||
|
||||
public sealed class Vector4DictionaryKeyPathProvider : BaseDictionaryKeyPathProvider<Vector4>
|
||||
{
|
||||
public override string ProviderID { get { return "v4"; } }
|
||||
|
||||
public override int Compare(Vector4 x, Vector4 y)
|
||||
{
|
||||
int result = x.x.CompareTo(y.x);
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
result = x.y.CompareTo(y.y);
|
||||
}
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
result = x.z.CompareTo(y.z);
|
||||
}
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
result = x.w.CompareTo(y.w);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public override Vector4 GetKeyFromPathString(string pathStr)
|
||||
{
|
||||
int sep1 = pathStr.IndexOf('|');
|
||||
int sep2 = pathStr.IndexOf('|', sep1 + 1);
|
||||
int sep3 = pathStr.IndexOf('|', sep2 + 1);
|
||||
|
||||
string x = pathStr.Substring(1, sep1 - 1).Trim();
|
||||
string y = pathStr.Substring(sep1 + 1, sep2 - (sep1 + 1)).Trim();
|
||||
string z = pathStr.Substring(sep2 + 1, sep3 - (sep2 + 1)).Trim();
|
||||
string w = pathStr.Substring(sep3 + 1, pathStr.Length - (sep3 + 2)).Trim();
|
||||
|
||||
return new Vector4(float.Parse(x), float.Parse(y), float.Parse(z), float.Parse(w));
|
||||
}
|
||||
|
||||
public override string GetPathStringFromKey(Vector4 key)
|
||||
{
|
||||
var x = key.x.ToString("R", CultureInfo.InvariantCulture);
|
||||
var y = key.y.ToString("R", CultureInfo.InvariantCulture);
|
||||
var z = key.z.ToString("R", CultureInfo.InvariantCulture);
|
||||
var w = key.w.ToString("R", CultureInfo.InvariantCulture);
|
||||
|
||||
return ("(" + x + "|" + y + "|" + z + "|" + w + ")").Replace('.', ',');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 51bb2cf369b5ea90948a20e4f2ebae48
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a7dcf20a0423fd046ad1bd854676dc1c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,73 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="AnimationCurveFormatter.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
using VRC.Udon.Serialization.OdinSerializer;
|
||||
|
||||
[assembly: RegisterFormatter(typeof(AnimationCurveFormatter))]
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Custom formatter for the <see cref="AnimationCurve"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="MinimalBaseFormatter{UnityEngine.AnimationCurve}" />
|
||||
public class AnimationCurveFormatter : MinimalBaseFormatter<AnimationCurve>
|
||||
{
|
||||
private static readonly Serializer<Keyframe[]> KeyframeSerializer = Serializer.Get<Keyframe[]>();
|
||||
private static readonly Serializer<WrapMode> WrapModeSerializer = Serializer.Get<WrapMode>();
|
||||
|
||||
/// <summary>
|
||||
/// Returns null.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A null value.
|
||||
/// </returns>
|
||||
protected override AnimationCurve GetUninitializedObject()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads into the specified value using the specified reader.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to read into.</param>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
protected override void Read(ref AnimationCurve value, IDataReader reader)
|
||||
{
|
||||
var keys = KeyframeSerializer.ReadValue(reader);
|
||||
|
||||
value = new AnimationCurve(keys);
|
||||
value.preWrapMode = WrapModeSerializer.ReadValue(reader);
|
||||
value.postWrapMode = WrapModeSerializer.ReadValue(reader);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes from the specified value using the specified writer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write from.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
protected override void Write(ref AnimationCurve value, IDataWriter writer)
|
||||
{
|
||||
KeyframeSerializer.WriteValue(value.keys, writer);
|
||||
WrapModeSerializer.WriteValue(value.preWrapMode, writer);
|
||||
WrapModeSerializer.WriteValue(value.postWrapMode, writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d2976bd61cccf62b11b4d3f02762465
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,57 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="BoundsFormatter.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
using VRC.Udon.Serialization.OdinSerializer;
|
||||
|
||||
[assembly: RegisterFormatter(typeof(BoundsFormatter))]
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Custom formatter for the <see cref="Bounds"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="MinimalBaseFormatter{UnityEngine.Bounds}" />
|
||||
public class BoundsFormatter : MinimalBaseFormatter<Bounds>
|
||||
{
|
||||
private static readonly Serializer<Vector3> Vector3Serializer = Serializer.Get<Vector3>();
|
||||
|
||||
/// <summary>
|
||||
/// Reads into the specified value using the specified reader.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to read into.</param>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
protected override void Read(ref Bounds value, IDataReader reader)
|
||||
{
|
||||
value.center = Vector3Serializer.ReadValue(reader);
|
||||
value.size = Vector3Serializer.ReadValue(reader);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes from the specified value using the specified writer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write from.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
protected override void Write(ref Bounds value, IDataWriter writer)
|
||||
{
|
||||
Vector3Serializer.WriteValue(value.center, writer);
|
||||
Vector3Serializer.WriteValue(value.size, writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6ff1b29d64402a15d020739becd8661e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,61 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="Color32Formatter.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
using VRC.Udon.Serialization.OdinSerializer;
|
||||
|
||||
[assembly: RegisterFormatter(typeof(Color32Formatter))]
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Custom formatter for the <see cref="Color32"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="MinimalBaseFormatter{UnityEngine.Color32}" />
|
||||
public class Color32Formatter : MinimalBaseFormatter<Color32>
|
||||
{
|
||||
private static readonly Serializer<byte> ByteSerializer = Serializer.Get<byte>();
|
||||
|
||||
/// <summary>
|
||||
/// Reads into the specified value using the specified reader.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to read into.</param>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
protected override void Read(ref Color32 value, IDataReader reader)
|
||||
{
|
||||
value.r = Color32Formatter.ByteSerializer.ReadValue(reader);
|
||||
value.g = Color32Formatter.ByteSerializer.ReadValue(reader);
|
||||
value.b = Color32Formatter.ByteSerializer.ReadValue(reader);
|
||||
value.a = Color32Formatter.ByteSerializer.ReadValue(reader);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes from the specified value using the specified writer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write from.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
protected override void Write(ref Color32 value, IDataWriter writer)
|
||||
{
|
||||
Color32Formatter.ByteSerializer.WriteValue(value.r, writer);
|
||||
Color32Formatter.ByteSerializer.WriteValue(value.g, writer);
|
||||
Color32Formatter.ByteSerializer.WriteValue(value.b, writer);
|
||||
Color32Formatter.ByteSerializer.WriteValue(value.a, writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0878ec68b6ab3c9ebc365b6d139e4840
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,161 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="ColorBlockFormatter.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
using VRC.Udon.Serialization.OdinSerializer;
|
||||
|
||||
[assembly: RegisterFormatterLocator(typeof(ColorBlockFormatterLocator))]
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
public class ColorBlockFormatterLocator : IFormatterLocator
|
||||
{
|
||||
#if false
|
||||
public bool TryGetFormatter(Type type, FormatterLocationStep step, ISerializationPolicy policy, bool allowWeakFallbackFormatters, out IFormatter formatter)
|
||||
#else
|
||||
public bool TryGetFormatter(Type type, FormatterLocationStep step, ISerializationPolicy policy, out IFormatter formatter)
|
||||
#endif
|
||||
{
|
||||
if (step == FormatterLocationStep.BeforeRegisteredFormatters && type.FullName == "UnityEngine.UI.ColorBlock")
|
||||
{
|
||||
#if false
|
||||
try
|
||||
{
|
||||
formatter = (IFormatter)Activator.CreateInstance(typeof(ColorBlockFormatter<>).MakeGenericType(type));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
if (allowWeakFallbackFormatters && (ex is ExecutionEngineException || ex.GetBaseException() is ExecutionEngineException))
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
{
|
||||
formatter = new WeakColorBlockFormatter(type);
|
||||
}
|
||||
else throw;
|
||||
}
|
||||
#else
|
||||
formatter = (IFormatter)Activator.CreateInstance(typeof(ColorBlockFormatter<>).MakeGenericType(type));
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
formatter = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Custom formatter for the <see cref="ColorBlock"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="MinimalBaseFormatter{UnityEngine.UI.ColorBlock}" />
|
||||
public class ColorBlockFormatter<T> : MinimalBaseFormatter<T>
|
||||
{
|
||||
private static readonly Serializer<float> FloatSerializer = Serializer.Get<float>();
|
||||
private static readonly Serializer<Color> ColorSerializer = Serializer.Get<Color>();
|
||||
|
||||
private static readonly PropertyInfo normalColor = typeof(T).GetProperty("normalColor");
|
||||
private static readonly PropertyInfo highlightedColor = typeof(T).GetProperty("highlightedColor");
|
||||
private static readonly PropertyInfo pressedColor = typeof(T).GetProperty("pressedColor");
|
||||
private static readonly PropertyInfo disabledColor = typeof(T).GetProperty("disabledColor");
|
||||
private static readonly PropertyInfo colorMultiplier = typeof(T).GetProperty("colorMultiplier");
|
||||
private static readonly PropertyInfo fadeDuration = typeof(T).GetProperty("fadeDuration");
|
||||
|
||||
/// <summary>
|
||||
/// Reads into the specified value using the specified reader.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to read into.</param>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
protected override void Read(ref T value, IDataReader reader)
|
||||
{
|
||||
object boxed = value;
|
||||
|
||||
normalColor.SetValue(boxed, ColorSerializer.ReadValue(reader), null);
|
||||
highlightedColor.SetValue(boxed, ColorSerializer.ReadValue(reader), null);
|
||||
pressedColor.SetValue(boxed, ColorSerializer.ReadValue(reader), null);
|
||||
disabledColor.SetValue(boxed, ColorSerializer.ReadValue(reader), null);
|
||||
colorMultiplier.SetValue(boxed, FloatSerializer.ReadValue(reader), null);
|
||||
fadeDuration.SetValue(boxed, FloatSerializer.ReadValue(reader), null);
|
||||
|
||||
value = (T)boxed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes from the specified value using the specified writer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write from.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
protected override void Write(ref T value, IDataWriter writer)
|
||||
{
|
||||
ColorSerializer.WriteValue((Color)normalColor.GetValue(value, null), writer);
|
||||
ColorSerializer.WriteValue((Color)highlightedColor.GetValue(value, null), writer);
|
||||
ColorSerializer.WriteValue((Color)pressedColor.GetValue(value, null), writer);
|
||||
ColorSerializer.WriteValue((Color)disabledColor.GetValue(value, null), writer);
|
||||
FloatSerializer.WriteValue((float)colorMultiplier.GetValue(value, null), writer);
|
||||
FloatSerializer.WriteValue((float)fadeDuration.GetValue(value, null), writer);
|
||||
}
|
||||
}
|
||||
|
||||
#if false
|
||||
public class WeakColorBlockFormatter : WeakBaseFormatter
|
||||
{
|
||||
private static readonly Serializer<float> FloatSerializer = Serializer.Get<float>();
|
||||
private static readonly Serializer<Color> ColorSerializer = Serializer.Get<Color>();
|
||||
|
||||
private readonly PropertyInfo normalColor;
|
||||
private readonly PropertyInfo highlightedColor;
|
||||
private readonly PropertyInfo pressedColor;
|
||||
private readonly PropertyInfo disabledColor;
|
||||
private readonly PropertyInfo colorMultiplier;
|
||||
private readonly PropertyInfo fadeDuration;
|
||||
|
||||
public WeakColorBlockFormatter(Type colorBlockType)
|
||||
: base(colorBlockType)
|
||||
{
|
||||
normalColor = colorBlockType.GetProperty("normalColor");
|
||||
highlightedColor = colorBlockType.GetProperty("highlightedColor");
|
||||
pressedColor = colorBlockType.GetProperty("pressedColor");
|
||||
disabledColor = colorBlockType.GetProperty("disabledColor");
|
||||
colorMultiplier = colorBlockType.GetProperty("colorMultiplier");
|
||||
fadeDuration = colorBlockType.GetProperty("fadeDuration");
|
||||
}
|
||||
|
||||
protected override void DeserializeImplementation(ref object value, IDataReader reader)
|
||||
{
|
||||
normalColor.SetValue(value, ColorSerializer.ReadValue(reader), null);
|
||||
highlightedColor.SetValue(value, ColorSerializer.ReadValue(reader), null);
|
||||
pressedColor.SetValue(value, ColorSerializer.ReadValue(reader), null);
|
||||
disabledColor.SetValue(value, ColorSerializer.ReadValue(reader), null);
|
||||
colorMultiplier.SetValue(value, FloatSerializer.ReadValue(reader), null);
|
||||
fadeDuration.SetValue(value, FloatSerializer.ReadValue(reader), null);
|
||||
}
|
||||
|
||||
protected override void SerializeImplementation(ref object value, IDataWriter writer)
|
||||
{
|
||||
ColorSerializer.WriteValue((Color)normalColor.GetValue(value, null), writer);
|
||||
ColorSerializer.WriteValue((Color)highlightedColor.GetValue(value, null), writer);
|
||||
ColorSerializer.WriteValue((Color)pressedColor.GetValue(value, null), writer);
|
||||
ColorSerializer.WriteValue((Color)disabledColor.GetValue(value, null), writer);
|
||||
FloatSerializer.WriteValue((float)colorMultiplier.GetValue(value, null), writer);
|
||||
FloatSerializer.WriteValue((float)fadeDuration.GetValue(value, null), writer);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 25e35581ce6d1febd9ac41864a76ecdb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,61 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="ColorFormatter.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
using VRC.Udon.Serialization.OdinSerializer;
|
||||
|
||||
[assembly: RegisterFormatter(typeof(ColorFormatter))]
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Custom formatter for the <see cref="Color"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="MinimalBaseFormatter{UnityEngine.Color}" />
|
||||
public class ColorFormatter : MinimalBaseFormatter<Color>
|
||||
{
|
||||
private static readonly Serializer<float> FloatSerializer = Serializer.Get<float>();
|
||||
|
||||
/// <summary>
|
||||
/// Reads into the specified value using the specified reader.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to read into.</param>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
protected override void Read(ref Color value, IDataReader reader)
|
||||
{
|
||||
value.r = ColorFormatter.FloatSerializer.ReadValue(reader);
|
||||
value.g = ColorFormatter.FloatSerializer.ReadValue(reader);
|
||||
value.b = ColorFormatter.FloatSerializer.ReadValue(reader);
|
||||
value.a = ColorFormatter.FloatSerializer.ReadValue(reader);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes from the specified value using the specified writer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write from.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
protected override void Write(ref Color value, IDataWriter writer)
|
||||
{
|
||||
ColorFormatter.FloatSerializer.WriteValue(value.r, writer);
|
||||
ColorFormatter.FloatSerializer.WriteValue(value.g, writer);
|
||||
ColorFormatter.FloatSerializer.WriteValue(value.b, writer);
|
||||
ColorFormatter.FloatSerializer.WriteValue(value.a, writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 484768ba343a6a05522c29d81a4ce61d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,81 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="CoroutineFormatter.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
using VRC.Udon.Serialization.OdinSerializer;
|
||||
|
||||
[assembly: RegisterFormatter(typeof(CoroutineFormatter))]
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// <para>
|
||||
/// Custom formatter for the <see cref="Coroutine"/> type.
|
||||
/// This serializes nothing and always deserializes null,
|
||||
/// and only exists to ensure that no coroutine instances
|
||||
/// are ever created by the serialization system, since they
|
||||
/// will in almost all cases be invalid instances.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Invalid coroutine instances crash Unity instantly when
|
||||
/// they are garbage collected.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public sealed class CoroutineFormatter : IFormatter<Coroutine>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the type that the formatter can serialize.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The type that the formatter can serialize.
|
||||
/// </value>
|
||||
public Type SerializedType { get { return typeof(Coroutine); } }
|
||||
|
||||
/// <summary>
|
||||
/// Returns null.
|
||||
/// </summary>
|
||||
object IFormatter.Deserialize(IDataReader reader)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns null.
|
||||
/// </summary>
|
||||
public Coroutine Deserialize(IDataReader reader)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does nothing.
|
||||
/// </summary>
|
||||
public void Serialize(object value, IDataWriter writer)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does nothing.
|
||||
/// </summary>
|
||||
public void Serialize(Coroutine value, IDataWriter writer)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c3968bef792c5668478ac01be7645b30
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,57 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="GradientAlphaKeyFormatter.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
using VRC.Udon.Serialization.OdinSerializer;
|
||||
|
||||
[assembly: RegisterFormatter(typeof(GradientAlphaKeyFormatter))]
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Custom formatter for the <see cref="GradientAlphaKey"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="MinimalBaseFormatter{UnityEngine.GradientAlphaKey}" />
|
||||
public class GradientAlphaKeyFormatter : MinimalBaseFormatter<GradientAlphaKey>
|
||||
{
|
||||
private static readonly Serializer<float> FloatSerializer = Serializer.Get<float>();
|
||||
|
||||
/// <summary>
|
||||
/// Reads into the specified value using the specified reader.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to read into.</param>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
protected override void Read(ref GradientAlphaKey value, IDataReader reader)
|
||||
{
|
||||
value.alpha = GradientAlphaKeyFormatter.FloatSerializer.ReadValue(reader);
|
||||
value.time = GradientAlphaKeyFormatter.FloatSerializer.ReadValue(reader);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes from the specified value using the specified writer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write from.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
protected override void Write(ref GradientAlphaKey value, IDataWriter writer)
|
||||
{
|
||||
GradientAlphaKeyFormatter.FloatSerializer.WriteValue(value.alpha, writer);
|
||||
GradientAlphaKeyFormatter.FloatSerializer.WriteValue(value.time, writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b5b415c00da8157ac50b8f5543f0b1d9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,58 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="GradientColorKeyFormatter.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
using VRC.Udon.Serialization.OdinSerializer;
|
||||
|
||||
[assembly: RegisterFormatter(typeof(GradientColorKeyFormatter))]
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Custom formatter for the <see cref="GradientColorKey"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="MinimalBaseFormatter{UnityEngine.GradientColorKey}" />
|
||||
public class GradientColorKeyFormatter : MinimalBaseFormatter<GradientColorKey>
|
||||
{
|
||||
private static readonly Serializer<Color> ColorSerializer = Serializer.Get<Color>();
|
||||
private static readonly Serializer<float> FloatSerializer = Serializer.Get<float>();
|
||||
|
||||
/// <summary>
|
||||
/// Reads into the specified value using the specified reader.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to read into.</param>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
protected override void Read(ref GradientColorKey value, IDataReader reader)
|
||||
{
|
||||
value.color = GradientColorKeyFormatter.ColorSerializer.ReadValue(reader);
|
||||
value.time = GradientColorKeyFormatter.FloatSerializer.ReadValue(reader);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes from the specified value using the specified writer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write from.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
protected override void Write(ref GradientColorKey value, IDataWriter writer)
|
||||
{
|
||||
GradientColorKeyFormatter.ColorSerializer.WriteValue(value.color, writer);
|
||||
GradientColorKeyFormatter.FloatSerializer.WriteValue(value.time, writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8936a3e43078251682f18923139f7aee
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,106 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="GradientFormatter.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
using VRC.Udon.Serialization.OdinSerializer;
|
||||
|
||||
[assembly: RegisterFormatter(typeof(GradientFormatter))]
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Custom formatter for the <see cref="Gradient"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="MinimalBaseFormatter{UnityEngine.Gradient}" />
|
||||
public class GradientFormatter : MinimalBaseFormatter<Gradient>
|
||||
{
|
||||
private static readonly Serializer<GradientAlphaKey[]> AlphaKeysSerializer = Serializer.Get<GradientAlphaKey[]>();
|
||||
private static readonly Serializer<GradientColorKey[]> ColorKeysSerializer = Serializer.Get<GradientColorKey[]>();
|
||||
|
||||
// The Gradient.mode member of type UnityEngine.GradientMode was added in a later version of Unity
|
||||
// Therefore we need to handle it using reflection, as it might not be there if Odin is running in an early version
|
||||
|
||||
private static readonly PropertyInfo ModeProperty = typeof(Gradient).GetProperty("mode", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
private static readonly Serializer<object> EnumSerializer = ModeProperty != null ? Serializer.Get<object>() : null;
|
||||
|
||||
protected override Gradient GetUninitializedObject()
|
||||
{
|
||||
return new Gradient();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads into the specified value using the specified reader.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to read into.</param>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
protected override void Read(ref Gradient value, IDataReader reader)
|
||||
{
|
||||
value.alphaKeys = GradientFormatter.AlphaKeysSerializer.ReadValue(reader);
|
||||
value.colorKeys = GradientFormatter.ColorKeysSerializer.ReadValue(reader);
|
||||
|
||||
string name;
|
||||
reader.PeekEntry(out name);
|
||||
|
||||
if (name == "mode")
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ModeProperty != null)
|
||||
{
|
||||
ModeProperty.SetValue(value, EnumSerializer.ReadValue(reader), null);
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.SkipEntry();
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
reader.Context.Config.DebugContext.LogWarning("Failed to read Gradient.mode, due to Unity's API disallowing setting of this member on other threads than the main thread. Gradient.mode value will have been lost.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes from the specified value using the specified writer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write from.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
protected override void Write(ref Gradient value, IDataWriter writer)
|
||||
{
|
||||
GradientFormatter.AlphaKeysSerializer.WriteValue(value.alphaKeys, writer);
|
||||
GradientFormatter.ColorKeysSerializer.WriteValue(value.colorKeys, writer);
|
||||
|
||||
if (ModeProperty != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
EnumSerializer.WriteValue("mode", ModeProperty.GetValue(value, null), writer);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
writer.Context.Config.DebugContext.LogWarning("Failed to write Gradient.mode, due to Unity's API disallowing setting of this member on other threads than the main thread. Gradient.mode will have been lost upon deserialization.");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d5b54660d5342fd45e2e43775538879d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,121 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="KeyframeFormatter.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
using VRC.Udon.Serialization.OdinSerializer;
|
||||
|
||||
[assembly: RegisterFormatter(typeof(KeyframeFormatter))]
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using VRC.Udon.Serialization.OdinSerializer.Utilities;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Custom formatter for the <see cref="Keyframe"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="MinimalBaseFormatter{UnityEngine.Keyframe}" />
|
||||
public class KeyframeFormatter : MinimalBaseFormatter<Keyframe>
|
||||
{
|
||||
private static readonly Serializer<float> FloatSerializer = Serializer.Get<float>();
|
||||
private static readonly Serializer<int> IntSerializer = Serializer.Get<int>();
|
||||
|
||||
private static readonly bool Is_In_2018_1_Or_Above;
|
||||
private static IFormatter<Keyframe> Formatter;
|
||||
|
||||
static KeyframeFormatter()
|
||||
{
|
||||
Is_In_2018_1_Or_Above = typeof(Keyframe).GetProperty("weightedMode") != null;
|
||||
|
||||
if (Is_In_2018_1_Or_Above)
|
||||
{
|
||||
if (EmitUtilities.CanEmit)
|
||||
{
|
||||
Formatter = (IFormatter<Keyframe>)FormatterEmitter.GetEmittedFormatter(typeof(Keyframe), SerializationPolicies.Everything);
|
||||
}
|
||||
else
|
||||
{
|
||||
Formatter = new ReflectionFormatter<Keyframe>(SerializationPolicies.Everything);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads into the specified value using the specified reader.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to read into.</param>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
protected override void Read(ref Keyframe value, IDataReader reader)
|
||||
{
|
||||
string name;
|
||||
EntryType first = reader.PeekEntry(out name);
|
||||
|
||||
if (first == EntryType.Integer && name == "ver")
|
||||
{
|
||||
if (Formatter == null)
|
||||
{
|
||||
// We're deserializing 2018.1+ data in a lower version of Unity - so just give it a go
|
||||
Formatter = new ReflectionFormatter<Keyframe>(SerializationPolicies.Everything);
|
||||
}
|
||||
|
||||
int version;
|
||||
reader.ReadInt32(out version);
|
||||
|
||||
// Only one version so far, so ignore it for now
|
||||
value = Formatter.Deserialize(reader);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Legacy Keyframe deserialization code
|
||||
value.inTangent = KeyframeFormatter.FloatSerializer.ReadValue(reader);
|
||||
value.outTangent = KeyframeFormatter.FloatSerializer.ReadValue(reader);
|
||||
value.time = KeyframeFormatter.FloatSerializer.ReadValue(reader);
|
||||
value.value = KeyframeFormatter.FloatSerializer.ReadValue(reader);
|
||||
|
||||
#pragma warning disable 0618
|
||||
value.tangentMode = KeyframeFormatter.IntSerializer.ReadValue(reader);
|
||||
#pragma warning restore 0618
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes from the specified value using the specified writer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write from.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
protected override void Write(ref Keyframe value, IDataWriter writer)
|
||||
{
|
||||
if (Is_In_2018_1_Or_Above)
|
||||
{
|
||||
writer.WriteInt32("ver", 1);
|
||||
Formatter.Serialize(value, writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Legacy Keyframe serialization code
|
||||
KeyframeFormatter.FloatSerializer.WriteValue(value.inTangent, writer);
|
||||
KeyframeFormatter.FloatSerializer.WriteValue(value.outTangent, writer);
|
||||
KeyframeFormatter.FloatSerializer.WriteValue(value.time, writer);
|
||||
KeyframeFormatter.FloatSerializer.WriteValue(value.value, writer);
|
||||
|
||||
#pragma warning disable 0618
|
||||
KeyframeFormatter.IntSerializer.WriteValue(value.tangentMode, writer);
|
||||
#pragma warning restore 0618
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 68ac0b27f571616d3ed26c23eef40c8c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,55 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="LayerMaskFormatter.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
using VRC.Udon.Serialization.OdinSerializer;
|
||||
|
||||
[assembly: RegisterFormatter(typeof(LayerMaskFormatter))]
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Custom formatter for the <see cref="LayerMask"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="MinimalBaseFormatter{UnityEngine.LayerMask}" />
|
||||
public class LayerMaskFormatter : MinimalBaseFormatter<LayerMask>
|
||||
{
|
||||
private static readonly Serializer<int> IntSerializer = Serializer.Get<int>();
|
||||
|
||||
/// <summary>
|
||||
/// Reads into the specified value using the specified reader.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to read into.</param>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
protected override void Read(ref LayerMask value, IDataReader reader)
|
||||
{
|
||||
value.value = LayerMaskFormatter.IntSerializer.ReadValue(reader);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes from the specified value using the specified writer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write from.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
protected override void Write(ref LayerMask value, IDataWriter writer)
|
||||
{
|
||||
LayerMaskFormatter.IntSerializer.WriteValue(value.value, writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: afc596cd95a1ac316024d16f6fec6536
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,61 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="QuaternionFormatter.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
using VRC.Udon.Serialization.OdinSerializer;
|
||||
|
||||
[assembly: RegisterFormatter(typeof(QuaternionFormatter))]
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Custom formatter for the <see cref="Quaternion"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="MinimalBaseFormatter{UnityEngine.Quaternion}" />
|
||||
public class QuaternionFormatter : MinimalBaseFormatter<Quaternion>
|
||||
{
|
||||
private static readonly Serializer<float> FloatSerializer = Serializer.Get<float>();
|
||||
|
||||
/// <summary>
|
||||
/// Reads into the specified value using the specified reader.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to read into.</param>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
protected override void Read(ref Quaternion value, IDataReader reader)
|
||||
{
|
||||
value.x = QuaternionFormatter.FloatSerializer.ReadValue(reader);
|
||||
value.y = QuaternionFormatter.FloatSerializer.ReadValue(reader);
|
||||
value.z = QuaternionFormatter.FloatSerializer.ReadValue(reader);
|
||||
value.w = QuaternionFormatter.FloatSerializer.ReadValue(reader);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes from the specified value using the specified writer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write from.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
protected override void Write(ref Quaternion value, IDataWriter writer)
|
||||
{
|
||||
QuaternionFormatter.FloatSerializer.WriteValue(value.x, writer);
|
||||
QuaternionFormatter.FloatSerializer.WriteValue(value.y, writer);
|
||||
QuaternionFormatter.FloatSerializer.WriteValue(value.z, writer);
|
||||
QuaternionFormatter.FloatSerializer.WriteValue(value.w, writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 558323987bf9b75943382a5faa093ee3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,61 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="RectFormatter.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
using VRC.Udon.Serialization.OdinSerializer;
|
||||
|
||||
[assembly: RegisterFormatter(typeof(RectFormatter))]
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Custom formatter for the <see cref="Rect"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="MinimalBaseFormatter{UnityEngine.Rect}" />
|
||||
public class RectFormatter : MinimalBaseFormatter<Rect>
|
||||
{
|
||||
private static readonly Serializer<float> FloatSerializer = Serializer.Get<float>();
|
||||
|
||||
/// <summary>
|
||||
/// Reads into the specified value using the specified reader.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to read into.</param>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
protected override void Read(ref Rect value, IDataReader reader)
|
||||
{
|
||||
value.x = RectFormatter.FloatSerializer.ReadValue(reader);
|
||||
value.y = RectFormatter.FloatSerializer.ReadValue(reader);
|
||||
value.width = RectFormatter.FloatSerializer.ReadValue(reader);
|
||||
value.height = RectFormatter.FloatSerializer.ReadValue(reader);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes from the specified value using the specified writer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write from.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
protected override void Write(ref Rect value, IDataWriter writer)
|
||||
{
|
||||
RectFormatter.FloatSerializer.WriteValue(value.x, writer);
|
||||
RectFormatter.FloatSerializer.WriteValue(value.y, writer);
|
||||
RectFormatter.FloatSerializer.WriteValue(value.width, writer);
|
||||
RectFormatter.FloatSerializer.WriteValue(value.height, writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 196809b991e565a48e3d4ad08cb30b5e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,61 @@
|
||||
//VRC TCL: Disabled for security
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="UnityEventFormatter.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>
|
||||
//-----------------------------------------------------------------------
|
||||
#if false
|
||||
using VRC.Udon.Serialization.OdinSerializer;
|
||||
|
||||
[assembly: RegisterFormatter(typeof(UnityEventFormatter<>), weakFallback: typeof(WeakUnityEventFormatter))]
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using System;
|
||||
using UnityEngine.Events;
|
||||
|
||||
/// <summary>
|
||||
/// Custom generic formatter for the <see cref="UnityEvent{T0}"/>, <see cref="UnityEvent{T0, T1}"/>, <see cref="UnityEvent{T0, T1, T2}"/> and <see cref="UnityEvent{T0, T1, T2, T3}"/> types.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of UnityEvent that this formatter can serialize and deserialize.</typeparam>
|
||||
/// <seealso cref="ReflectionFormatter{UnityEngine.Events.UnityEvent}" />
|
||||
public class UnityEventFormatter<T> : ReflectionFormatter<T> where T : UnityEventBase, new()
|
||||
{
|
||||
/// <summary>
|
||||
/// Get an uninitialized object of type <see cref="T" />.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An uninitialized object of type <see cref="T" />.
|
||||
/// </returns>
|
||||
protected override T GetUninitializedObject()
|
||||
{
|
||||
return new T();
|
||||
}
|
||||
}
|
||||
|
||||
public class WeakUnityEventFormatter : WeakReflectionFormatter
|
||||
{
|
||||
public WeakUnityEventFormatter(Type serializedType) : base(serializedType)
|
||||
{
|
||||
}
|
||||
|
||||
protected override object GetUninitializedObject()
|
||||
{
|
||||
return Activator.CreateInstance(this.SerializedType);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c934302874ac3315ed322feefefa1f9c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,57 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="Vector2Formatter.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
using VRC.Udon.Serialization.OdinSerializer;
|
||||
|
||||
[assembly: RegisterFormatter(typeof(Vector2Formatter))]
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Custom formatter for the <see cref="Vector2"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="MinimalBaseFormatter{UnityEngine.Vector2}" />
|
||||
public class Vector2Formatter : MinimalBaseFormatter<Vector2>
|
||||
{
|
||||
private static readonly Serializer<float> FloatSerializer = Serializer.Get<float>();
|
||||
|
||||
/// <summary>
|
||||
/// Reads into the specified value using the specified reader.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to read into.</param>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
protected override void Read(ref Vector2 value, IDataReader reader)
|
||||
{
|
||||
value.x = Vector2Formatter.FloatSerializer.ReadValue(reader);
|
||||
value.y = Vector2Formatter.FloatSerializer.ReadValue(reader);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes from the specified value using the specified writer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write from.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
protected override void Write(ref Vector2 value, IDataWriter writer)
|
||||
{
|
||||
Vector2Formatter.FloatSerializer.WriteValue(value.x, writer);
|
||||
Vector2Formatter.FloatSerializer.WriteValue(value.y, writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 70c675a7b4c71c685ee39d745ccb058b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,59 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="Vector3Formatter.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
using VRC.Udon.Serialization.OdinSerializer;
|
||||
|
||||
[assembly: RegisterFormatter(typeof(Vector3Formatter))]
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Custom formatter for the <see cref="Vector3"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="MinimalBaseFormatter{UnityEngine.Vector3}" />
|
||||
public class Vector3Formatter : MinimalBaseFormatter<Vector3>
|
||||
{
|
||||
private static readonly Serializer<float> FloatSerializer = Serializer.Get<float>();
|
||||
|
||||
/// <summary>
|
||||
/// Reads into the specified value using the specified reader.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to read into.</param>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
protected override void Read(ref Vector3 value, IDataReader reader)
|
||||
{
|
||||
value.x = Vector3Formatter.FloatSerializer.ReadValue(reader);
|
||||
value.y = Vector3Formatter.FloatSerializer.ReadValue(reader);
|
||||
value.z = Vector3Formatter.FloatSerializer.ReadValue(reader);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes from the specified value using the specified writer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write from.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
protected override void Write(ref Vector3 value, IDataWriter writer)
|
||||
{
|
||||
Vector3Formatter.FloatSerializer.WriteValue(value.x, writer);
|
||||
Vector3Formatter.FloatSerializer.WriteValue(value.y, writer);
|
||||
Vector3Formatter.FloatSerializer.WriteValue(value.z, writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: da2644647af1368176103aa87de1dbaf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,61 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="Vector4Formatter.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
using VRC.Udon.Serialization.OdinSerializer;
|
||||
|
||||
[assembly: RegisterFormatter(typeof(Vector4Formatter))]
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Custom formatter for the <see cref="Vector4"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="MinimalBaseFormatter{UnityEngine.Vector4}" />
|
||||
public class Vector4Formatter : MinimalBaseFormatter<Vector4>
|
||||
{
|
||||
private static readonly Serializer<float> FloatSerializer = Serializer.Get<float>();
|
||||
|
||||
/// <summary>
|
||||
/// Reads into the specified value using the specified reader.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to read into.</param>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
protected override void Read(ref Vector4 value, IDataReader reader)
|
||||
{
|
||||
value.x = Vector4Formatter.FloatSerializer.ReadValue(reader);
|
||||
value.y = Vector4Formatter.FloatSerializer.ReadValue(reader);
|
||||
value.z = Vector4Formatter.FloatSerializer.ReadValue(reader);
|
||||
value.w = Vector4Formatter.FloatSerializer.ReadValue(reader);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes from the specified value using the specified writer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write from.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
protected override void Write(ref Vector4 value, IDataWriter writer)
|
||||
{
|
||||
Vector4Formatter.FloatSerializer.WriteValue(value.x, writer);
|
||||
Vector4Formatter.FloatSerializer.WriteValue(value.y, writer);
|
||||
Vector4Formatter.FloatSerializer.WriteValue(value.z, writer);
|
||||
Vector4Formatter.FloatSerializer.WriteValue(value.w, writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 60afa8ede3981c383782a01ddc55e943
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,91 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="Vector4Formatter.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
using VRC.Udon.Serialization.OdinSerializer;
|
||||
|
||||
[assembly: RegisterFormatter(typeof(Vector2IntFormatter))]
|
||||
[assembly: RegisterFormatter(typeof(Vector3IntFormatter))]
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Custom formatter for the <see cref="Vector2Int"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="Sirenix.Serialization.MinimalBaseFormatter{UnityEngine.Vector2Int}" />
|
||||
public class Vector2IntFormatter : MinimalBaseFormatter<Vector2Int>
|
||||
{
|
||||
private static readonly Serializer<int> Serializer = OdinSerializer.Serializer.Get<int>();
|
||||
|
||||
/// <summary>
|
||||
/// Reads into the specified value using the specified reader.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to read into.</param>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
protected override void Read(ref Vector2Int value, IDataReader reader)
|
||||
{
|
||||
value.x = Vector2IntFormatter.Serializer.ReadValue(reader);
|
||||
value.y = Vector2IntFormatter.Serializer.ReadValue(reader);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes from the specified value using the specified writer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write from.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
protected override void Write(ref Vector2Int value, IDataWriter writer)
|
||||
{
|
||||
Vector2IntFormatter.Serializer.WriteValue(value.x, writer);
|
||||
Vector2IntFormatter.Serializer.WriteValue(value.y, writer);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Custom formatter for the <see cref="Vector3Int"/> type.
|
||||
/// </summary>
|
||||
/// <seealso cref="Sirenix.Serialization.MinimalBaseFormatter{UnityEngine.Vector3Int}" />
|
||||
public class Vector3IntFormatter : MinimalBaseFormatter<Vector3Int>
|
||||
{
|
||||
private static readonly Serializer<int> Serializer = OdinSerializer.Serializer.Get<int>();
|
||||
|
||||
/// <summary>
|
||||
/// Reads into the specified value using the specified reader.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to read into.</param>
|
||||
/// <param name="reader">The reader to use.</param>
|
||||
protected override void Read(ref Vector3Int value, IDataReader reader)
|
||||
{
|
||||
value.x = Vector3IntFormatter.Serializer.ReadValue(reader);
|
||||
value.y = Vector3IntFormatter.Serializer.ReadValue(reader);
|
||||
value.z = Vector3IntFormatter.Serializer.ReadValue(reader);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes from the specified value using the specified writer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to write from.</param>
|
||||
/// <param name="writer">The writer to use.</param>
|
||||
protected override void Write(ref Vector3Int value, IDataWriter writer)
|
||||
{
|
||||
Vector3IntFormatter.Serializer.WriteValue(value.x, writer);
|
||||
Vector3IntFormatter.Serializer.WriteValue(value.y, writer);
|
||||
Vector3IntFormatter.Serializer.WriteValue(value.z, writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 93c15c193841b7f45871c38815e37589
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,156 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <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);
|
||||
private static MethodInfo PrefabUtility_ApplyPropertyOverride_Method;
|
||||
|
||||
static OdinPrefabSerializationEditorUtility()
|
||||
{
|
||||
Type interactionModeEnum = typeof(UnityEditor.Editor).Assembly.GetType("UnityEditor.InteractionMode");
|
||||
|
||||
if (interactionModeEnum != null)
|
||||
{
|
||||
PrefabUtility_ApplyPropertyOverride_Method = typeof(PrefabUtility).GetMethod("ApplyPropertyOverride", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(SerializedProperty), typeof(string), interactionModeEnum }, null);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool HasNewPrefabWorkflow
|
||||
{
|
||||
get
|
||||
{
|
||||
if (hasNewPrefabWorkflow == null)
|
||||
{
|
||||
hasNewPrefabWorkflow = DetectNewPrefabWorkflow();
|
||||
}
|
||||
|
||||
return hasNewPrefabWorkflow.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool HasApplyPropertyOverride
|
||||
{
|
||||
get
|
||||
{
|
||||
return PrefabUtility_ApplyPropertyOverride_Method != null;
|
||||
}
|
||||
}
|
||||
|
||||
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 void ApplyPropertyOverride(SerializedProperty instanceProperty, string assetPath)
|
||||
{
|
||||
//PrefabUtility.ApplyPropertyOverride(instanceProperty, assetPath, InteractionMode.AutomatedAction);
|
||||
if (!HasApplyPropertyOverride) throw new NotSupportedException("PrefabUtility.ApplyPropertyOverride doesn't exist in this version of Unity");
|
||||
PrefabUtility_ApplyPropertyOverride_Method.Invoke(null, new object[] { instanceProperty, assetPath, 0 });
|
||||
}
|
||||
|
||||
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
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aaf2f90207414827b53b85dae0eae82e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e281f95be0fe014489e2c46801dce8cc
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,30 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="IOverridesSerializationFormat.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>
|
||||
//-----------------------------------------------------------------------
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that an Odin-serialized Unity object controls its own serialization format. Every time it is serialized, it will be asked which format to use.
|
||||
/// </summary>
|
||||
public interface IOverridesSerializationFormat
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the format to use for serialization.
|
||||
/// </summary>
|
||||
DataFormat GetFormatToSerializeAs(bool isPlayer);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ff1ca109149d83b03b39644f8045275e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,31 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="IOverridesSerializationPolicy.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that an Odin-serialized Unity object provides its own serialization policy rather than using the default policy.
|
||||
/// <para/>
|
||||
/// Note that THE VALUES RETURNED BY THIS INTERFACE WILL OVERRIDE THE PARAMETERS PASSED TO <see cref="UnitySerializationUtility.SerializeUnityObject(UnityEngine.Object, ref SerializationData, bool, SerializationContext)"/> and <see cref="UnitySerializationUtility.DeserializeUnityObject(UnityEngine.Object, ref SerializationData, DeserializationContext)"/>.
|
||||
/// </summary>
|
||||
public interface IOverridesSerializationPolicy
|
||||
{
|
||||
ISerializationPolicy SerializationPolicy { get; }
|
||||
bool OdinSerializesUnityFields { get; }
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8942002e9ac41c2bfd27c4fbedf93f09
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,30 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="ISupportsPrefabSerialization.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>
|
||||
//-----------------------------------------------------------------------
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that an Odin-serialized Unity object supports prefab serialization.
|
||||
/// </summary>
|
||||
public interface ISupportsPrefabSerialization
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the serialization data of the object.
|
||||
/// </summary>
|
||||
SerializationData SerializationData { get; set; }
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7279ec8ad7837f13ec833193ab4282cc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,176 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="SerializationData.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>
|
||||
//-----------------------------------------------------------------------
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Utilities;
|
||||
|
||||
/// <summary>
|
||||
/// Unity serialized data struct that contains all data needed by Odin serialization.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public struct SerializationData
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the <see cref="PrefabModificationsReferencedUnityObjects"/> field.
|
||||
/// </summary>
|
||||
public const string PrefabModificationsReferencedUnityObjectsFieldName = "PrefabModificationsReferencedUnityObjects";
|
||||
|
||||
/// <summary>
|
||||
/// The name of the <see cref="PrefabModifications"/> field.
|
||||
/// </summary>
|
||||
public const string PrefabModificationsFieldName = "PrefabModifications";
|
||||
|
||||
/// <summary>
|
||||
/// The name of the <see cref="Prefab"/> field.
|
||||
/// </summary>
|
||||
public const string PrefabFieldName = "Prefab";
|
||||
|
||||
/// <summary>
|
||||
/// The data format used by the serializer. This field will be automatically set to the format specified in the global serialization config
|
||||
/// when the Unity object gets serialized, unless the Unity object implements the <see cref="IOverridesSerializationFormat"/> interface.
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
public DataFormat SerializedFormat;
|
||||
|
||||
/// <summary>
|
||||
/// The serialized data when serializing with the Binray format.
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
public byte[] SerializedBytes;
|
||||
|
||||
/// <summary>
|
||||
/// All serialized Unity references.
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
public List<UnityEngine.Object> ReferencedUnityObjects;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the object contains any serialized data.
|
||||
/// </summary>
|
||||
[Obsolete("Use ContainsData instead")]
|
||||
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
public bool HasEditorData
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (this.SerializedFormat)
|
||||
{
|
||||
case DataFormat.Binary:
|
||||
case DataFormat.JSON:
|
||||
return !(this.SerializedBytesString.IsNullOrWhitespace() && (this.SerializedBytes == null || this.SerializedBytes.Length == 0));
|
||||
|
||||
case DataFormat.Nodes:
|
||||
return !(this.SerializationNodes == null || this.SerializationNodes.Count == 0);
|
||||
|
||||
default:
|
||||
throw new NotImplementedException(this.SerializedFormat.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the struct contains any data.
|
||||
/// If this is false, then it could mean that Unity has not yet deserialized the struct.
|
||||
/// </summary>
|
||||
public bool ContainsData
|
||||
{
|
||||
get
|
||||
{
|
||||
return
|
||||
// this.SerializedBytesString != null && // Unity serialized strings remains null when an object is created until it's deserialized.
|
||||
this.SerializedBytes != null &&
|
||||
this.SerializationNodes != null &&
|
||||
this.PrefabModifications != null &&
|
||||
this.ReferencedUnityObjects != null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The serialized data when serializing with the JSON format.
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
public string SerializedBytesString;
|
||||
|
||||
/// <summary>
|
||||
/// The reference to the prefab this is only populated in prefab scene instances.
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
public UnityEngine.Object Prefab;
|
||||
|
||||
/// <summary>
|
||||
/// All serialized Unity references.
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
public List<UnityEngine.Object> PrefabModificationsReferencedUnityObjects;
|
||||
|
||||
/// <summary>
|
||||
/// All Odin serialized prefab modifications.
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
public List<string> PrefabModifications;
|
||||
|
||||
/// <summary>
|
||||
/// The serialized data when serializing with the Nodes format.
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
public List<SerializationNode> SerializationNodes;
|
||||
|
||||
/// <summary>
|
||||
/// Resets all data.
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
this.SerializedFormat = DataFormat.Binary;
|
||||
|
||||
if (this.SerializedBytes != null && this.SerializedBytes.Length > 0)
|
||||
{
|
||||
this.SerializedBytes = new byte[0];
|
||||
}
|
||||
|
||||
if (this.ReferencedUnityObjects != null && this.ReferencedUnityObjects.Count > 0)
|
||||
{
|
||||
this.ReferencedUnityObjects.Clear();
|
||||
}
|
||||
|
||||
this.Prefab = null;
|
||||
|
||||
if (this.SerializationNodes != null && this.SerializationNodes.Count > 0)
|
||||
{
|
||||
this.SerializationNodes.Clear();
|
||||
}
|
||||
|
||||
if (this.SerializedBytesString != null && this.SerializedBytesString.Length > 0)
|
||||
{
|
||||
this.SerializedBytesString = string.Empty;
|
||||
}
|
||||
|
||||
if (this.PrefabModificationsReferencedUnityObjects != null && this.PrefabModificationsReferencedUnityObjects.Count > 0)
|
||||
{
|
||||
this.PrefabModificationsReferencedUnityObjects.Clear();
|
||||
}
|
||||
|
||||
if (this.PrefabModifications != null && this.PrefabModifications.Count > 0)
|
||||
{
|
||||
this.PrefabModifications.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ea095023abd05a7af0da4166dcefdee8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,62 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="SerializedBehaviour.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>
|
||||
//-----------------------------------------------------------------------
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// A Unity Behaviour which is serialized by the Sirenix serialization system.
|
||||
/// </summary>
|
||||
#if ODIN_INSPECTOR
|
||||
[Sirenix.OdinInspector.ShowOdinSerializedPropertiesInInspector]
|
||||
#endif
|
||||
|
||||
public abstract class SerializedBehaviour : Behaviour, ISerializationCallbackReceiver, ISupportsPrefabSerialization
|
||||
{
|
||||
[SerializeField, HideInInspector]
|
||||
private SerializationData serializationData;
|
||||
|
||||
SerializationData ISupportsPrefabSerialization.SerializationData { get { return this.serializationData; } set { this.serializationData = value; } }
|
||||
|
||||
void ISerializationCallbackReceiver.OnAfterDeserialize()
|
||||
{
|
||||
UnitySerializationUtility.DeserializeUnityObject(this, ref this.serializationData);
|
||||
this.OnAfterDeserialize();
|
||||
}
|
||||
|
||||
void ISerializationCallbackReceiver.OnBeforeSerialize()
|
||||
{
|
||||
this.OnBeforeSerialize();
|
||||
UnitySerializationUtility.SerializeUnityObject(this, ref this.serializationData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked after deserialization has taken place.
|
||||
/// </summary>
|
||||
protected virtual void OnAfterDeserialize()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked before serialization has taken place.
|
||||
/// </summary>
|
||||
protected virtual void OnBeforeSerialize()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c3cecb461cebbc940ede3b5ddb72382e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,62 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="SerializedComponent.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>
|
||||
//-----------------------------------------------------------------------
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// A Unity Component which is serialized by the Sirenix serialization system.
|
||||
/// </summary>
|
||||
#if ODIN_INSPECTOR
|
||||
[Sirenix.OdinInspector.ShowOdinSerializedPropertiesInInspector]
|
||||
#endif
|
||||
|
||||
public abstract class SerializedComponent : Component, ISerializationCallbackReceiver, ISupportsPrefabSerialization
|
||||
{
|
||||
[SerializeField, HideInInspector]
|
||||
private SerializationData serializationData;
|
||||
|
||||
SerializationData ISupportsPrefabSerialization.SerializationData { get { return this.serializationData; } set { this.serializationData = value; } }
|
||||
|
||||
void ISerializationCallbackReceiver.OnAfterDeserialize()
|
||||
{
|
||||
UnitySerializationUtility.DeserializeUnityObject(this, ref this.serializationData);
|
||||
this.OnAfterDeserialize();
|
||||
}
|
||||
|
||||
void ISerializationCallbackReceiver.OnBeforeSerialize()
|
||||
{
|
||||
this.OnBeforeSerialize();
|
||||
UnitySerializationUtility.SerializeUnityObject(this, ref this.serializationData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked after deserialization has taken place.
|
||||
/// </summary>
|
||||
protected virtual void OnAfterDeserialize()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked before serialization has taken place.
|
||||
/// </summary>
|
||||
protected virtual void OnBeforeSerialize()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 56b88cfe9935184fe250bda018144f26
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,63 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="SerializedMonoBehaviour.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// A Unity MonoBehaviour which is serialized by the Sirenix serialization system.
|
||||
/// </summary>
|
||||
#if ODIN_INSPECTOR
|
||||
[Sirenix.OdinInspector.ShowOdinSerializedPropertiesInInspector]
|
||||
#endif
|
||||
|
||||
public abstract class SerializedMonoBehaviour : MonoBehaviour, ISerializationCallbackReceiver, ISupportsPrefabSerialization
|
||||
{
|
||||
[SerializeField, HideInInspector]
|
||||
private SerializationData serializationData;
|
||||
|
||||
SerializationData ISupportsPrefabSerialization.SerializationData { get { return this.serializationData; } set { this.serializationData = value; } }
|
||||
|
||||
void ISerializationCallbackReceiver.OnAfterDeserialize()
|
||||
{
|
||||
UnitySerializationUtility.DeserializeUnityObject(this, ref this.serializationData);
|
||||
this.OnAfterDeserialize();
|
||||
}
|
||||
|
||||
void ISerializationCallbackReceiver.OnBeforeSerialize()
|
||||
{
|
||||
this.OnBeforeSerialize();
|
||||
UnitySerializationUtility.SerializeUnityObject(this, ref this.serializationData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked after deserialization has taken place.
|
||||
/// </summary>
|
||||
protected virtual void OnAfterDeserialize()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked before serialization has taken place.
|
||||
/// </summary>
|
||||
protected virtual void OnBeforeSerialize()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d1b9fa6342beb9fdfc2c4bc1d8e5e971
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,60 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="SerializedScriptableObject.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>
|
||||
//-----------------------------------------------------------------------
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// A Unity ScriptableObject which is serialized by the Sirenix serialization system.
|
||||
/// </summary>
|
||||
#if ODIN_INSPECTOR
|
||||
[Sirenix.OdinInspector.ShowOdinSerializedPropertiesInInspector]
|
||||
#endif
|
||||
|
||||
public abstract class SerializedScriptableObject : ScriptableObject, ISerializationCallbackReceiver
|
||||
{
|
||||
[SerializeField, HideInInspector]
|
||||
private SerializationData serializationData;
|
||||
|
||||
void ISerializationCallbackReceiver.OnAfterDeserialize()
|
||||
{
|
||||
UnitySerializationUtility.DeserializeUnityObject(this, ref this.serializationData);
|
||||
this.OnAfterDeserialize();
|
||||
}
|
||||
|
||||
void ISerializationCallbackReceiver.OnBeforeSerialize()
|
||||
{
|
||||
this.OnBeforeSerialize();
|
||||
UnitySerializationUtility.SerializeUnityObject(this, ref this.serializationData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked after deserialization has taken place.
|
||||
/// </summary>
|
||||
protected virtual void OnAfterDeserialize()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked before serialization has taken place.
|
||||
/// </summary>
|
||||
protected virtual void OnBeforeSerialize()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6cb9325ffffee5d6ed94d71590b4049a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,60 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="SerializedStateMachineBehaviour.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>
|
||||
//-----------------------------------------------------------------------
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// A Unity StateMachineBehaviour which is serialized by the Sirenix serialization system.
|
||||
/// </summary>
|
||||
#if ODIN_INSPECTOR
|
||||
[Sirenix.OdinInspector.ShowOdinSerializedPropertiesInInspector]
|
||||
#endif
|
||||
|
||||
public abstract class SerializedStateMachineBehaviour : StateMachineBehaviour, ISerializationCallbackReceiver
|
||||
{
|
||||
[SerializeField, HideInInspector]
|
||||
private SerializationData serializationData;
|
||||
|
||||
void ISerializationCallbackReceiver.OnAfterDeserialize()
|
||||
{
|
||||
UnitySerializationUtility.DeserializeUnityObject(this, ref this.serializationData);
|
||||
this.OnAfterDeserialize();
|
||||
}
|
||||
|
||||
void ISerializationCallbackReceiver.OnBeforeSerialize()
|
||||
{
|
||||
this.OnBeforeSerialize();
|
||||
UnitySerializationUtility.SerializeUnityObject(this, ref this.serializationData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked after deserialization has taken place.
|
||||
/// </summary>
|
||||
protected virtual void OnAfterDeserialize()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked before serialization has taken place.
|
||||
/// </summary>
|
||||
protected virtual void OnBeforeSerialize()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eefcd68a84ee7903b08c6254c17fafe3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,60 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="SerializedUnityObject.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>
|
||||
//-----------------------------------------------------------------------
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// A Unity ScriptableObject which is serialized by the Sirenix serialization system.
|
||||
/// </summary>
|
||||
#if ODIN_INSPECTOR
|
||||
[Sirenix.OdinInspector.ShowOdinSerializedPropertiesInInspector]
|
||||
#endif
|
||||
|
||||
public abstract class SerializedUnityObject : UnityEngine.Object, ISerializationCallbackReceiver
|
||||
{
|
||||
[SerializeField, HideInInspector]
|
||||
private SerializationData serializationData;
|
||||
|
||||
void ISerializationCallbackReceiver.OnAfterDeserialize()
|
||||
{
|
||||
UnitySerializationUtility.DeserializeUnityObject(this, ref this.serializationData);
|
||||
this.OnAfterDeserialize();
|
||||
}
|
||||
|
||||
void ISerializationCallbackReceiver.OnBeforeSerialize()
|
||||
{
|
||||
this.OnBeforeSerialize();
|
||||
UnitySerializationUtility.SerializeUnityObject(this, ref this.serializationData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked after deserialization has taken place.
|
||||
/// </summary>
|
||||
protected virtual void OnAfterDeserialize()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked before serialization has taken place.
|
||||
/// </summary>
|
||||
protected virtual void OnBeforeSerialize()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d62f7ab4e5aa075b819d6c71e929686b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,160 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="UnityReferenceResolver.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using Utilities;
|
||||
|
||||
/// <summary>
|
||||
/// Resolves external index references to Unity objects.
|
||||
/// </summary>
|
||||
/// <seealso cref="IExternalIndexReferenceResolver" />
|
||||
/// <seealso cref="ICacheNotificationReceiver" />
|
||||
public sealed class UnityReferenceResolver : IExternalIndexReferenceResolver, ICacheNotificationReceiver
|
||||
{
|
||||
private Dictionary<UnityEngine.Object, int> referenceIndexMapping = new Dictionary<UnityEngine.Object, int>(32, ReferenceEqualityComparer<UnityEngine.Object>.Default);
|
||||
private List<UnityEngine.Object> referencedUnityObjects;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UnityReferenceResolver"/> class.
|
||||
/// </summary>
|
||||
public UnityReferenceResolver()
|
||||
{
|
||||
this.referencedUnityObjects = new List<UnityEngine.Object>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UnityReferenceResolver"/> class with a list of Unity objects.
|
||||
/// </summary>
|
||||
/// <param name="referencedUnityObjects">The referenced Unity objects.</param>
|
||||
public UnityReferenceResolver(List<UnityEngine.Object> referencedUnityObjects)
|
||||
{
|
||||
this.SetReferencedUnityObjects(referencedUnityObjects);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the currently referenced Unity objects.
|
||||
/// </summary>
|
||||
/// <returns>A list of the currently referenced Unity objects.</returns>
|
||||
public List<UnityEngine.Object> GetReferencedUnityObjects()
|
||||
{
|
||||
return this.referencedUnityObjects;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the referenced Unity objects of the resolver to a given list, or a new list if the value is null.
|
||||
/// </summary>
|
||||
/// <param name="referencedUnityObjects">The referenced Unity objects to set, or null if a new list is required.</param>
|
||||
public void SetReferencedUnityObjects(List<UnityEngine.Object> referencedUnityObjects)
|
||||
{
|
||||
if (referencedUnityObjects == null)
|
||||
{
|
||||
referencedUnityObjects = new List<UnityEngine.Object>();
|
||||
}
|
||||
|
||||
this.referencedUnityObjects = referencedUnityObjects;
|
||||
this.referenceIndexMapping.Clear();
|
||||
|
||||
for (int i = 0; i < this.referencedUnityObjects.Count; i++)
|
||||
{
|
||||
if (object.ReferenceEquals(this.referencedUnityObjects[i], null) == false)
|
||||
{
|
||||
if (!this.referenceIndexMapping.ContainsKey(this.referencedUnityObjects[i]))
|
||||
{
|
||||
this.referenceIndexMapping.Add(this.referencedUnityObjects[i], i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified value can be referenced externally via this resolver.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to reference.</param>
|
||||
/// <param name="index">The index of the resolved value, if it can be referenced.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the reference can be resolved, otherwise <c>false</c>.
|
||||
/// </returns>
|
||||
public bool CanReference(object value, out int index)
|
||||
{
|
||||
if (this.referencedUnityObjects == null)
|
||||
{
|
||||
this.referencedUnityObjects = new List<UnityEngine.Object>(32);
|
||||
}
|
||||
|
||||
var obj = value as UnityEngine.Object;
|
||||
|
||||
if (object.ReferenceEquals(null, obj) == false)
|
||||
{
|
||||
if (this.referenceIndexMapping.TryGetValue(obj, out index) == false)
|
||||
{
|
||||
index = this.referencedUnityObjects.Count;
|
||||
this.referenceIndexMapping.Add(obj, index);
|
||||
this.referencedUnityObjects.Add(obj);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
index = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to resolve the given reference index to a reference value.
|
||||
/// </summary>
|
||||
/// <param name="index">The index to resolve.</param>
|
||||
/// <param name="value">The resolved value.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the index could be resolved to a value, otherwise <c>false</c>.
|
||||
/// </returns>
|
||||
public bool TryResolveReference(int index, out object value)
|
||||
{
|
||||
if (this.referencedUnityObjects == null || index < 0 || index >= this.referencedUnityObjects.Count)
|
||||
{
|
||||
// Sometimes something has destroyed the list of references in between serialization and deserialization
|
||||
// (Unity prefab instances are especially bad at preserving such data), and in these cases we still don't
|
||||
// want the system to fall back to a formatter, so we give out a null value.
|
||||
value = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
value = this.referencedUnityObjects[index];
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets this instance.
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
this.referencedUnityObjects = null;
|
||||
this.referenceIndexMapping.Clear();
|
||||
}
|
||||
|
||||
void ICacheNotificationReceiver.OnFreed()
|
||||
{
|
||||
this.Reset();
|
||||
}
|
||||
|
||||
void ICacheNotificationReceiver.OnClaimed()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de5584f66ccc5e072681a310c5987b8c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,100 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="UnitySerializationInitializer.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>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace VRC.Udon.Serialization.OdinSerializer
|
||||
{
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Utility class which initializes the Sirenix serialization system to be compatible with Unity.
|
||||
/// </summary>
|
||||
public static class UnitySerializationInitializer
|
||||
{
|
||||
private static readonly object LOCK = new object();
|
||||
private static bool initialized = false;
|
||||
|
||||
public static bool Initialized { get { return initialized; } }
|
||||
|
||||
public static RuntimePlatform CurrentPlatform { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the Sirenix serialization system to be compatible with Unity.
|
||||
/// </summary>
|
||||
public static void Initialize()
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
lock (LOCK)
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Ensure that the config instance is loaded before deserialization of anything occurs.
|
||||
// If we try to load it during deserialization, Unity will throw exceptions, as a lot of
|
||||
// the Unity API is disallowed during serialization and deserialization.
|
||||
GlobalSerializationConfig.LoadInstanceIfAssetExists();
|
||||
|
||||
CurrentPlatform = Application.platform;
|
||||
|
||||
if (Application.isEditor) return;
|
||||
|
||||
ArchitectureInfo.SetRuntimePlatform(CurrentPlatform);
|
||||
|
||||
//if (CurrentPlatform == RuntimePlatform.Android)
|
||||
//{
|
||||
// //using (var system = new AndroidJavaClass("java.lang.System"))
|
||||
// //{
|
||||
// // string architecture = system.CallStatic<string>("getProperty", "os.arch");
|
||||
// // ArchitectureInfo.SetIsOnAndroid(architecture);
|
||||
// //}
|
||||
//}
|
||||
//else if (CurrentPlatform == RuntimePlatform.IPhonePlayer)
|
||||
//{
|
||||
// ArchitectureInfo.SetIsOnIPhone();
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// ArchitectureInfo.SetIsNotOnMobile();
|
||||
//}
|
||||
}
|
||||
finally
|
||||
{
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
||||
private static void InitializeRuntime()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
||||
[UnityEditor.InitializeOnLoadMethod]
|
||||
private static void InitializeEditor()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f670c1f9aa9ab0c5988e81802c005767
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9eb15f2339819bb651c7872d73c89776
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user