整合SLSUtilities
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace LunaWolfStudiosEditor.ScriptableSheets.Tables
|
||||
{
|
||||
public struct AssetPathTableProperty : ITableProperty
|
||||
{
|
||||
private static readonly string s_PropertyName = $"k_{nameof(AssetPathTableProperty)}";
|
||||
|
||||
private readonly Object m_RootObject;
|
||||
public Object RootObject => m_RootObject;
|
||||
|
||||
private readonly string m_PropertyPath;
|
||||
public string PropertyPath => m_PropertyPath;
|
||||
|
||||
private readonly string m_ControlName;
|
||||
public string ControlName => m_ControlName;
|
||||
|
||||
private readonly string m_AssetPath;
|
||||
public string AssetPath => m_AssetPath;
|
||||
|
||||
public AssetPathTableProperty(Object rootObject, string assetPath, string controlName)
|
||||
{
|
||||
m_RootObject = rootObject;
|
||||
m_PropertyPath = s_PropertyName;
|
||||
m_ControlName = controlName;
|
||||
m_AssetPath = assetPath;
|
||||
}
|
||||
|
||||
public void AddNewLine()
|
||||
{
|
||||
Debug.LogWarning($"Cannot add new lines to {nameof(ITableProperty)} {nameof(AssetPathTableProperty)}!");
|
||||
return;
|
||||
}
|
||||
|
||||
public string GetProperty()
|
||||
{
|
||||
return m_AssetPath;
|
||||
}
|
||||
|
||||
public string GetProperty(FlatFileFormatSettings formatSettings)
|
||||
{
|
||||
return GetProperty();
|
||||
}
|
||||
|
||||
public void SetProperty(string value, FlatFileFormatSettings formatSettings)
|
||||
{
|
||||
// Cannot change asset path property.
|
||||
return;
|
||||
}
|
||||
|
||||
public bool IsInputFieldProperty(bool isScriptableObject)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool IsUnityLocalizationProperty()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool NeedsSelectionBorder(bool lockNames = false)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 10ea46e845c01494c95773f54ba31114
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 284559
|
||||
packageName: Scriptable Sheets
|
||||
packageVersion: 1.8.0
|
||||
assetPath: Packages/com.lunawolfstudios.scriptablesheets/Editor/Modules/Tables/TableProperties/AssetPathTableProperty.cs
|
||||
uploadId: 823456
|
||||
@@ -0,0 +1,67 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace LunaWolfStudiosEditor.ScriptableSheets.Tables
|
||||
{
|
||||
public struct GuidTableProperty : ITableProperty
|
||||
{
|
||||
private static readonly string s_PropertyName = $"k_{nameof(GuidTableProperty)}";
|
||||
|
||||
private readonly Object m_RootObject;
|
||||
public Object RootObject => m_RootObject;
|
||||
|
||||
private readonly string m_PropertyPath;
|
||||
public string PropertyPath => m_PropertyPath;
|
||||
|
||||
private readonly string m_ControlName;
|
||||
public string ControlName => m_ControlName;
|
||||
|
||||
private readonly string m_Guid;
|
||||
public string Guid => m_Guid;
|
||||
|
||||
public GuidTableProperty(Object rootObject, string assetPath, string controlName)
|
||||
{
|
||||
m_RootObject = rootObject;
|
||||
m_PropertyPath = s_PropertyName;
|
||||
m_ControlName = controlName;
|
||||
m_Guid = AssetDatabase.AssetPathToGUID(assetPath);
|
||||
}
|
||||
|
||||
public void AddNewLine()
|
||||
{
|
||||
Debug.LogWarning($"Cannot add new lines to {nameof(ITableProperty)} {nameof(GuidTableProperty)}!");
|
||||
return;
|
||||
}
|
||||
|
||||
public string GetProperty()
|
||||
{
|
||||
return m_Guid;
|
||||
}
|
||||
|
||||
public string GetProperty(FlatFileFormatSettings formatSettings)
|
||||
{
|
||||
return GetProperty();
|
||||
}
|
||||
|
||||
public void SetProperty(string value, FlatFileFormatSettings formatSettings)
|
||||
{
|
||||
// Cannot change guid property.
|
||||
return;
|
||||
}
|
||||
|
||||
public bool IsInputFieldProperty(bool isScriptableObject)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool IsUnityLocalizationProperty()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool NeedsSelectionBorder(bool lockNames = false)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec9b40505f6825f49b485d1440a448d4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 284559
|
||||
packageName: Scriptable Sheets
|
||||
packageVersion: 1.8.0
|
||||
assetPath: Packages/com.lunawolfstudios.scriptablesheets/Editor/Modules/Tables/TableProperties/GuidTableProperty.cs
|
||||
uploadId: 823456
|
||||
@@ -0,0 +1,23 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace LunaWolfStudiosEditor.ScriptableSheets.Tables
|
||||
{
|
||||
public interface ITableProperty
|
||||
{
|
||||
Object RootObject { get; }
|
||||
string PropertyPath { get; }
|
||||
string ControlName { get; }
|
||||
|
||||
void AddNewLine();
|
||||
|
||||
string GetProperty(FlatFileFormatSettings settings);
|
||||
|
||||
void SetProperty(string value, FlatFileFormatSettings formatSettings);
|
||||
|
||||
bool IsInputFieldProperty(bool isScriptableObject);
|
||||
|
||||
bool IsUnityLocalizationProperty();
|
||||
|
||||
bool NeedsSelectionBorder(bool lockNames = false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a33571dd12ba01342b48d2b9d36c991e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 284559
|
||||
packageName: Scriptable Sheets
|
||||
packageVersion: 1.8.0
|
||||
assetPath: Packages/com.lunawolfstudios.scriptablesheets/Editor/Modules/Tables/TableProperties/ITableProperty.cs
|
||||
uploadId: 823456
|
||||
@@ -0,0 +1,622 @@
|
||||
using LunaWolfStudiosEditor.ScriptableSheets.Serializables;
|
||||
using LunaWolfStudiosEditor.ScriptableSheets.Shared;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace LunaWolfStudiosEditor.ScriptableSheets.Tables
|
||||
{
|
||||
public struct SerializedTableProperty : ITableProperty
|
||||
{
|
||||
public const string NullObjectValue = "null";
|
||||
private const char AssetDelimiter = '&';
|
||||
// Sub Asset names can contain special chars, so use a unique string.
|
||||
private const string SubAssetDelimiter = "&SUBASSET#";
|
||||
|
||||
private readonly Object m_RootObject;
|
||||
public Object RootObject => m_RootObject;
|
||||
|
||||
private readonly string m_PropertyPath;
|
||||
public string PropertyPath => m_PropertyPath;
|
||||
|
||||
private readonly string m_ControlName;
|
||||
public string ControlName => m_ControlName;
|
||||
|
||||
public SerializedTableProperty(Object rootObject, string propertyPath, string controlName)
|
||||
{
|
||||
m_RootObject = rootObject;
|
||||
m_PropertyPath = propertyPath;
|
||||
m_ControlName = controlName;
|
||||
}
|
||||
|
||||
public SerializedObject GetSerializedObject()
|
||||
{
|
||||
return new SerializedObject(m_RootObject);
|
||||
}
|
||||
|
||||
public SerializedProperty GetSerializedProperty()
|
||||
{
|
||||
return GetSerializedProperty(GetSerializedObject());
|
||||
}
|
||||
|
||||
public SerializedProperty GetSerializedProperty(SerializedObject serializedObject)
|
||||
{
|
||||
return serializedObject.FindProperty(PropertyPath);
|
||||
}
|
||||
|
||||
public string GetProperty(FlatFileFormatSettings formatSettings)
|
||||
{
|
||||
var property = GetSerializedProperty();
|
||||
if (property.propertyPath == UnityConstants.Field.Name)
|
||||
{
|
||||
return m_RootObject.name;
|
||||
}
|
||||
switch (property.propertyType)
|
||||
{
|
||||
case SerializedPropertyType.Integer:
|
||||
return property.GetIntStringValue();
|
||||
|
||||
case SerializedPropertyType.Boolean:
|
||||
return property.boolValue.ToString();
|
||||
|
||||
case SerializedPropertyType.Float:
|
||||
return property.GetFloatStringValue();
|
||||
|
||||
case SerializedPropertyType.String:
|
||||
return property.stringValue;
|
||||
|
||||
case SerializedPropertyType.Color:
|
||||
return ColorUtility.ToHtmlStringRGBA(property.colorValue);
|
||||
|
||||
case SerializedPropertyType.LayerMask:
|
||||
return property.intValue.ToString();
|
||||
|
||||
case SerializedPropertyType.Enum:
|
||||
if (!IsDefaultUnityEngineType(property.serializedObject) && formatSettings.UseStringEnums && property.TryGetEnumType(m_RootObject, out Type enumType))
|
||||
{
|
||||
if (!enumType.HasFlagsAttribute())
|
||||
{
|
||||
var enumName = Enum.GetName(enumType, property.intValue);
|
||||
if (!string.IsNullOrEmpty(enumName))
|
||||
{
|
||||
return enumName;
|
||||
}
|
||||
}
|
||||
}
|
||||
return property.intValue.ToString();
|
||||
|
||||
case SerializedPropertyType.ObjectReference:
|
||||
var objValue = property.objectReferenceValue;
|
||||
if (objValue != null && AssetDatabase.TryGetGUIDAndLocalFileIdentifier(property.objectReferenceValue, out string guid, out long localId))
|
||||
{
|
||||
return $"{guid}{AssetDelimiter}{objValue.name}";
|
||||
}
|
||||
else
|
||||
{
|
||||
return NullObjectValue;
|
||||
}
|
||||
|
||||
case SerializedPropertyType.ArraySize:
|
||||
return property.intValue.ToString();
|
||||
|
||||
case SerializedPropertyType.Character:
|
||||
return ((char) property.intValue).ToString();
|
||||
|
||||
case SerializedPropertyType.AnimationCurve:
|
||||
var animationCurveJson = JsonUtility.ToJson(new SerializableAnimationCurve(property));
|
||||
if (formatSettings.WrapOption.IsJsonUnsafe())
|
||||
{
|
||||
return animationCurveJson.EncodeBase64();
|
||||
}
|
||||
else
|
||||
{
|
||||
return animationCurveJson;
|
||||
}
|
||||
|
||||
case SerializedPropertyType.Gradient:
|
||||
var gradientJson = JsonUtility.ToJson(new SerializableGradient(property));
|
||||
if (formatSettings.WrapOption.IsJsonUnsafe())
|
||||
{
|
||||
return gradientJson.EncodeBase64();
|
||||
}
|
||||
else
|
||||
{
|
||||
return gradientJson;
|
||||
}
|
||||
|
||||
case SerializedPropertyType.Generic:
|
||||
if (property.IsAssetReference())
|
||||
{
|
||||
var assetGuid = property.FindPropertyRelative(UnityConstants.Field.AssetRefGuid)?.stringValue;
|
||||
var subObjectName = property.FindPropertyRelative(UnityConstants.Field.AssetRefSubObjectName)?.stringValue;
|
||||
if (string.IsNullOrEmpty(assetGuid))
|
||||
{
|
||||
return NullObjectValue;
|
||||
}
|
||||
return $"{assetGuid}{SubAssetDelimiter}{subObjectName}";
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"Unsupported generic property type for property at path {PropertyPath}.");
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
default:
|
||||
Debug.LogWarning($"Unsupported property type {property.propertyType} for property at path {PropertyPath}.");
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetProperty(string value, FlatFileFormatSettings formatSettings)
|
||||
{
|
||||
var serializedObject = GetSerializedObject();
|
||||
var property = GetSerializedProperty(serializedObject);
|
||||
if (property != null)
|
||||
{
|
||||
if ((!property.editable && property.name != UnityConstants.Field.Name) || value == null)
|
||||
{
|
||||
// Cannot change read-only properties. To set properties null use an empty string or the null object string.
|
||||
return;
|
||||
}
|
||||
var propertyType = property.propertyType;
|
||||
switch (property.propertyType)
|
||||
{
|
||||
case SerializedPropertyType.Integer:
|
||||
case SerializedPropertyType.ArraySize:
|
||||
if (!property.TrySetIntValue(value))
|
||||
{
|
||||
LogParseWarning(value, propertyType, $"Not a valid int for numeric type '{property.type}'.");
|
||||
}
|
||||
break;
|
||||
|
||||
case SerializedPropertyType.LayerMask:
|
||||
value = value.UnwrapLayerMask();
|
||||
if (int.TryParse(value, out int intValue))
|
||||
{
|
||||
property.intValue = intValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogParseWarning(value, propertyType, "Not a valid int.");
|
||||
}
|
||||
break;
|
||||
|
||||
case SerializedPropertyType.Enum:
|
||||
if (!IsDefaultUnityEngineType(serializedObject) && formatSettings.UseStringEnums)
|
||||
{
|
||||
if (property.TryGetEnumType(m_RootObject, out Type enumType))
|
||||
{
|
||||
if (!enumType.HasFlagsAttribute() || value.Contains(UnityConstants.EnumPrefix))
|
||||
{
|
||||
try
|
||||
{
|
||||
// Unity prefixes single enum values with 'Enum:' when copying from the Inspector.
|
||||
value = value.Replace(UnityConstants.EnumPrefix, string.Empty);
|
||||
// Use Enum.Parse instead of TryParse to support older versions of C#.
|
||||
var enumObject = Enum.Parse(enumType, value, formatSettings.IgnoreCase);
|
||||
property.intValue = (int) enumObject;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogParseWarning(value, propertyType, ex.Message);
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = value.UnwrapLayerMask();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogParseWarning(value, propertyType, "Did not find a valid enum type.");
|
||||
}
|
||||
}
|
||||
if (int.TryParse(value, out int enumValue))
|
||||
{
|
||||
property.intValue = enumValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogParseWarning(value, propertyType, "Not a valid int.");
|
||||
}
|
||||
break;
|
||||
|
||||
case SerializedPropertyType.Boolean:
|
||||
if (bool.TryParse(value, out bool boolValue))
|
||||
{
|
||||
property.boolValue = boolValue;
|
||||
}
|
||||
else if (int.TryParse(value, out int boolIntValue))
|
||||
{
|
||||
property.boolValue = boolIntValue > 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogParseWarning(value, propertyType, "Not a valid bool.");
|
||||
}
|
||||
break;
|
||||
|
||||
case SerializedPropertyType.Float:
|
||||
if (!property.TrySetFloatValue(value))
|
||||
{
|
||||
LogParseWarning(value, propertyType, "Not a valid float.");
|
||||
}
|
||||
break;
|
||||
|
||||
case SerializedPropertyType.String:
|
||||
if (property.name == UnityConstants.Field.Name)
|
||||
{
|
||||
if (!value.Any(c => Path.GetInvalidFileNameChars().Contains(c)))
|
||||
{
|
||||
if (value != m_RootObject.name)
|
||||
{
|
||||
var assetPath = AssetDatabase.GetAssetPath(m_RootObject);
|
||||
if (assetPath.Contains($"/{m_RootObject.name}."))
|
||||
{
|
||||
var assetRenameResponse = AssetDatabase.RenameAsset(assetPath, value);
|
||||
if (!string.IsNullOrEmpty(assetRenameResponse))
|
||||
{
|
||||
LogParseWarning(value, propertyType, assetRenameResponse);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RootObject.name = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"Invalid filename '{value}'.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
property.stringValue = value;
|
||||
}
|
||||
break;
|
||||
|
||||
case SerializedPropertyType.Color:
|
||||
if (value.Length > 0 && value[0] != '#')
|
||||
{
|
||||
value = "#" + value;
|
||||
}
|
||||
if (ColorUtility.TryParseHtmlString(value, out Color parsedColor))
|
||||
{
|
||||
property.colorValue = parsedColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogParseWarning(value, propertyType, "Not a valid color hex code.");
|
||||
}
|
||||
break;
|
||||
|
||||
case SerializedPropertyType.ObjectReference:
|
||||
if (value.Length > 0 && value != NullObjectValue)
|
||||
{
|
||||
// Handle case where user might copy from the inspector.
|
||||
UnityObjectWrapper objectWrapper = null;
|
||||
if (value.Contains(UnityConstants.ObjectWrapperJSON))
|
||||
{
|
||||
value = value.Replace(UnityConstants.ObjectWrapperJSON, string.Empty);
|
||||
try
|
||||
{
|
||||
objectWrapper = JsonConvert.DeserializeObject<UnityObjectWrapper>(value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogParseWarning(value, propertyType, ex.Message);
|
||||
break;
|
||||
}
|
||||
value = objectWrapper.Guid;
|
||||
}
|
||||
|
||||
var parts = value.Split(AssetDelimiter);
|
||||
var assetPath = AssetDatabase.GUIDToAssetPath(parts[0]);
|
||||
if (!string.IsNullOrEmpty(assetPath))
|
||||
{
|
||||
// GUIDs for Unity built in extra assets are not unique and must be found with a manual search by filename or localId.
|
||||
if (assetPath == UnityConstants.Path.BuiltInExtra)
|
||||
{
|
||||
Object foundAsset = null;
|
||||
var friendlyType = property.FriendlyType();
|
||||
if (objectWrapper != null)
|
||||
{
|
||||
foreach (var asset in SerializedPropertyUtility.UnityBuiltInAssets)
|
||||
{
|
||||
if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(asset, out string guid, out long localId) && objectWrapper.LocalId == localId)
|
||||
{
|
||||
foundAsset = asset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (foundAsset != null)
|
||||
{
|
||||
property.objectReferenceValue = foundAsset;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogParseWarning(value, propertyType, $"Unable to find asset at path '{assetPath}' with {objectWrapper}.");
|
||||
}
|
||||
}
|
||||
else if (parts.Length > 1 && !string.IsNullOrWhiteSpace(parts[1]))
|
||||
{
|
||||
foreach (var asset in SerializedPropertyUtility.UnityBuiltInAssets)
|
||||
{
|
||||
if (asset.name == parts[1] && friendlyType == asset.GetType().Name)
|
||||
{
|
||||
foundAsset = asset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (foundAsset != null)
|
||||
{
|
||||
property.objectReferenceValue = foundAsset;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogParseWarning(value, propertyType, $"Unable to find asset '{parts[1].GetEscapedText()}' at path '{assetPath}'.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogParseWarning(value, propertyType, $"Unable to find asset with GUID '{parts[0]}' at path '{assetPath}'. Please include the asset name.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!IsDefaultUnityEngineType(serializedObject))
|
||||
{
|
||||
// Certain Object types like Sprite as well as Sub Assets require the Type to be explicit when loading from an asset path.
|
||||
var objectType = ReflectionUtility.GetNestedFieldType(m_RootObject.GetType(), property.propertyPath);
|
||||
if (objectType != null)
|
||||
{
|
||||
property.objectReferenceValue = AssetDatabase.LoadAssetAtPath(assetPath, objectType);
|
||||
}
|
||||
else
|
||||
{
|
||||
property.objectReferenceValue = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Object));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
property.objectReferenceValue = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Object));
|
||||
}
|
||||
|
||||
// If we still haven't found the exact Object then see if it's a Sub Asset. This can occur with TMPro shared material assets and child GameObjects.
|
||||
if (parts.Length > 1 && (property.objectReferenceValue == null || property.objectReferenceValue.name != parts[1]))
|
||||
{
|
||||
foreach (var subAsset in AssetDatabase.LoadAllAssetsAtPath(assetPath))
|
||||
{
|
||||
property.objectReferenceValue = subAsset;
|
||||
// Validate the asset names match up if possible.
|
||||
if (property.objectReferenceValue != null && property.objectReferenceValue.name == parts[1])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogParseWarning(value, propertyType, $"Unable to find asset path for GUID '{parts[0].GetEscapedText()}'.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
property.objectReferenceValue = null;
|
||||
}
|
||||
break;
|
||||
|
||||
case SerializedPropertyType.Character:
|
||||
if (value.Length > 0)
|
||||
{
|
||||
property.intValue = value[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
LogParseWarning(value, propertyType, "Char cannot be empty.");
|
||||
}
|
||||
break;
|
||||
|
||||
case SerializedPropertyType.AnimationCurve:
|
||||
if (formatSettings.WrapOption.IsJsonUnsafe())
|
||||
{
|
||||
value = value.DecodeBase64();
|
||||
}
|
||||
// Handle case where user might copy from the inspector.
|
||||
value = value.Replace("UnityEditor.AnimationCurveWrapperJSON:{\"c", "{\"m_AnimationC");
|
||||
try
|
||||
{
|
||||
var animationCurve = JsonUtility.FromJson<SerializableAnimationCurve>(value).AnimationCurve;
|
||||
property.animationCurveValue = animationCurve;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogParseWarning(value, propertyType, ex.Message);
|
||||
}
|
||||
break;
|
||||
|
||||
case SerializedPropertyType.Gradient:
|
||||
if (formatSettings.WrapOption.IsJsonUnsafe())
|
||||
{
|
||||
value = value.DecodeBase64();
|
||||
}
|
||||
// Handle case where user might copy from the inspector.
|
||||
value = value.Replace("UnityEditor.GradientWrapperJSON:{\"g", "{\"m_G");
|
||||
try
|
||||
{
|
||||
var gradient = JsonUtility.FromJson<SerializableGradient>(value).Gradient;
|
||||
property.SetGradientValue(gradient);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogParseWarning(value, propertyType, ex.Message);
|
||||
}
|
||||
break;
|
||||
|
||||
case SerializedPropertyType.Generic:
|
||||
if (property.IsAssetReference())
|
||||
{
|
||||
var guidProperty = property.FindPropertyRelative(UnityConstants.Field.AssetRefGuid);
|
||||
var subObjectNameProperty = property.FindPropertyRelative(UnityConstants.Field.AssetRefSubObjectName);
|
||||
var subObjectTypeProperty = property.FindPropertyRelative(UnityConstants.Field.AssetRefSubObjectType);
|
||||
if (guidProperty != null && subObjectNameProperty != null && subObjectTypeProperty != null)
|
||||
{
|
||||
// Remove line endings to avoid creating sub asset references when pasting content.
|
||||
value = value.Replace("\r", string.Empty).Replace("\n", string.Empty);
|
||||
if (value.Length > 0 && value != NullObjectValue)
|
||||
{
|
||||
var parts = value.Split(new string[] { SubAssetDelimiter }, StringSplitOptions.None);
|
||||
var assetGuid = parts[0];
|
||||
var assetPath = AssetDatabase.GUIDToAssetPath(assetGuid);
|
||||
if (!string.IsNullOrEmpty(assetPath))
|
||||
{
|
||||
if (parts.Length > 1 && !string.IsNullOrEmpty(parts[1]))
|
||||
{
|
||||
var assetName = parts[1];
|
||||
var subAssets = AssetDatabase.LoadAllAssetRepresentationsAtPath(assetPath);
|
||||
var subObject = subAssets.FirstOrDefault(s => s.name == assetName);
|
||||
if (subObject != null)
|
||||
{
|
||||
guidProperty.stringValue = assetGuid;
|
||||
subObjectNameProperty.stringValue = assetName;
|
||||
subObjectTypeProperty.stringValue = subObject.GetType().AssemblyQualifiedName;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogParseWarning(value, propertyType, $"Failed to find sub asset '{assetName}' at path '{assetPath}'.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
guidProperty.stringValue = assetGuid;
|
||||
subObjectNameProperty.stringValue = string.Empty;
|
||||
subObjectTypeProperty.stringValue = string.Empty;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogParseWarning(value, propertyType, $"Failed to find asset with GUID '{assetGuid}'.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
guidProperty.stringValue = string.Empty;
|
||||
subObjectNameProperty.stringValue = string.Empty;
|
||||
subObjectTypeProperty.stringValue = string.Empty;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogParseWarning(value, propertyType, $"Unsupported type of {UnityConstants.Type.AssetReference}. Unable to find {UnityConstants.Type.AssetReference} properties.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogParseWarning(value, propertyType, "Unsupported Property Type.");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
LogParseWarning(value, propertyType, "Unsupported Property Type.");
|
||||
break;
|
||||
}
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SerializedPropertyUtility.IsArrayElement(m_PropertyPath))
|
||||
{
|
||||
Debug.LogWarning($"Unable to find array element at path {m_PropertyPath} on {nameof(Object)} {m_RootObject.name}. Did you update the size of the array?");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"Unable to find property at path {m_PropertyPath} on {nameof(Object)} {m_RootObject.name}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void LogParseWarning(string value, SerializedPropertyType propertyType, string message)
|
||||
{
|
||||
Debug.LogWarning($"Cannot parse '{value.GetEscapedText()}' to type {propertyType} for property at path {m_PropertyPath} on {nameof(Object)} {m_RootObject.name}.\n{message}");
|
||||
}
|
||||
|
||||
public void AddNewLine()
|
||||
{
|
||||
var serializedObject = GetSerializedObject();
|
||||
var property = GetSerializedProperty(serializedObject);
|
||||
if (property.propertyPath == UnityConstants.Field.Name)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (property.propertyType != SerializedPropertyType.String)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var editor = typeof(EditorGUI).GetField("activeEditor", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null) as TextEditor;
|
||||
if (editor == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
editor.Insert('\n');
|
||||
property.stringValue = editor.text;
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
var currentIndex = editor.cursorIndex;
|
||||
// Unity's default TextFields do not support multilines, brute force it.
|
||||
editor.cursorIndex = currentIndex;
|
||||
editor.selectIndex = currentIndex;
|
||||
EditorApplication.delayCall += () =>
|
||||
{
|
||||
if (editor != null)
|
||||
{
|
||||
editor.cursorIndex = currentIndex;
|
||||
editor.selectIndex = currentIndex;
|
||||
EditorApplication.delayCall += () =>
|
||||
{
|
||||
// If the user changed the index inbetween frames then we ignore this second delayed call, which would reset it back.
|
||||
if (editor != null && editor.cursorIndex != editor.selectIndex)
|
||||
{
|
||||
editor.cursorIndex = currentIndex;
|
||||
editor.selectIndex = currentIndex;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public bool IsInputFieldProperty(bool isScriptableObject)
|
||||
{
|
||||
var property = GetSerializedProperty();
|
||||
return property.IsInputFieldProperty(isScriptableObject);
|
||||
}
|
||||
|
||||
public bool IsUnityLocalizationProperty()
|
||||
{
|
||||
return PropertyPath.EndsWith(UnityConstants.Field.TableReferenceCollectionName) || PropertyPath.EndsWith(UnityConstants.Field.TableEntryReferenceKeyId);
|
||||
}
|
||||
|
||||
// Draw our own selected cell border for properties Unity doesn't automatically.
|
||||
public bool NeedsSelectionBorder(bool lockNames = false)
|
||||
{
|
||||
var property = GetSerializedProperty();
|
||||
// Name property is readonly on certain fields like Enum TextAssets.
|
||||
var isNameProperty = property.propertyPath == UnityConstants.Field.Name;
|
||||
return (!isNameProperty && property.IsReadOnly() || (isNameProperty && lockNames)) || property.propertyType == SerializedPropertyType.AnimationCurve || property.propertyType == SerializedPropertyType.Gradient;
|
||||
}
|
||||
|
||||
// Various default Unity Engine Components have different limitations on how backing fields are serialized and accessed.
|
||||
private static bool IsDefaultUnityEngineType(SerializedObject serializedObject)
|
||||
{
|
||||
return serializedObject.targetObject.GetType().FullName.StartsWith(UnityConstants.Type.UnityEngine);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b30a41eefbfb06d45bf6cd0b56aff4ca
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 284559
|
||||
packageName: Scriptable Sheets
|
||||
packageVersion: 1.8.0
|
||||
assetPath: Packages/com.lunawolfstudios.scriptablesheets/Editor/Modules/Tables/TableProperties/SerializedTableProperty.cs
|
||||
uploadId: 823456
|
||||
Reference in New Issue
Block a user