初始化

This commit is contained in:
come
2025-07-26 16:56:42 +08:00
parent 8291dbb91c
commit fa81439a8c
2574 changed files with 328492 additions and 2170 deletions

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: d92d0eb8b980c6d44b5f0e64a620355b
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7baa23f1c7f0b87469e056662cd72ad1
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ba1664ec1a0467641a742eaadae146d4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,29 @@
{
"name": "Sirenix.OdinInspector.Modules.Unity.Addressables",
"references": [
"Unity.Addressables",
"Unity.Addressables.Editor",
"Sirenix.Serialization",
"Sirenix.OdinInspector.Attributes",
"Sirenix.OdinInspector.Editor",
"Sirenix.Utilities.Editor",
"Sirenix.Utilities",
"Sirenix.OdinValidator.Editor"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": true,
"overrideReferences": false,
"precompiledReferences": [
"Sirenix.Serialization.dll",
"Sirenix.OdinInspector.Attributes.dll",
"Sirenix.OdinInspector.Editor.dll",
"Sirenix.Utilities.Editor.dll",
"Sirenix.Utilities.dll",
"Sirenix.OdinValidator.Editor.dll"
],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 3b4d8e09c665bfa47849130d8695171e
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b568c1d508ce0b74eb0025b8501d1c1e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,94 @@
//-----------------------------------------------------------------------
// <copyright file="AssetLabelReferenceValidator.cs" company="Sirenix ApS">
// Copyright (c) Sirenix ApS. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
#if UNITY_EDITOR
using UnityEngine;
using UnityEditor.AddressableAssets;
using Sirenix.OdinInspector.Editor.Validation;
using UnityEngine.AddressableAssets;
using Sirenix.OdinInspector.Modules.Addressables.Editor;
#if ODIN_VALIDATOR_3_1
[assembly: RegisterValidationRule(typeof(AssetLabelReferenceValidator), Description =
"This validator ensures that AssetLabelReferences marked with the Required attribute display an error " +
"message if they are not set. It can also be configured to require that all AssetLabelReferences be set " +
"by default; the Optional attribute can then be used to exclude specific AssetLabelReferences from " +
"validation.")]
#else
[assembly: RegisterValidator(typeof(AssetLabelReferenceValidator))]
#endif
namespace Sirenix.OdinInspector.Modules.Addressables.Editor
{
/// <summary>
/// Validator for AssetLabelReference values.
/// </summary>
public class AssetLabelReferenceValidator : ValueValidator<AssetLabelReference>
{
[Tooltip("If enabled, the validator will display an error message if the AssetLabelReference is not set. " +
"If disabled, the validator will only display an error message if the AssetLabelReference is set, but the " +
"assigned label does not exist.")]
[ToggleLeft]
public bool RequiredByDefault;
private bool required;
private bool optional;
private string requiredMessage;
protected override void Initialize()
{
var requiredAttr = this.Property.GetAttribute<RequiredAttribute>();
this.requiredMessage = requiredAttr?.ErrorMessage ?? $"<b>{this.Property.NiceName}</b> is required.";
if (this.RequiredByDefault)
{
required = true;
optional = Property.GetAttribute<OptionalAttribute>() != null;
}
else
{
required = requiredAttr != null;
optional = false;
}
}
protected override void Validate(ValidationResult result)
{
// If the Addressables settings have not been created, nothing else is really valid.
if (AddressableAssetSettingsDefaultObject.SettingsExists == false)
{
result.AddError("Addressables Settings have not been created.")
.WithButton("Open Settings Window", () => OdinAddressableUtility.OpenGroupsWindow());
return;
}
var value = Value?.labelString;
if (string.IsNullOrEmpty(value))
{
if (optional == false && required) // Optional == false & required? Nice.
{
result.AddError(requiredMessage).EnableRichText();
}
}
else
{
var labels = AddressableAssetSettingsDefaultObject.Settings.GetLabels();
if (labels.Contains(value) == false)
{
result.AddError($"Label <i>{value}</i> has not been created as a label.")
.WithButton("Open Label Settings", () => OdinAddressableUtility.OpenLabelsWindow());
}
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fcaf7dc3b9a98a545b301a1ea175055b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,280 @@
//-----------------------------------------------------------------------
// <copyright file="AssetReferenceValidator.cs" company="Sirenix ApS">
// Copyright (c) Sirenix ApS. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
#if UNITY_EDITOR
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEditor;
using UnityEditor.AddressableAssets;
using Sirenix.OdinInspector.Editor.Validation;
using Sirenix.Utilities;
using Sirenix.Utilities.Editor;
using UnityEditor.AddressableAssets.Settings;
using UnityEngine.AddressableAssets;
using Sirenix.OdinInspector.Modules.Addressables.Editor;
#if ODIN_VALIDATOR_3_1
[assembly: RegisterValidationRule(typeof(AssetReferenceValidator), Description =
"This validator provides robust integrity checks for your asset references within Unity. " +
"It validates whether an asset reference has been assigned, and if it's missing, raises an error. " +
"It further checks the existence of the main asset at the assigned path, ensuring it hasn't been " +
"inadvertently deleted or moved. The validator also verifies if the assigned asset is addressable " +
"and, if not, offers a fix to make it addressable. Moreover, it ensures the asset adheres to " +
"specific label restrictions set through the AssetReferenceUILabelRestriction attribute. " +
"Lastly, it performs checks on any sub-object linked to the asset, making sure it hasn't gone missing. " +
"This comprehensive validation system prevents hard-to-spot bugs and errors, " +
"fostering a more robust and efficient development workflow.")]
#else
[assembly: RegisterValidator(typeof(AssetReferenceValidator))]
#endif
namespace Sirenix.OdinInspector.Modules.Addressables.Editor
{
public class AssetReferenceValidator : ValueValidator<AssetReference>
{
[Tooltip("If true and the AssetReference is not marked with the Optional attribute, " +
"the validator will display an error message if the AssetReference is not set. " +
"If false, the validator will only display an error message if the AssetReference is set, " +
"but the assigned asset does not exist.")]
[ToggleLeft]
public bool RequiredByDefault;
private bool required;
private bool optional;
private string requiredMessage;
private List<AssetReferenceUIRestriction> restrictions;
protected override void Initialize()
{
var requiredAttr = this.Property.GetAttribute<RequiredAttribute>();
this.requiredMessage = requiredAttr?.ErrorMessage ?? $"<b>{this.Property.NiceName}</b> is required.";
if (this.RequiredByDefault)
{
this.required = true;
this.optional = this.Property.GetAttribute<OptionalAttribute>() != null;
}
else
{
this.required = requiredAttr != null;
this.optional = false;
}
this.restrictions = new List<AssetReferenceUIRestriction>();
foreach (var attr in this.Property.Attributes)
{
if (attr is AssetReferenceUIRestriction r)
{
this.restrictions.Add(r);
}
}
}
protected override void Validate(ValidationResult result)
{
// If the Addressables settings have not been created, nothing else is really valid.
if (AddressableAssetSettingsDefaultObject.SettingsExists == false)
{
result.AddError("Addressables Settings have not been created.")
.WithButton("Open Settings Window", () => OdinAddressableUtility.OpenGroupsWindow());
return;
}
var assetReference = this.Value;
var assetReferenceHasBeenAssigned = !string.IsNullOrEmpty(assetReference?.AssetGUID);
// No item has been assigned.
if (!assetReferenceHasBeenAssigned)
{
if (optional == false && required) // Optional == false & required? Nice.
{
result.AddError(this.requiredMessage).EnableRichText();
}
return;
}
var assetPath = AssetDatabase.GUIDToAssetPath(assetReference.AssetGUID);
var mainAsset = AssetDatabase.LoadMainAssetAtPath(assetPath);
// The item has been assigned, but is now missing.
if (mainAsset == null)
{
result.AddError($"The previously assigned main asset with path <b>'{assetPath}'</b> is missing. GUID <b>'{assetReference.AssetGUID}'</b>");
return;
}
var addressableAssetEntry = AddressableAssetSettingsDefaultObject.Settings.FindAssetEntry(assetReference.AssetGUID, true);
var isAddressable = addressableAssetEntry != null;
// Somehow an item sneaked through all of unity's validation measures and ended up not being addressable
// while still ending up in the asset reference object field.
if (!isAddressable)
{
result.AddError("Assigned item is not addressable.")
.WithFix<MakeAddressableFixArgs>("Make Addressable", args => OdinAddressableUtility.MakeAddressable(mainAsset, args.Group));
}
// Check the assigned item against any and all label restrictions.
else
{
if (OdinAddressableUtility.ValidateAssetReferenceRestrictions(restrictions, mainAsset, out var failedRestriction) == false)
{
if (failedRestriction is AssetReferenceUILabelRestriction labelRestriction)
{
result.AddError($"Asset reference is restricted to items with these specific labels <b>'{string.Join(", ", labelRestriction.m_AllowedLabels)}'</b>. The currently assigned item has none of them.")
.WithFix<AddLabelsFixArgs>("Add Labels", args => SetLabels(mainAsset, args.AssetLabels));
}
else
{
result.AddError("Restriction failed: " + failedRestriction.ToString());
}
}
}
// The assigned item had a sub object, but it's missing.
if (!string.IsNullOrEmpty(assetReference.SubObjectName))
{
var subObjects = AssetDatabase.LoadAllAssetRepresentationsAtPath(assetPath);
var hasMissingSubObject = true;
foreach (var subObject in subObjects)
{
if (subObject.name == assetReference.SubObjectName)
{
hasMissingSubObject = false;
break;
}
}
if (hasMissingSubObject)
{
result.AddError($"The previously assigned sub asset with name <b>'{assetReference.SubObjectName}'</b> is missing.").EnableRichText();
}
}
if (assetReference.ValidateAsset(mainAsset) || assetReference.ValidateAsset(assetPath))
return;
if (assetReference is AssetReferenceSprite && assetReference.editorAsset is Sprite)
return;
result.AddError($"{assetReference.GetType().GetNiceFullName()}.ValidateAsset failed to validate assigned asset.");
}
private static void SetLabels(UnityEngine.Object obj, List<AssetLabel> assetLabels)
{
if (!AddressableAssetSettingsDefaultObject.SettingsExists) return;
var settings = AddressableAssetSettingsDefaultObject.Settings;
var guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(obj));
var entry = settings.FindAssetEntry(guid, false);
foreach (var assetLabel in assetLabels.Where(a => a.Toggled))
{
entry.SetLabel(assetLabel.Label, true, false, false);
}
settings.SetDirty(AddressableAssetSettings.ModificationEvent.LabelAdded, entry, false, true);
}
private class MakeAddressableFixArgs
{
[ValueDropdown(nameof(GetGroups))]
[OnInspectorInit(nameof(SelectDefault))]
public AddressableAssetGroup Group;
private void SelectDefault()
{
this.Group = AddressableAssetSettingsDefaultObject.SettingsExists
? AddressableAssetSettingsDefaultObject.Settings.DefaultGroup
: null;
}
private static IEnumerable<ValueDropdownItem> GetGroups()
{
return !AddressableAssetSettingsDefaultObject.SettingsExists
? Enumerable.Empty<ValueDropdownItem>()
: AddressableAssetSettingsDefaultObject.Settings.groups
.Where(group => !group.ReadOnly)
.Select(group => new ValueDropdownItem(group.Name, group));
}
[Button(SdfIconType.ListNested), PropertySpace(8f)]
private void OpenAddressablesGroups() => OdinAddressableUtility.OpenGroupsWindow();
}
private class AddLabelsFixArgs
{
[HideIf("@true")]
public List<AssetLabel> AssetLabels
{
get
{
if (!AddressableAssetSettingsDefaultObject.SettingsExists) return this.assetLabels;
var settings = AddressableAssetSettingsDefaultObject.Settings;
var labels = settings
.GetLabels()
.Select(l => new AssetLabel { Label = l, Toggled = false })
.ToList();
foreach (var assetLabel in this.assetLabels)
{
var label = labels.FirstOrDefault(l => l.Label == assetLabel.Label);
if (label != null)
{
label.Toggled = assetLabel.Toggled;
}
}
this.assetLabels = labels;
return this.assetLabels;
}
}
private List<AssetLabel> assetLabels = new List<AssetLabel>();
[OnInspectorGUI]
private void Draw()
{
var togglesRect = EditorGUILayout.GetControlRect(false, Mathf.CeilToInt(this.AssetLabels.Count / 2f) * 20f);
for (var i = 0; i < this.AssetLabels.Count; i++)
{
var assetLabel = this.AssetLabels[i];
var toggleRect = togglesRect.SplitGrid(togglesRect.width / 2f, 20, i);
assetLabel.Toggled = GUI.Toggle(toggleRect, assetLabel.Toggled, assetLabel.Label);
}
if (!AddressableAssetSettingsDefaultObject.SettingsExists) return;
GUILayout.Space(8f);
var buttonsRect = EditorGUILayout.GetControlRect(false, 20f);
if (SirenixEditorGUI.SDFIconButton(buttonsRect, "Open Addressables Labels", SdfIconType.TagsFill))
{
OdinAddressableUtility.OpenLabelsWindow();
}
}
}
private class AssetLabel
{
public bool Toggled;
public string Label;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b44b08a1f58a83149988fde5ac600fe4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,201 @@
//-----------------------------------------------------------------------
// <copyright file="CheckDuplicateBundleDependenciesValidator.cs" company="Sirenix ApS">
// Copyright (c) Sirenix ApS. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
#if UNITY_EDITOR && ODIN_VALIDATOR_3_1
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEditor;
using UnityEditor.AddressableAssets;
using Sirenix.OdinInspector.Editor.Validation;
using Sirenix.Utilities;
using Sirenix.Utilities.Editor;
using UnityEditor.AddressableAssets.Settings;
using System.Collections;
using System;
using Sirenix.OdinValidator.Editor;
using Sirenix.OdinInspector.Modules.Addressables.Editor;
[assembly: RegisterValidationRule(typeof(CheckDuplicateBundleDependenciesValidator),
Description = "This validator detects potential duplicate asset dependencies in an addressable group, without the need for a build. " +
"For instance, imagine two prefabs in separate groups, both referencing the same material. Each group would then include the material " +
"and all its associated dependencies. " +
"To address this, the material should be marked as Addressable, either with one of the prefabs or in a distinct group.\n\n" +
"<b>Fixes: </b>Executing the fix will make the dependency addressable and move it to the specified group.\n\n" +
"<b>Exceptions: </b>It's important to note that duplicate assets aren't inherently problematic. For example, if certain assets are " +
"never accessed by the same user group, such as region-specific assets, these duplications might be desired or at least inconsequential. " +
"As every project is unique, decisions concerning duplicate asset dependencies should be considered on a case-by-case basis.")]
namespace Sirenix.OdinInspector.Modules.Addressables.Editor
{
public class CheckDuplicateBundleDependenciesValidator : GlobalValidator
{
private static Dictionary<GUID, List<string>> dependencyGroupMap = new Dictionary<GUID, List<string>>();
[Tooltip("The severity of the validation result.")]
public ValidatorSeverity ValidatorSeverity = ValidatorSeverity.Warning;
[Tooltip("Assets to ignore when validating.")]
[LabelText("Ignored GUIDs"), CustomValueDrawer(nameof(DrawGUIDEntry))]
public List<string> IgnoredGUIDs = new List<string>();
public override IEnumerable RunValidation(ValidationResult result)
{
dependencyGroupMap.Clear();
var addressableAssetSettings = AddressableAssetSettingsDefaultObject.Settings;
if (addressableAssetSettings == null) yield break;
foreach (var addressableAssetGroup in addressableAssetSettings.groups)
{
if (addressableAssetGroup == null) continue;
foreach (var addressableAssetEntry in addressableAssetGroup.entries)
{
var dependencyAssetPaths = AssetDatabase.GetDependencies(addressableAssetEntry.AssetPath)
.Where(assetPath => !assetPath.EndsWith(".cs", StringComparison.OrdinalIgnoreCase) &&
!assetPath.EndsWith(".dll", StringComparison.OrdinalIgnoreCase));
foreach (var dependencyAssetPath in dependencyAssetPaths)
{
var dependencyGUID = new GUID(AssetDatabase.AssetPathToGUID(dependencyAssetPath));
if (this.IgnoredGUIDs.Contains(dependencyGUID.ToString())) continue;
var dependencyAddressableAssetEntry = addressableAssetSettings.FindAssetEntry(dependencyGUID.ToString());
var isAddressable = dependencyAddressableAssetEntry != null;
if (isAddressable) continue;
if (!dependencyGroupMap.ContainsKey(dependencyGUID))
{
dependencyGroupMap.Add(dependencyGUID, new List<string>());
}
if (!dependencyGroupMap[dependencyGUID].Contains(addressableAssetGroup.Name))
{
dependencyGroupMap[dependencyGUID].Add(addressableAssetGroup.Name);
}
}
}
}
foreach (var kvp in dependencyGroupMap)
{
var dependencyGUID = kvp.Key;
var groups = kvp.Value;
if (groups.Count > 1)
{
var assetPath = AssetDatabase.GUIDToAssetPath(dependencyGUID.ToString());
var message = $"{assetPath} is duplicated in these groups: {string.Join(", ", groups)}";
result.Add(this.ValidatorSeverity, message).WithFix<FixArgs>(args =>
{
if (args.FixChoice == FixChoice.Ignore)
{
var sourceType = args.IgnoreForEveryone ? ConfigSourceType.Project : ConfigSourceType.Local;
var data = RuleConfig.Instance.GetRuleData<CheckDuplicateBundleDependenciesValidator>(sourceType);
data.IgnoredGUIDs.Add(dependencyGUID.ToString());
RuleConfig.Instance.SetAndSaveRuleData(data, sourceType);
return;
}
var obj = AssetDatabase.LoadAssetAtPath(assetPath, typeof(UnityEngine.Object));
AddressableAssetGroup group;
if (args.Group == "Create New Group")
{
if (args.GroupName.IsNullOrWhitespace()) return;
group = addressableAssetSettings.FindGroup(args.GroupName);
if (group == null)
{
group = addressableAssetSettings.CreateGroup(args.GroupName, false, false, false, null);
}
}
else
{
group = addressableAssetSettings.FindGroup(args.Group);
if (group == null)
{
group = addressableAssetSettings.CreateGroup(args.Group, false, false, false, null);
}
}
OdinAddressableUtility.MakeAddressable(obj, group);
}, false).WithModifyRuleDataContextClick<CheckDuplicateBundleDependenciesValidator>("Ignore", data =>
{
data.IgnoredGUIDs.Add(dependencyGUID.ToString());
}).SetSelectionObject(AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(AssetDatabase.GUIDToAssetPath(dependencyGUID.ToString())));
}
}
}
private string DrawGUIDEntry(string guid)
{
var assetPath = AssetDatabase.GUIDToAssetPath(guid);
EditorGUILayout.TextArea(assetPath, SirenixGUIStyles.MultiLineLabel);
EditorGUILayout.TextField(guid);
return guid;
}
private enum FixChoice
{
AddToGroup,
Ignore,
}
private class FixArgs
{
[EnumToggleButtons, HideLabel]
public FixChoice FixChoice;
[PropertySpace(10)]
[ValueDropdown("Groups")]
//[Title("Group To Add To", TitleAlignment = TitleAlignments.Centered)]
[ShowIf(nameof(FixChoice), FixChoice.AddToGroup, Animate = false)]
public string Group = "Duplicate Asset Isolation";
[ValidateInput(nameof(ValidateGroupName), "The group name cannot be empty")]
[ShowIf(nameof(ShowNewGroupName), Animate = false)]
public string GroupName;
[LabelWidth(120f)]
[PropertySpace(10)]
[ShowIf("FixChoice", FixChoice.Ignore, Animate = false)]
public bool IgnoreForEveryone = true;
[OnInspectorGUI]
[PropertySpace(10)]
[DetailedInfoBox("Note that duplicate assets may not always be an issue", "Note that duplicate assets may not always be an issue. If assets will never be requested by the same set of users (for example, region-specific assets), then duplicate dependencies may be desired, or at least inconsequential. Each Project is unique, so fixing duplicate asset dependencies should be evaluated on a case by case basis")]
private void Dummy() { }
private bool ShowNewGroupName => this.FixChoice != FixChoice.Ignore && this.Group == "Create New Group";
private bool ValidateGroupName() => !this.GroupName.IsNullOrWhitespace();
private IEnumerable<string> Groups()
{
var addressableAssetSettings = AddressableAssetSettingsDefaultObject.Settings;
return addressableAssetSettings == null
? Enumerable.Empty<string>()
: addressableAssetSettings.groups
.Where(group => group != null && group.Name != "Built In Data")
.Select(group => group.Name)
.Append("Duplicate Asset Isolation")
.Prepend("Create New Group");
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bdc8ee2cf75a17644a0bd81a965cc2e0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,171 @@
//-----------------------------------------------------------------------
// <copyright file="CheckResourcesToAddressableDuplicateDependenciesValidator.cs" company="Sirenix ApS">
// Copyright (c) Sirenix ApS. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
#if UNITY_EDITOR && ODIN_VALIDATOR_3_1
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEditor;
using UnityEditor.AddressableAssets;
using Sirenix.OdinInspector.Editor.Validation;
using Sirenix.Utilities.Editor;
using System.Collections;
using System;
using System.IO;
using Sirenix.OdinValidator.Editor;
using Sirenix.OdinInspector.Modules.Addressables.Editor;
[assembly: RegisterValidationRule(typeof(CheckResourcesToAddressableDuplicateDependenciesValidator),
Description = "This validator identifies dependencies that are duplicated in both addressable groups and the \"Resources\" folder.\n\n" +
"These duplications mean that data will be included in both the application build and the addressables build.\n\n" +
"You can decide to simply ignore these duplicated dependencies if this behavior is desired, or use the provided fix " +
"to move the asset outside of the \"Resources\" folder.")]
namespace Sirenix.OdinInspector.Modules.Addressables.Editor
{
public class CheckResourcesToAddressableDuplicateDependenciesValidator : GlobalValidator
{
[Tooltip("The severity of the validation result.")]
public ValidatorSeverity ValidatorSeverity = ValidatorSeverity.Warning;
[Tooltip("Assets to ignore when validating.")]
[LabelText("Ignored GUIDs"), CustomValueDrawer(nameof(DrawGUIDEntry))]
public List<string> IgnoredGUIDs = new List<string>();
public override IEnumerable RunValidation(ValidationResult result)
{
var addressableAssetSettings = AddressableAssetSettingsDefaultObject.Settings;
if (addressableAssetSettings == null) yield break;
foreach (var addressableAssetGroup in addressableAssetSettings.groups)
{
if (addressableAssetGroup == null) continue;
foreach (var addressableAssetEntry in addressableAssetGroup.entries)
{
var dependencyAssetPaths = AssetDatabase.GetDependencies(addressableAssetEntry.AssetPath)
.Where(assetPath => !assetPath.EndsWith(".cs", StringComparison.OrdinalIgnoreCase) &&
!assetPath.EndsWith(".dll", StringComparison.OrdinalIgnoreCase));
foreach (var dependencyAssetPath in dependencyAssetPaths)
{
var dependencyGUID = new GUID(AssetDatabase.AssetPathToGUID(dependencyAssetPath));
if (this.IgnoredGUIDs.Contains(dependencyGUID.ToString())) continue;
var dependencyAddressableAssetEntry = addressableAssetSettings.FindAssetEntry(dependencyGUID.ToString());
var isAddressable = dependencyAddressableAssetEntry != null;
if (isAddressable) continue;
if (!IsInsideResourcesFolder(dependencyAssetPath)) continue;
result.Add(this.ValidatorSeverity, $"{dependencyAssetPath} is duplicated in addressable data and resource folders.")
.WithFix<FixArgs>(args =>
{
if (args.FixChoice == FixChoice.Ignore)
{
var sourceType = args.IgnoreForEveryone ? ConfigSourceType.Project : ConfigSourceType.Local;
var data = RuleConfig.Instance.GetRuleData<CheckResourcesToAddressableDuplicateDependenciesValidator>(sourceType);
data.IgnoredGUIDs.Add(dependencyGUID.ToString());
RuleConfig.Instance.SetAndSaveRuleData(data, sourceType);
return;
}
if (!ValidNewFolder(args.NewFolder, out _)) return;
if (!AssetDatabase.IsValidFolder(args.NewFolder))
{
Directory.CreateDirectory(new DirectoryInfo(args.NewFolder).FullName);
AssetDatabase.Refresh();
}
var newPath = $"{args.NewFolder}/{Path.GetFileName(dependencyAssetPath)}";
AssetDatabase.MoveAsset(dependencyAssetPath, newPath);
}, false).WithModifyRuleDataContextClick<CheckResourcesToAddressableDuplicateDependenciesValidator>("Ignore", data =>
{
data.IgnoredGUIDs.Add(dependencyGUID.ToString());
}).SetSelectionObject(AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(AssetDatabase.GUIDToAssetPath(dependencyGUID.ToString())));
yield break;
}
}
}
}
private string DrawGUIDEntry(string guid)
{
var assetPath = AssetDatabase.GUIDToAssetPath(guid);
EditorGUILayout.TextArea(assetPath, SirenixGUIStyles.MultiLineLabel);
EditorGUILayout.TextField(guid);
return guid;
}
private static bool IsInsideResourcesFolder(string path)
{
var pathElements = path.Split('/');
foreach (var pathElement in pathElements)
{
if (pathElement.Equals("Resources", StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
return false;
}
private static bool ValidNewFolder(string path, out string message)
{
if (IsInsideResourcesFolder(path))
{
message = "The asset cannot be moved into a 'Resources' folder";
return false;
}
if (!path.StartsWith("Assets/"))
{
message = "The asset must be inside the 'Assets' folder";
return false;
}
message = "The folder is valid";
return true;
}
private enum FixChoice
{
MoveAsset,
Ignore,
}
private class FixArgs
{
[HideLabel]
[EnumToggleButtons]
public FixChoice FixChoice;
[FolderPath]
[PropertySpace(10)]
[ValidateInput(nameof(ValidateFolderPath))]
[ShowIf("FixChoice", FixChoice.MoveAsset, Animate = false)]
public string NewFolder = "Assets/Resources_moved";
[LabelWidth(120f)]
[PropertySpace(10)]
[ShowIf("FixChoice", FixChoice.Ignore, Animate = false)]
public bool IgnoreForEveryone = true;
private bool ValidateFolderPath(string path, ref string message)
{
return ValidNewFolder(path, out message);
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f75aebe03a9aa4a4b82d2b54dcc34de5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,34 @@
//-----------------------------------------------------------------------
// <copyright file="DisallowAddressableSubAssetFieldAttributeValidator.cs" company="Sirenix ApS">
// Copyright (c) Sirenix ApS. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
#if UNITY_EDITOR
using Sirenix.OdinInspector.Editor.Validation;
using Sirenix.OdinInspector.Modules.Addressables.Editor;
using UnityEngine.AddressableAssets;
[assembly: RegisterValidator(typeof(DisallowAddressableSubAssetFieldAttributeValidator))]
namespace Sirenix.OdinInspector.Modules.Addressables.Editor
{
/// <summary>
/// Validator for the DisallowAddressableSubAssetFieldAttribute.
/// </summary>
public class DisallowAddressableSubAssetFieldAttributeValidator : AttributeValidator<DisallowAddressableSubAssetFieldAttribute, AssetReference>
{
protected override void Validate(ValidationResult result)
{
if (this.Value != null && string.IsNullOrEmpty(this.Value.SubObjectName) == false)
{
result.AddError("Sub-asset references is not allowed on this field.")
.WithFix("Remove Sub-Asset", () => this.Value.SubObjectName = null, true);
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5775d33ffc1143149c4f425f693b04b6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,55 @@
//-----------------------------------------------------------------------
// <copyright file="MissingAddressableGroupReferenceValidator.cs" company="Sirenix ApS">
// Copyright (c) Sirenix ApS. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
#if UNITY_EDITOR && ODIN_VALIDATOR_3_1
using System.Collections.Generic;
using UnityEditor.AddressableAssets;
using Sirenix.OdinInspector.Editor.Validation;
using UnityEditor.AddressableAssets.Settings;
using System.Collections;
using Sirenix.OdinInspector.Modules.Addressables.Editor;
[assembly: RegisterValidator(typeof(MissingAddressableGroupReferenceValidator))]
namespace Sirenix.OdinInspector.Modules.Addressables.Editor
{
public class MissingAddressableGroupReferenceValidator : GlobalValidator
{
public override IEnumerable RunValidation(ValidationResult result)
{
var addressableAssetSettings = AddressableAssetSettingsDefaultObject.Settings;
if (addressableAssetSettings == null) yield break;
var missingGroupIndices = new List<int>();
for (var i = 0; i < addressableAssetSettings.groups.Count; i++)
{
var group = addressableAssetSettings.groups[i];
if (group == null)
{
missingGroupIndices.Add(i);
}
}
if (missingGroupIndices.Count > 0)
{
result.Add(ValidatorSeverity.Error, "Addressable groups contains missing references").WithFix("Delete missing reference", () =>
{
for (var i = missingGroupIndices.Count - 1; i >= 0; i--)
{
addressableAssetSettings.groups.RemoveAt(missingGroupIndices[i]);
addressableAssetSettings.SetDirty(AddressableAssetSettings.ModificationEvent.GroupRemoved, null, true, true);
}
});
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4ae55abdaf19ef4498d1a2fbe1bd9f9b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,21 @@
ManifestVersion: 1
ModuleID: Unity.Addressables
ModuleVersion: 1.1.0.4
ModuleFiles:
AddressablesInspectors.cs
AddressablesInspectors.cs.meta
Sirenix.OdinInspector.Modules.Unity.Addressables.asmdef
Sirenix.OdinInspector.Modules.Unity.Addressables.asmdef.meta
Validators.meta
Validators/AssetLabelReferenceValidator.cs
Validators/AssetLabelReferenceValidator.cs.meta
Validators/AssetReferenceValidator.cs
Validators/AssetReferenceValidator.cs.meta
Validators/CheckDuplicateBundleDependenciesValidator.cs
Validators/CheckDuplicateBundleDependenciesValidator.cs.meta
Validators/CheckResourcesToAddressableDuplicateDependenciesValidator.cs
Validators/CheckResourcesToAddressableDuplicateDependenciesValidator.cs.meta
Validators/DisallowAddressableSubAssetFieldAttributeValidator.cs
Validators/DisallowAddressableSubAssetFieldAttributeValidator.cs.meta
Validators/MissingAddressableGroupReferenceValidator.cs
Validators/MissingAddressableGroupReferenceValidator.cs.meta

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 25fb33c418245fb4c9a46da061f40821
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 728df0e3465c1a148b83053a3f31d489
timeCreated: 1573836981
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,6 @@
fileFormatVersion: 2
guid: 5a1693d73a4f6e34d955789129c71e11
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4866e740a22eb1e49b1603b051e4d92c
timeCreated: 1573836980
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a0e57d3aa973ccc469187fec43fa117b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,883 @@
//-----------------------------------------------------------------------
// <copyright file="MathematicsDrawers.cs" company="Sirenix ApS">
// Copyright (c) Sirenix ApS. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
namespace Sirenix.OdinInspector.Modules.UnityMathematics.Editor
{
#if UNITY_EDITOR
using System;
using System.Collections.Generic;
using System.Reflection;
using Sirenix.OdinInspector.Editor;
using Sirenix.Utilities;
using Sirenix.Utilities.Editor;
using Unity.Mathematics;
using UnityEditor;
using UnityEngine;
public sealed class MatrixFloat2x2Processor : MatrixProcessor<float2x2> { }
public sealed class MatrixFloat3x2Processor : MatrixProcessor<float3x2> { }
public sealed class MatrixFloat4x2Processor : MatrixProcessor<float4x2> { }
public sealed class MatrixFloat2x3Processor : MatrixProcessor<float2x3> { }
public sealed class MatrixFloat3x3Processor : MatrixProcessor<float3x3> { }
public sealed class MatrixFloat4x3Processor : MatrixProcessor<float4x3> { }
public sealed class MatrixFloat2x4Processor : MatrixProcessor<float2x4> { }
public sealed class MatrixFloat3x4Processor : MatrixProcessor<float3x4> { }
public sealed class MatrixFloat4x4Processor : MatrixProcessor<float4x4> { }
public sealed class MatrixDouble2x2Processor : MatrixProcessor<double2x2> { }
public sealed class MatrixDouble3x2Processor : MatrixProcessor<double3x2> { }
public sealed class MatrixDouble4x2Processor : MatrixProcessor<double4x2> { }
public sealed class MatrixDouble2x3Processor : MatrixProcessor<double2x3> { }
public sealed class MatrixDouble3x3Processor : MatrixProcessor<double3x3> { }
public sealed class MatrixDouble4x3Processor : MatrixProcessor<double4x3> { }
public sealed class MatrixDouble2x4Processor : MatrixProcessor<double2x4> { }
public sealed class MatrixDouble3x4Processor : MatrixProcessor<double3x4> { }
public sealed class MatrixDouble4x4Processor : MatrixProcessor<double4x4> { }
public sealed class MatrixBool2x2Processor : MatrixProcessor<bool2x2> { }
public sealed class MatrixBool3x2Processor : MatrixProcessor<bool3x2> { }
public sealed class MatrixBool4x2Processor : MatrixProcessor<bool4x2> { }
public sealed class MatrixBool2x3Processor : MatrixProcessor<bool2x3> { }
public sealed class MatrixBool3x3Processor : MatrixProcessor<bool3x3> { }
public sealed class MatrixBool4x3Processor : MatrixProcessor<bool4x3> { }
public sealed class MatrixBool2x4Processor : MatrixProcessor<bool2x4> { }
public sealed class MatrixBool3x4Processor : MatrixProcessor<bool3x4> { }
public sealed class MatrixBool4x4Processor : MatrixProcessor<bool4x4> { }
public sealed class MatrixInt2x2Processor : MatrixProcessor<int2x2> { }
public sealed class MatrixInt3x2Processor : MatrixProcessor<int3x2> { }
public sealed class MatrixInt4x2Processor : MatrixProcessor<int4x2> { }
public sealed class MatrixInt2x3Processor : MatrixProcessor<int2x3> { }
public sealed class MatrixInt3x3Processor : MatrixProcessor<int3x3> { }
public sealed class MatrixInt4x3Processor : MatrixProcessor<int4x3> { }
public sealed class MatrixInt2x4Processor : MatrixProcessor<int2x4> { }
public sealed class MatrixInt3x4Processor : MatrixProcessor<int3x4> { }
public sealed class MatrixInt4x4Processor : MatrixProcessor<int4x4> { }
public sealed class MatrixUInt2x2Processor : MatrixProcessor<uint2x2> { }
public sealed class MatrixUInt3x2Processor : MatrixProcessor<uint3x2> { }
public sealed class MatrixUInt4x2Processor : MatrixProcessor<uint4x2> { }
public sealed class MatrixUInt2x3Processor : MatrixProcessor<uint2x3> { }
public sealed class MatrixUInt3x3Processor : MatrixProcessor<uint3x3> { }
public sealed class MatrixUInt4x3Processor : MatrixProcessor<uint4x3> { }
public sealed class MatrixUInt2x4Processor : MatrixProcessor<uint2x4> { }
public sealed class MatrixUInt3x4Processor : MatrixProcessor<uint3x4> { }
public sealed class MatrixUInt4x4Processor : MatrixProcessor<uint4x4> { }
public sealed class DisableUnityMatrixDrawerAttribute : Attribute { }
public abstract class MatrixProcessor<T> : OdinAttributeProcessor<T>
{
public override void ProcessSelfAttributes(InspectorProperty property, List<Attribute> attributes)
{
attributes.GetOrAddAttribute<InlinePropertyAttribute>();
attributes.GetOrAddAttribute<DisableUnityMatrixDrawerAttribute>();
}
public override void ProcessChildMemberAttributes(InspectorProperty parentProperty, MemberInfo member, List<Attribute> attributes)
{
attributes.Add(new HideLabelAttribute());
attributes.Add(new MatrixChildAttribute());
}
}
public class DisableUnityMatrixDrawerAttributeDrawer : OdinAttributeDrawer<DisableUnityMatrixDrawerAttribute>
{
protected override void Initialize()
{
this.SkipWhenDrawing = true;
var chain = this.Property.GetActiveDrawerChain().BakedDrawerArray;
for (int i = 0; i < chain.Length; i++)
{
var type = chain[i].GetType();
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(UnityPropertyDrawer<,>) && type.GetGenericArguments()[0].Name == "MatrixDrawer")
{
chain[i].SkipWhenDrawing = true;
break;
}
}
}
}
public class MatrixChildAttribute : Attribute { }
public class Bool2Drawer : OdinValueDrawer<bool2>
{
private bool isMatrixChild;
protected override void Initialize()
{
this.isMatrixChild = this.Property.GetAttribute<MatrixChildAttribute>() != null;
}
protected override void DrawPropertyLayout(GUIContent label)
{
Rect labelRect;
Rect contentRect = SirenixEditorGUI.BeginHorizontalPropertyLayout(label, out labelRect);
{
var showLabels = !this.isMatrixChild && SirenixEditorFields.ResponsiveVectorComponentFields && contentRect.width >= 100;
if (label != null)
{
GUILayout.Space(3); // Ugh, better than nothing
}
var options = GUILayoutOptions.Height(EditorGUIUtility.singleLineHeight);
GUIHelper.PushLabelWidth(SirenixEditorFields.SingleLetterStructLabelWidth);
EditorGUILayout.BeginVertical(options);
this.ValueEntry.Property.Children[0].Draw(showLabels ? GUIHelper.TempContent("X") : null);
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical(options);
this.ValueEntry.Property.Children[1].Draw(showLabels ? GUIHelper.TempContent("Y") : null);
EditorGUILayout.EndVertical();
GUIHelper.PopLabelWidth();
}
SirenixEditorGUI.EndHorizontalPropertyLayout();
}
}
public class Bool3Drawer : OdinValueDrawer<bool3>
{
private bool isMatrixChild;
protected override void Initialize()
{
this.isMatrixChild = this.Property.GetAttribute<MatrixChildAttribute>() != null;
}
protected override void DrawPropertyLayout(GUIContent label)
{
Rect labelRect;
Rect contentRect = SirenixEditorGUI.BeginHorizontalPropertyLayout(label, out labelRect);
{
var showLabels = !this.isMatrixChild && SirenixEditorFields.ResponsiveVectorComponentFields && contentRect.width >= 100;
if (label != null)
{
GUILayout.Space(3); // Ugh, better than nothing
}
var options = GUILayoutOptions.Height(EditorGUIUtility.singleLineHeight);
GUIHelper.PushLabelWidth(SirenixEditorFields.SingleLetterStructLabelWidth);
EditorGUILayout.BeginVertical(options);
this.ValueEntry.Property.Children[0].Draw(showLabels ? GUIHelper.TempContent("X") : null);
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical(options);
this.ValueEntry.Property.Children[1].Draw(showLabels ? GUIHelper.TempContent("Y") : null);
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical(options);
this.ValueEntry.Property.Children[2].Draw(showLabels ? GUIHelper.TempContent("Z") : null);
EditorGUILayout.EndVertical();
GUIHelper.PopLabelWidth();
}
SirenixEditorGUI.EndHorizontalPropertyLayout();
}
}
public class Bool4Drawer : OdinValueDrawer<bool4>
{
private bool isMatrixChild;
protected override void Initialize()
{
this.isMatrixChild = this.Property.GetAttribute<MatrixChildAttribute>() != null;
}
protected override void DrawPropertyLayout(GUIContent label)
{
Rect labelRect;
Rect contentRect = SirenixEditorGUI.BeginHorizontalPropertyLayout(label, out labelRect);
{
var showLabels = !this.isMatrixChild && SirenixEditorFields.ResponsiveVectorComponentFields && contentRect.width >= 100;
if (label != null)
{
GUILayout.Space(3); // Ugh, better than nothing
}
var options = GUILayoutOptions.Height(EditorGUIUtility.singleLineHeight);
GUIHelper.PushLabelWidth(SirenixEditorFields.SingleLetterStructLabelWidth);
EditorGUILayout.BeginVertical(options);
this.ValueEntry.Property.Children[0].Draw(showLabels ? GUIHelper.TempContent("X") : null);
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical(options);
this.ValueEntry.Property.Children[1].Draw(showLabels ? GUIHelper.TempContent("Y") : null);
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical(options);
this.ValueEntry.Property.Children[2].Draw(showLabels ? GUIHelper.TempContent("Z") : null);
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical(options);
this.ValueEntry.Property.Children[3].Draw(showLabels ? GUIHelper.TempContent("W") : null);
EditorGUILayout.EndVertical();
GUIHelper.PopLabelWidth();
}
SirenixEditorGUI.EndHorizontalPropertyLayout();
}
}
public class Float2Drawer : OdinValueDrawer<float2>, IDefinesGenericMenuItems
{
private bool isMatrixChild;
protected override void Initialize()
{
this.isMatrixChild = this.Property.GetAttribute<MatrixChildAttribute>() != null;
}
protected override void DrawPropertyLayout(GUIContent label)
{
Rect labelRect;
Rect contentRect = SirenixEditorGUI.BeginHorizontalPropertyLayout(label, out labelRect);
{
// Slide rect
{
var val = this.ValueEntry.SmartValue;
EditorGUI.BeginChangeCheck();
var vec = SirenixEditorFields.VectorPrefixSlideRect(labelRect, new Vector2(val.x, val.y));
val = new float2(vec.x, vec.y);
if (EditorGUI.EndChangeCheck())
{
this.ValueEntry.SmartValue = val;
}
}
var showLabels = !this.isMatrixChild && SirenixEditorFields.ResponsiveVectorComponentFields && contentRect.width >= 185;
GUIHelper.PushLabelWidth(SirenixEditorFields.SingleLetterStructLabelWidth);
this.ValueEntry.Property.Children[0].Draw(showLabels ? GUIHelper.TempContent("X") : null);
this.ValueEntry.Property.Children[1].Draw(showLabels ? GUIHelper.TempContent("Y") : null);
GUIHelper.PopLabelWidth();
}
SirenixEditorGUI.EndHorizontalPropertyLayout();
}
/// <summary>
/// Populates the generic menu for the property.
/// </summary>
public void PopulateGenericMenu(InspectorProperty property, GenericMenu genericMenu)
{
float2 value = (float2)property.ValueEntry.WeakSmartValue;
var vec = new Vector2(value.x, value.y);
if (genericMenu.GetItemCount() > 0)
{
genericMenu.AddSeparator("");
}
genericMenu.AddItem(new GUIContent("Normalize"), Mathf.Approximately(vec.magnitude, 1f), () => NormalizeEntries(property));
genericMenu.AddItem(new GUIContent("Zero", "Set the vector to (0, 0)"), vec == Vector2.zero, () => SetVector(property, Vector2.zero));
genericMenu.AddItem(new GUIContent("One", "Set the vector to (1, 1)"), vec == Vector2.one, () => SetVector(property, Vector2.one));
genericMenu.AddSeparator("");
genericMenu.AddItem(new GUIContent("Right", "Set the vector to (1, 0)"), vec == Vector2.right, () => SetVector(property, Vector2.right));
genericMenu.AddItem(new GUIContent("Left", "Set the vector to (-1, 0)"), vec == Vector2.left, () => SetVector(property, Vector2.left));
genericMenu.AddItem(new GUIContent("Up", "Set the vector to (0, 1)"), vec == Vector2.up, () => SetVector(property, Vector2.up));
genericMenu.AddItem(new GUIContent("Down", "Set the vector to (0, -1)"), vec == Vector2.down, () => SetVector(property, Vector2.down));
}
private void SetVector(InspectorProperty property, Vector2 value)
{
property.Tree.DelayActionUntilRepaint(() =>
{
for (int i = 0; i < property.ValueEntry.ValueCount; i++)
{
property.ValueEntry.WeakValues[i] = new float2(value.x, value.y);
}
});
}
private void NormalizeEntries(InspectorProperty property)
{
property.Tree.DelayActionUntilRepaint(() =>
{
for (int i = 0; i < property.ValueEntry.ValueCount; i++)
{
property.ValueEntry.WeakValues[i] = math.normalizesafe((float2)property.ValueEntry.WeakValues[i]);
}
});
}
}
public class Float3Drawer : OdinValueDrawer<float3>, IDefinesGenericMenuItems
{
private bool isMatrixChild;
protected override void Initialize()
{
this.isMatrixChild = this.Property.GetAttribute<MatrixChildAttribute>() != null;
}
protected override void DrawPropertyLayout(GUIContent label)
{
Rect labelRect;
Rect contentRect = SirenixEditorGUI.BeginHorizontalPropertyLayout(label, out labelRect);
{
// Slide rect
{
var val = this.ValueEntry.SmartValue;
EditorGUI.BeginChangeCheck();
var vec = SirenixEditorFields.VectorPrefixSlideRect(labelRect, new Vector3(val.x, val.y, val.z));
val = new float3(vec.x, vec.y, vec.z);
if (EditorGUI.EndChangeCheck())
{
this.ValueEntry.SmartValue = val;
}
}
var showLabels = !this.isMatrixChild && SirenixEditorFields.ResponsiveVectorComponentFields && contentRect.width >= 185;
GUIHelper.PushLabelWidth(SirenixEditorFields.SingleLetterStructLabelWidth);
this.ValueEntry.Property.Children[0].Draw(showLabels ? GUIHelper.TempContent("X") : null);
this.ValueEntry.Property.Children[1].Draw(showLabels ? GUIHelper.TempContent("Y") : null);
this.ValueEntry.Property.Children[2].Draw(showLabels ? GUIHelper.TempContent("Z") : null);
GUIHelper.PopLabelWidth();
}
SirenixEditorGUI.EndHorizontalPropertyLayout();
}
/// <summary>
/// Populates the generic menu for the property.
/// </summary>
public void PopulateGenericMenu(InspectorProperty property, GenericMenu genericMenu)
{
float3 value = (float3)property.ValueEntry.WeakSmartValue;
var vec = new Vector3(value.x, value.y, value.z);
if (genericMenu.GetItemCount() > 0)
{
genericMenu.AddSeparator("");
}
genericMenu.AddItem(new GUIContent("Normalize"), Mathf.Approximately(vec.magnitude, 1f), () => NormalizeEntries(property));
genericMenu.AddItem(new GUIContent("Zero", "Set the vector to (0, 0, 0)"), vec == Vector3.zero, () => SetVector(property, Vector3.zero));
genericMenu.AddItem(new GUIContent("One", "Set the vector to (1, 1, 1)"), vec == Vector3.one, () => SetVector(property, Vector3.one));
genericMenu.AddSeparator("");
genericMenu.AddItem(new GUIContent("Right", "Set the vector to (1, 0, 0)"), vec == Vector3.right, () => SetVector(property, Vector3.right));
genericMenu.AddItem(new GUIContent("Left", "Set the vector to (-1, 0, 0)"), vec == Vector3.left, () => SetVector(property, Vector3.left));
genericMenu.AddItem(new GUIContent("Up", "Set the vector to (0, 1, 0)"), vec == Vector3.up, () => SetVector(property, Vector3.up));
genericMenu.AddItem(new GUIContent("Down", "Set the vector to (0, -1, 0)"), vec == Vector3.down, () => SetVector(property, Vector3.down));
genericMenu.AddItem(new GUIContent("Forward", "Set the vector property to (0, 0, 1)"), vec == Vector3.forward, () => SetVector(property, Vector3.forward));
genericMenu.AddItem(new GUIContent("Back", "Set the vector property to (0, 0, -1)"), vec == Vector3.back, () => SetVector(property, Vector3.back));
}
private void SetVector(InspectorProperty property, Vector3 value)
{
property.Tree.DelayActionUntilRepaint(() =>
{
for (int i = 0; i < property.ValueEntry.ValueCount; i++)
{
property.ValueEntry.WeakValues[i] = new float3(value.x, value.y, value.z);
}
});
}
private void NormalizeEntries(InspectorProperty property)
{
property.Tree.DelayActionUntilRepaint(() =>
{
for (int i = 0; i < property.ValueEntry.ValueCount; i++)
{
property.ValueEntry.WeakValues[i] = math.normalizesafe((float3)property.ValueEntry.WeakValues[i]);
}
});
}
}
public class Float4Drawer : OdinValueDrawer<float4>, IDefinesGenericMenuItems
{
private bool isMatrixChild;
protected override void Initialize()
{
this.isMatrixChild = this.Property.GetAttribute<MatrixChildAttribute>() != null;
}
protected override void DrawPropertyLayout(GUIContent label)
{
Rect labelRect;
Rect contentRect = SirenixEditorGUI.BeginHorizontalPropertyLayout(label, out labelRect);
{
// Slide rect
{
var val = this.ValueEntry.SmartValue;
EditorGUI.BeginChangeCheck();
var vec = SirenixEditorFields.VectorPrefixSlideRect(labelRect, new Vector4(val.x, val.y, val.z, val.w));
val = new float4(vec.x, vec.y, vec.z, vec.w);
if (EditorGUI.EndChangeCheck())
{
this.ValueEntry.SmartValue = val;
}
}
var showLabels = !this.isMatrixChild && SirenixEditorFields.ResponsiveVectorComponentFields && contentRect.width >= 185;
GUIHelper.PushLabelWidth(SirenixEditorFields.SingleLetterStructLabelWidth);
this.ValueEntry.Property.Children[0].Draw(showLabels ? GUIHelper.TempContent("X") : null);
this.ValueEntry.Property.Children[1].Draw(showLabels ? GUIHelper.TempContent("Y") : null);
this.ValueEntry.Property.Children[2].Draw(showLabels ? GUIHelper.TempContent("Z") : null);
this.ValueEntry.Property.Children[3].Draw(showLabels ? GUIHelper.TempContent("W") : null);
GUIHelper.PopLabelWidth();
}
SirenixEditorGUI.EndHorizontalPropertyLayout();
}
/// <summary>
/// Populates the generic menu for the property.
/// </summary>
public void PopulateGenericMenu(InspectorProperty property, GenericMenu genericMenu)
{
float4 value = (float4)property.ValueEntry.WeakSmartValue;
var vec = new Vector4(value.x, value.y, value.z, value.w);
if (genericMenu.GetItemCount() > 0)
{
genericMenu.AddSeparator("");
}
genericMenu.AddItem(new GUIContent("Normalize"), Mathf.Approximately(vec.magnitude, 1f), () => NormalizeEntries(property));
genericMenu.AddItem(new GUIContent("Zero", "Set the vector to (0, 0, 0, 0)"), vec == Vector4.zero, () => SetVector(property, Vector3.zero));
genericMenu.AddItem(new GUIContent("One", "Set the vector to (1, 1, 1, 1)"), vec == Vector4.one, () => SetVector(property, Vector4.one));
genericMenu.AddSeparator("");
genericMenu.AddItem(new GUIContent("Right", "Set the vector to (1, 0, 0, 0)"), (Vector3)vec == Vector3.right, () => SetVector(property, Vector3.right));
genericMenu.AddItem(new GUIContent("Left", "Set the vector to (-1, 0, 0, 0)"), (Vector3)vec == Vector3.left, () => SetVector(property, Vector3.left));
genericMenu.AddItem(new GUIContent("Up", "Set the vector to (0, 1, 0, 0)"), (Vector3)vec == Vector3.up, () => SetVector(property, Vector3.up));
genericMenu.AddItem(new GUIContent("Down", "Set the vector to (0, -1, 0, 0)"), (Vector3)vec == Vector3.down, () => SetVector(property, Vector3.down));
genericMenu.AddItem(new GUIContent("Forward", "Set the vector property to (0, 0, 1, 0)"), (Vector3)vec == Vector3.forward, () => SetVector(property, Vector3.forward));
genericMenu.AddItem(new GUIContent("Back", "Set the vector property to (0, 0, -1, 0)"), (Vector3)vec == Vector3.back, () => SetVector(property, Vector3.back));
}
private void SetVector(InspectorProperty property, Vector4 value)
{
property.Tree.DelayActionUntilRepaint(() =>
{
for (int i = 0; i < property.ValueEntry.ValueCount; i++)
{
property.ValueEntry.WeakValues[i] = new float4(value.x, value.y, value.z, value.w);
}
});
}
private void NormalizeEntries(InspectorProperty property)
{
property.Tree.DelayActionUntilRepaint(() =>
{
for (int i = 0; i < property.ValueEntry.ValueCount; i++)
{
property.ValueEntry.WeakValues[i] = math.normalizesafe((float4)property.ValueEntry.WeakValues[i]);
}
});
}
}
public class Double2Drawer : OdinValueDrawer<double2>, IDefinesGenericMenuItems
{
private bool isMatrixChild;
protected override void Initialize()
{
this.isMatrixChild = this.Property.GetAttribute<MatrixChildAttribute>() != null;
}
protected override void DrawPropertyLayout(GUIContent label)
{
Rect labelRect;
Rect contentRect = SirenixEditorGUI.BeginHorizontalPropertyLayout(label, out labelRect);
{
// Slide rect
{
var val = this.ValueEntry.SmartValue;
EditorGUI.BeginChangeCheck();
var vec = SirenixEditorFields.VectorPrefixSlideRect(labelRect, new Vector2((float)val.x, (float)val.y));
val = new double2(vec.x, vec.y);
if (EditorGUI.EndChangeCheck())
{
this.ValueEntry.SmartValue = val;
}
}
var showLabels = !this.isMatrixChild && SirenixEditorFields.ResponsiveVectorComponentFields && contentRect.width >= 185;
GUIHelper.PushLabelWidth(SirenixEditorFields.SingleLetterStructLabelWidth);
this.ValueEntry.Property.Children[0].Draw(showLabels ? GUIHelper.TempContent("X") : null);
this.ValueEntry.Property.Children[1].Draw(showLabels ? GUIHelper.TempContent("Y") : null);
GUIHelper.PopLabelWidth();
}
SirenixEditorGUI.EndHorizontalPropertyLayout();
}
/// <summary>
/// Populates the generic menu for the property.
/// </summary>
public void PopulateGenericMenu(InspectorProperty property, GenericMenu genericMenu)
{
double2 value = (double2)property.ValueEntry.WeakSmartValue;
var vec = new Vector2((float)value.x, (float)value.y);
if (genericMenu.GetItemCount() > 0)
{
genericMenu.AddSeparator("");
}
genericMenu.AddItem(new GUIContent("Normalize"), Mathf.Approximately(vec.magnitude, 1f), () => NormalizeEntries(property));
genericMenu.AddItem(new GUIContent("Zero", "Set the vector to (0, 0)"), vec == Vector2.zero, () => SetVector(property, Vector2.zero));
genericMenu.AddItem(new GUIContent("One", "Set the vector to (1, 1)"), vec == Vector2.one, () => SetVector(property, Vector2.one));
genericMenu.AddSeparator("");
genericMenu.AddItem(new GUIContent("Right", "Set the vector to (1, 0)"), vec == Vector2.right, () => SetVector(property, Vector2.right));
genericMenu.AddItem(new GUIContent("Left", "Set the vector to (-1, 0)"), vec == Vector2.left, () => SetVector(property, Vector2.left));
genericMenu.AddItem(new GUIContent("Up", "Set the vector to (0, 1)"), vec == Vector2.up, () => SetVector(property, Vector2.up));
genericMenu.AddItem(new GUIContent("Down", "Set the vector to (0, -1)"), vec == Vector2.down, () => SetVector(property, Vector2.down));
}
private void SetVector(InspectorProperty property, Vector2 value)
{
property.Tree.DelayActionUntilRepaint(() =>
{
for (int i = 0; i < property.ValueEntry.ValueCount; i++)
{
property.ValueEntry.WeakValues[i] = new double2(value.x, value.y);
}
});
}
private void NormalizeEntries(InspectorProperty property)
{
property.Tree.DelayActionUntilRepaint(() =>
{
for (int i = 0; i < property.ValueEntry.ValueCount; i++)
{
property.ValueEntry.WeakValues[i] = math.normalizesafe((double2)property.ValueEntry.WeakValues[i]);
}
});
}
}
public class Double3Drawer : OdinValueDrawer<double3>, IDefinesGenericMenuItems
{
private bool isMatrixChild;
protected override void Initialize()
{
this.isMatrixChild = this.Property.GetAttribute<MatrixChildAttribute>() != null;
}
protected override void DrawPropertyLayout(GUIContent label)
{
Rect labelRect;
Rect contentRect = SirenixEditorGUI.BeginHorizontalPropertyLayout(label, out labelRect);
{
// Slide rect
{
var val = this.ValueEntry.SmartValue;
EditorGUI.BeginChangeCheck();
var vec = SirenixEditorFields.VectorPrefixSlideRect(labelRect, new Vector3((float)val.x, (float)val.y, (float)val.z));
val = new double3(vec.x, vec.y, vec.z);
if (EditorGUI.EndChangeCheck())
{
this.ValueEntry.SmartValue = val;
}
}
var showLabels = !this.isMatrixChild && SirenixEditorFields.ResponsiveVectorComponentFields && contentRect.width >= 185;
GUIHelper.PushLabelWidth(SirenixEditorFields.SingleLetterStructLabelWidth);
this.ValueEntry.Property.Children[0].Draw(showLabels ? GUIHelper.TempContent("X") : null);
this.ValueEntry.Property.Children[1].Draw(showLabels ? GUIHelper.TempContent("Y") : null);
this.ValueEntry.Property.Children[2].Draw(showLabels ? GUIHelper.TempContent("Z") : null);
GUIHelper.PopLabelWidth();
}
SirenixEditorGUI.EndHorizontalPropertyLayout();
}
/// <summary>
/// Populates the generic menu for the property.
/// </summary>
public void PopulateGenericMenu(InspectorProperty property, GenericMenu genericMenu)
{
double3 value = (double3)property.ValueEntry.WeakSmartValue;
var vec = new Vector3((float)value.x, (float)value.y, (float)value.z);
if (genericMenu.GetItemCount() > 0)
{
genericMenu.AddSeparator("");
}
genericMenu.AddItem(new GUIContent("Normalize"), Mathf.Approximately(vec.magnitude, 1f), () => NormalizeEntries(property));
genericMenu.AddItem(new GUIContent("Zero", "Set the vector to (0, 0, 0)"), vec == Vector3.zero, () => SetVector(property, Vector3.zero));
genericMenu.AddItem(new GUIContent("One", "Set the vector to (1, 1, 1)"), vec == Vector3.one, () => SetVector(property, Vector3.one));
genericMenu.AddSeparator("");
genericMenu.AddItem(new GUIContent("Right", "Set the vector to (1, 0, 0)"), vec == Vector3.right, () => SetVector(property, Vector3.right));
genericMenu.AddItem(new GUIContent("Left", "Set the vector to (-1, 0, 0)"), vec == Vector3.left, () => SetVector(property, Vector3.left));
genericMenu.AddItem(new GUIContent("Up", "Set the vector to (0, 1, 0)"), vec == Vector3.up, () => SetVector(property, Vector3.up));
genericMenu.AddItem(new GUIContent("Down", "Set the vector to (0, -1, 0)"), vec == Vector3.down, () => SetVector(property, Vector3.down));
genericMenu.AddItem(new GUIContent("Forward", "Set the vector property to (0, 0, 1)"), vec == Vector3.forward, () => SetVector(property, Vector3.forward));
genericMenu.AddItem(new GUIContent("Back", "Set the vector property to (0, 0, -1)"), vec == Vector3.back, () => SetVector(property, Vector3.back));
}
private void SetVector(InspectorProperty property, Vector3 value)
{
property.Tree.DelayActionUntilRepaint(() =>
{
for (int i = 0; i < property.ValueEntry.ValueCount; i++)
{
property.ValueEntry.WeakValues[i] = new double3(value.x, value.y, value.z);
}
});
}
private void NormalizeEntries(InspectorProperty property)
{
property.Tree.DelayActionUntilRepaint(() =>
{
for (int i = 0; i < property.ValueEntry.ValueCount; i++)
{
property.ValueEntry.WeakValues[i] = math.normalizesafe((double3)property.ValueEntry.WeakValues[i]);
}
});
}
}
public class Double4Drawer : OdinValueDrawer<double4>, IDefinesGenericMenuItems
{
private bool isMatrixChild;
protected override void Initialize()
{
this.isMatrixChild = this.Property.GetAttribute<MatrixChildAttribute>() != null;
}
protected override void DrawPropertyLayout(GUIContent label)
{
Rect labelRect;
Rect contentRect = SirenixEditorGUI.BeginHorizontalPropertyLayout(label, out labelRect);
{
// Slide rect
{
var val = this.ValueEntry.SmartValue;
EditorGUI.BeginChangeCheck();
var vec = SirenixEditorFields.VectorPrefixSlideRect(labelRect, new Vector4((float)val.x, (float)val.y, (float)val.z, (float)val.w));
val = new double4(vec.x, vec.y, vec.z, vec.w);
if (EditorGUI.EndChangeCheck())
{
this.ValueEntry.SmartValue = val;
}
}
var showLabels = !this.isMatrixChild && SirenixEditorFields.ResponsiveVectorComponentFields && contentRect.width >= 185;
GUIHelper.PushLabelWidth(SirenixEditorFields.SingleLetterStructLabelWidth);
this.ValueEntry.Property.Children[0].Draw(showLabels ? GUIHelper.TempContent("X") : null);
this.ValueEntry.Property.Children[1].Draw(showLabels ? GUIHelper.TempContent("Y") : null);
this.ValueEntry.Property.Children[2].Draw(showLabels ? GUIHelper.TempContent("Z") : null);
this.ValueEntry.Property.Children[3].Draw(showLabels ? GUIHelper.TempContent("W") : null);
GUIHelper.PopLabelWidth();
}
SirenixEditorGUI.EndHorizontalPropertyLayout();
}
/// <summary>
/// Populates the generic menu for the property.
/// </summary>
public void PopulateGenericMenu(InspectorProperty property, GenericMenu genericMenu)
{
double4 value = (double4)property.ValueEntry.WeakSmartValue;
var vec = new Vector4((float)value.x, (float)value.y, (float)value.z, (float)value.w);
if (genericMenu.GetItemCount() > 0)
{
genericMenu.AddSeparator("");
}
genericMenu.AddItem(new GUIContent("Normalize"), Mathf.Approximately(vec.magnitude, 1f), () => NormalizeEntries(property));
genericMenu.AddItem(new GUIContent("Zero", "Set the vector to (0, 0, 0, 0)"), vec == Vector4.zero, () => SetVector(property, Vector3.zero));
genericMenu.AddItem(new GUIContent("One", "Set the vector to (1, 1, 1, 1)"), vec == Vector4.one, () => SetVector(property, Vector4.one));
genericMenu.AddSeparator("");
genericMenu.AddItem(new GUIContent("Right", "Set the vector to (1, 0, 0, 0)"), (Vector3)vec == Vector3.right, () => SetVector(property, Vector3.right));
genericMenu.AddItem(new GUIContent("Left", "Set the vector to (-1, 0, 0, 0)"), (Vector3)vec == Vector3.left, () => SetVector(property, Vector3.left));
genericMenu.AddItem(new GUIContent("Up", "Set the vector to (0, 1, 0, 0)"), (Vector3)vec == Vector3.up, () => SetVector(property, Vector3.up));
genericMenu.AddItem(new GUIContent("Down", "Set the vector to (0, -1, 0, 0)"), (Vector3)vec == Vector3.down, () => SetVector(property, Vector3.down));
genericMenu.AddItem(new GUIContent("Forward", "Set the vector property to (0, 0, 1, 0)"), (Vector3)vec == Vector3.forward, () => SetVector(property, Vector3.forward));
genericMenu.AddItem(new GUIContent("Back", "Set the vector property to (0, 0, -1, 0)"), (Vector3)vec == Vector3.back, () => SetVector(property, Vector3.back));
}
private void SetVector(InspectorProperty property, Vector4 value)
{
property.Tree.DelayActionUntilRepaint(() =>
{
for (int i = 0; i < property.ValueEntry.ValueCount; i++)
{
property.ValueEntry.WeakValues[i] = new double4(value.x, value.y, value.z, value.w);
}
});
}
private void NormalizeEntries(InspectorProperty property)
{
property.Tree.DelayActionUntilRepaint(() =>
{
for (int i = 0; i < property.ValueEntry.ValueCount; i++)
{
property.ValueEntry.WeakValues[i] = math.normalizesafe((double4)property.ValueEntry.WeakValues[i]);
}
});
}
}
public class Int2Drawer : OdinValueDrawer<int2>
{
private bool isMatrixChild;
protected override void Initialize()
{
this.isMatrixChild = this.Property.GetAttribute<MatrixChildAttribute>() != null;
}
protected override void DrawPropertyLayout(GUIContent label)
{
Rect labelRect;
Rect contentRect = SirenixEditorGUI.BeginHorizontalPropertyLayout(label, out labelRect);
{
var showLabels = !this.isMatrixChild && SirenixEditorFields.ResponsiveVectorComponentFields && contentRect.width >= 185;
GUIHelper.PushLabelWidth(SirenixEditorFields.SingleLetterStructLabelWidth);
this.ValueEntry.Property.Children[0].Draw(showLabels ? GUIHelper.TempContent("X") : null);
this.ValueEntry.Property.Children[1].Draw(showLabels ? GUIHelper.TempContent("Y") : null);
GUIHelper.PopLabelWidth();
}
SirenixEditorGUI.EndHorizontalPropertyLayout();
}
}
public class Int3Drawer : OdinValueDrawer<int3>
{
private bool isMatrixChild;
protected override void Initialize()
{
this.isMatrixChild = this.Property.GetAttribute<MatrixChildAttribute>() != null;
}
protected override void DrawPropertyLayout(GUIContent label)
{
Rect labelRect;
Rect contentRect = SirenixEditorGUI.BeginHorizontalPropertyLayout(label, out labelRect);
{
var showLabels = !this.isMatrixChild && SirenixEditorFields.ResponsiveVectorComponentFields && contentRect.width >= 185;
GUIHelper.PushLabelWidth(SirenixEditorFields.SingleLetterStructLabelWidth);
this.ValueEntry.Property.Children[0].Draw(showLabels ? GUIHelper.TempContent("X") : null);
this.ValueEntry.Property.Children[1].Draw(showLabels ? GUIHelper.TempContent("Y") : null);
this.ValueEntry.Property.Children[2].Draw(showLabels ? GUIHelper.TempContent("Z") : null);
GUIHelper.PopLabelWidth();
}
SirenixEditorGUI.EndHorizontalPropertyLayout();
}
}
public class Int4Drawer : OdinValueDrawer<int4>
{
private bool isMatrixChild;
protected override void Initialize()
{
this.isMatrixChild = this.Property.GetAttribute<MatrixChildAttribute>() != null;
}
protected override void DrawPropertyLayout(GUIContent label)
{
Rect labelRect;
Rect contentRect = SirenixEditorGUI.BeginHorizontalPropertyLayout(label, out labelRect);
{
var showLabels = !this.isMatrixChild && SirenixEditorFields.ResponsiveVectorComponentFields && contentRect.width >= 185;
GUIHelper.PushLabelWidth(SirenixEditorFields.SingleLetterStructLabelWidth);
this.ValueEntry.Property.Children[0].Draw(showLabels ? GUIHelper.TempContent("X") : null);
this.ValueEntry.Property.Children[1].Draw(showLabels ? GUIHelper.TempContent("Y") : null);
this.ValueEntry.Property.Children[2].Draw(showLabels ? GUIHelper.TempContent("Z") : null);
this.ValueEntry.Property.Children[3].Draw(showLabels ? GUIHelper.TempContent("W") : null);
GUIHelper.PopLabelWidth();
}
SirenixEditorGUI.EndHorizontalPropertyLayout();
}
}
public class UInt2Drawer : OdinValueDrawer<uint2>
{
private bool isMatrixChild;
protected override void Initialize()
{
this.isMatrixChild = this.Property.GetAttribute<MatrixChildAttribute>() != null;
}
protected override void DrawPropertyLayout(GUIContent label)
{
Rect labelRect;
Rect contentRect = SirenixEditorGUI.BeginHorizontalPropertyLayout(label, out labelRect);
{
var showLabels = !this.isMatrixChild && SirenixEditorFields.ResponsiveVectorComponentFields && contentRect.width >= 185;
GUIHelper.PushLabelWidth(SirenixEditorFields.SingleLetterStructLabelWidth);
this.ValueEntry.Property.Children[0].Draw(showLabels ? GUIHelper.TempContent("X") : null);
this.ValueEntry.Property.Children[1].Draw(showLabels ? GUIHelper.TempContent("Y") : null);
GUIHelper.PopLabelWidth();
}
SirenixEditorGUI.EndHorizontalPropertyLayout();
}
}
public class UInt3Drawer : OdinValueDrawer<uint3>
{
private bool isMatrixChild;
protected override void Initialize()
{
this.isMatrixChild = this.Property.GetAttribute<MatrixChildAttribute>() != null;
}
protected override void DrawPropertyLayout(GUIContent label)
{
Rect labelRect;
Rect contentRect = SirenixEditorGUI.BeginHorizontalPropertyLayout(label, out labelRect);
{
var showLabels = !this.isMatrixChild && SirenixEditorFields.ResponsiveVectorComponentFields && contentRect.width >= 185;
GUIHelper.PushLabelWidth(SirenixEditorFields.SingleLetterStructLabelWidth);
this.ValueEntry.Property.Children[0].Draw(showLabels ? GUIHelper.TempContent("X") : null);
this.ValueEntry.Property.Children[1].Draw(showLabels ? GUIHelper.TempContent("Y") : null);
this.ValueEntry.Property.Children[2].Draw(showLabels ? GUIHelper.TempContent("Z") : null);
GUIHelper.PopLabelWidth();
}
SirenixEditorGUI.EndHorizontalPropertyLayout();
}
}
public class UInt4Drawer : OdinValueDrawer<uint4>
{
private bool isMatrixChild;
protected override void Initialize()
{
this.isMatrixChild = this.Property.GetAttribute<MatrixChildAttribute>() != null;
}
protected override void DrawPropertyLayout(GUIContent label)
{
Rect labelRect;
Rect contentRect = SirenixEditorGUI.BeginHorizontalPropertyLayout(label, out labelRect);
{
var showLabels = !this.isMatrixChild && SirenixEditorFields.ResponsiveVectorComponentFields && contentRect.width >= 185;
GUIHelper.PushLabelWidth(SirenixEditorFields.SingleLetterStructLabelWidth);
this.ValueEntry.Property.Children[0].Draw(showLabels ? GUIHelper.TempContent("X") : null);
this.ValueEntry.Property.Children[1].Draw(showLabels ? GUIHelper.TempContent("Y") : null);
this.ValueEntry.Property.Children[2].Draw(showLabels ? GUIHelper.TempContent("Z") : null);
this.ValueEntry.Property.Children[3].Draw(showLabels ? GUIHelper.TempContent("W") : null);
GUIHelper.PopLabelWidth();
}
SirenixEditorGUI.EndHorizontalPropertyLayout();
}
}
#endif
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 74718b273a32d874a9dc3c58269c36b3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
{
"name": "Sirenix.OdinInspector.Modules.UnityMathematics",
"references": [ "Unity.Mathematics", "Sirenix.OdinInspector.Attributes", "Sirenix.OdinInspector.Editor", "Sirenix.Utilities", "Sirenix.Utilities.Editor" ],
"includePlatforms": [ "Editor" ],
"excludePlatforms": [],
"allowUnsafeCode": true,
"autoReferenced": true,
"overrideReferences": false,
"precompiledReferences": [ "Sirenix.Utilities.dll", "Sirenix.Utilities.Editor.dll", "Sirenix.OdinInspector.Attributes.dll", "Sirenix.OdinInspector.Editor.dll", "Sirenix.Serialization.dll" ],
"defineConstraints": []
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: ad968d605628d06499b62cdc30f11cf8
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
ManifestVersion: 1
ModuleID: Unity.Mathematics
ModuleVersion: 1.0.1.0
ModuleFiles:
MathematicsDrawers.cs
MathematicsDrawers.cs.meta
Sirenix.OdinInspector.Modules.UnityMathematics.asmdef
Sirenix.OdinInspector.Modules.UnityMathematics.asmdef.meta

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8a48b1672b724d642837b19ad6330d62
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: