Exclude specific properties from presets

I’d like to create a preset in the editor for a custom object I created but I don’t want the preset to affect some of its properties (because some properties are GameObjects which differ from object to object). I saw there is an ExcludeFromPreset attribute but it can only be applied to classes. Is there a way to do the same but for individual properties?

To my knowledge there is no attribute for excluding specific properties from prefabs in Unity.

However if you were to apply the Preset manually, then you could control exactly which properties to modify.

Here is a utility class that can be used to apply a preset to a target with specific properties excluded:

using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.Presets;

public static class PresetUtility
{
    public static void ApplyPresetExcludingProperties(Preset preset, Object target, params string[] excludedPropertyPaths)
    {
        var appliedPropertyPaths = GetAllPropertyPaths(target);

        foreach(var excludedPropertyPath in excludedPropertyPaths)
        {
            appliedPropertyPaths.Remove(excludedPropertyPath);
        }

        preset.ApplyTo(target, appliedPropertyPaths.ToArray());
    }

    public static List<string> GetAllPropertyPaths(Object target)
    {
        var serializedObject = new SerializedObject(target);
        var propertyPaths = new List<string>(10);
        var serializedProperty = serializedObject.GetIterator();
        if(serializedProperty.NextVisible(true))
        {
            while(serializedProperty.NextVisible(false))
            {
                propertyPaths.Add(serializedProperty.propertyPath);
            }
        }
        return propertyPaths;
    }
}

You could use it like this:

using UnityEngine;
using UnityEditor.Presets;

public class ComponentWithPartialPreset : MonoBehaviour
{
    // these are excluded from preset
    public Preset preset; //assign default value using import settings of the ComponentWithPartialPreset script asset
    public GameObject a;
    public GameObject b;

    // these are included in preset
    public int c;
    public int d;

    private void Reset()
    {
        if(preset != null)
        {
            ApplyPreset();
        }
    }
   
    [ContextMenu("Apply Preset")]
    private void ApplyPreset()
    {
        PresetUtility.ApplyPresetExcludingProperties(preset, this, nameof(preset), nameof(a), nameof(b));
    }
}

If you were to do something like this a lot in your project, you could even add your own ExcludePropertyFromPresetAttribute and automatically build the list of excluded properties based on that :slight_smile:

1 Like

OK, great - thanks a lot! That’s exactly what I was looking for.

I think it would be relatively easy for UT to implement this.

Unity already has an attribute named ExcludeFromPresetAttribute, but it can only be applied to classes. When declaring it they could also include fields by using the AttributeUsage attribute, and then add an if-statement in the code that applies the present. That would make presets a whole lot more useful.

1 Like