1
\$\begingroup\$

I have some data types' properties that depend on the input given into other attributes, but I haven't found in the Unity's API an elegant way to update them automagically on the Inspector.

As an example, let's say I have a struct that has a divider value. Since I want to save division computations, I also have on the class a multiplicative inverse value that depends on the divider's, so I'd rather multiply instead of dividing.

Example Code Snippet:

[Serializable]
public struct SomeNumbers
{
    [SerializeField] private float divider;
    private float multiplicativeInverse;

    /// When the divider is set, the multiplicative inverse is also set.
    public float Divider
    {
        get { return divider; }
        set
        {
            divider = value;
            multiplicativeInverse = (1f / divider);
        }
    }

    public float MultiplicativeInverse
    {
        get { return multiplicativeInverse; }
        private set { multiplicativeInverse = value; }
    }

    /// Constructor.
    public SomeNumbers(float divider) : this()
    {
        Divider = divider;
    }
}

public class ExampleScript : MonoBehaviour
{
    public float value;
    public SomeNumbers numbers;

    void Update()
    {
        float result = (value * numbers.MultiplicativeInverse); /// Instead of (value / numbers.divider)...
        Debug.Log("Result: " + result.ToString());
    }
}

What I'd like, is that each time I change the divider's field, the value under the hood (this case the multiplicative inverse) also gets changed, as if I used the Divider's setter. Since the idea is to have an independent data type, the approach of using OnValidate on a class that contains this struct would not be applicable, since that would be a hard case.

I could also set the Divider's setter on each class at Start/Awake do that for me, but that would be prone to be forgotten. I know about Property Drawers , but I am not sure if that would be the right approach.

I hope the question was clear enough, if not make me know so I correct it. Thanks in advance.

\$\endgroup\$

2 Answers 2

3
\$\begingroup\$

You can use a MonoBehaviour or ScriptableObject's OnValidate() method. This gets called in the Editor when a script instance gets (re)loaded or when Inspector properties are changed.

It won't automatically be called on structs nested inside your type, but you can relay it down yourself. Eg...

[System.Serializable]
public struct SomeNumbers {

    [SerializeField]
    private float divisor;

    public float Divisor { 
         get { return divisor; }
         set { 
              divisor = value;
              OnValidate();
          }

    public float multiplicativeInverse { get; private set;}

    public void OnValidate() {
           multiplicativeInverse = 1f/divisor;
    }
}

public class MyBehaviour : MonoBehaviour {
     public SomeNumbers myNumbers;

     void OnValidate() {
          myNumbers.OnValidate();
     }
}
\$\endgroup\$
2
\$\begingroup\$

In my opinion I these variables should be treated separately. Use your properties methods as just interactor to that one variable alone. Putting logic in them is a bit smelly I think. The setter for the Divider but should only set its self. I would be tempted to use the boolean as a toggle between divide and multiplication and the multiplication value as the value you operate with.

(Do you even need the value if you have a value that can do negative to divide? Could you have a negative value and just do x * value? My brain isn't thinking maths atm so apologies for this jabber.

If this isn't possible then use the value as only positive and your factor and the bool as your operation type. This would eliminate your need for the toggle with value change. If this is something that is needed else where then this should be an interactor function which you call as it is interacting between the two variables. Using the inspector should edit properties seperately. If you have a variable that is effected by the other like time that then works out mph at a speed this should go in a function rather than being effected on a property change.

Sorry if this is a mess, hope helps in some way.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .