Hooking the Add of the MonoBehaviour to a GameObject - while in Edit mode

Hi,

I have a class (a class to be specific) which could potentially change other Components in the same gameObject and I’d like to save the T value this class changes in other Components so that it can copy in one of its fields.

In particular, I’m working on a game with a time-switching mechanic and some objects need to change their behaviour in a modular way.

So I wrote a base class:

using UnityEngine;
using System.Collections;
using AdvancedInspector;

[ExecuteInEditMode]
public class AgeSpecificAttribute<T> : MonoBehaviour {
    public T valuePresent;
    public T valueAlternate;
   
    [ReadOnly]
    public T value;
   
    protected bool initialized = false;
[...]
    protected virtual void OnValidate()
    {
        Debug.Log("OnValidate");
        MaybeAttributeInitialize();
        SetAgeAppropriateAttribute();
    }

but as soon as it gets validated it overwrites the original value of a certain component with valuePresent or valueAlternate, according to the current Age.

So, for instance, when the level designer needs to make a certain SpriteRenderer change its sprite according to the current Age, as soon as this component gets added:

[System.Serializable]
public class AgeSpecificSprite : AgeSpecificAttribute<Sprite> {
    protected SpriteRenderer cachedRenderer;
   
    protected override bool AttributeInitialize()
    {
        cachedRenderer = GetComponent<SpriteRenderer>();
       
        return cachedRenderer != null;
    }
   
    public override bool ApplyAgeAttribute(Sprite attributeValue)
    {
        if (cachedRenderer == null)
            return false;
       
        cachedRenderer.sprite = attributeValue;
       
        return true;
    }
}

it overwrites the original sprite value in the SpriteRenderer, forcing the level designer to put it back in the valuePresent or valueAlternate to have it reflected to the SpriteRenderer.

Do you have any suggestions on how to handle this?
I’d like to help the level designer as much as possible, and clearing the initial sprite value definitely doesn’t contribute to that.

That behavior seems like what you want, since you’re using OnValidate to update the component. OnValidate is only called in the editor: Unity - Scripting API: MonoBehaviour.OnValidate() This is exactly what it is meant to do.

If you only want this attribute to change values during runtime, I suggest that it runs during an Update or LateUpdate stage. Or, you have the component listen to some game event when it wakes up, and run its logic when the event fires.

1 Like

Mumble, I think I’ll just handle it in the AttributeInitialize() method, which is possibly called by MaybeAttributeInitialize() which only initialises the method if protected bool initialized is false.

everything that doesn’t get serialized gets resetted when I press Play, right?