- Home /
Is it possible to detect a property change at runtime?
Meaning... if someone changes the color property of a script in the Inspector at runtime, is there a way to detect that event?
Could you maybe use the Set method of the Property to call some "Alert, Value has changed!" function? That way, whenever the value is changed (actually, even if it set to the same value), the relevant script will know it.
@Cherno - that might be a good idea. But I'd rather know what the existing method was before I went about overloading it to add a message or something. I've not mucked about with overloading internal Unity classes. Any tips on where I might start?
Answer by poncho · Feb 18, 2011 at 03:37 PM
you can "detect" it by saving the value constantly and compare it with its actual value like
color oldColor;
color newColor;
update()
{
newColor = object.color;
if(oldColor!= newColor)
{
Debug.log("The color change was realized");
}
oldColor = object.color;
}
thats one way to see the change, hope this helps you
Answer by Xepherys · Jun 28, 2016 at 02:21 PM
This actually isn't a valid solution due to floating point precision issues (trust me, I've been at this for a full day now). I'm working on a method that will compare a specific precision of the float
for each rgba channel in two colors, but I'm trying to make it quick enough that the compare isn't detrimental when run in Update()
.
I've also seen a recommendation to use inverselerp
, but that seems costly in Update()
or FixedUpdate()
For anyone who comes across this thread - whatever solution you come up with, thought I'd share that depending on how quickly you need to detect the change, you can use a coroutine to run the check less often than every frame.
Answer by voigtboy · Mar 05, 2017 at 03:26 PM
This is what I just coded up that works really well and simple to use:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
public class PropertyNotifier<T>
{
object Instance;
FieldInfo Field;
MethodInfo OnChangedMethod;
public PropertyNotifier(object propertyObject, string fieldName)
{
// verify object
Instance = propertyObject;
// pull field for the property on the object
Field = Instance.GetType().GetField(fieldName);
if (Field == null)
throw new Exception(Instance.GetType().Name + "." + fieldName + " not found!");
// pull changed method for the property on the object
var changedMethodName = "On" + fieldName + "Changed";
OnChangedMethod = Instance.GetType().GetMethod(changedMethodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (OnChangedMethod == null)
throw new Exception(Instance.GetType().Name + "." + changedMethodName + " not found. Please create it!");
}
public void Set(T value)
{
T currentValue = (T)Field.GetValue(Instance);
if (currentValue == null && value == null)
return;
if (currentValue != null && value != null && currentValue.Equals(value))
return;
Field.SetValue(Instance, value);
OnChangedMethod.Invoke(Instance, null);
}
public void ForceNotification()
{
OnChangedMethod.Invoke(Instance, null);
}
}
public class TestClass
{
public int IntField;
PropertyNotifier<int> IntProperty;
public string StrField;
PropertyNotifier<string> StrProperty;
public TestClass()
{
IntProperty = new PropertyNotifier<int>(this, "IntField");
StrProperty = new PropertyNotifier<string>(this, "StrField");
IntProperty.Set(5);
IntProperty.Set(6);
IntProperty.Set(6);
IntProperty.Set(7);
StrProperty.Set(null);
StrProperty.Set("hello");
StrProperty.Set("hello");
StrProperty.Set("world");
StrProperty.Set(null);
}
void OnIntFieldChanged()
{
System.Diagnostics.Debug.WriteLine("OnIntMemberChanged to " + IntField);
}
void OnStrFieldChanged()
{
System.Diagnostics.Debug.WriteLine("OnStrMemberChanged to " + (string.IsNullOrEmpty(StrField) ? "nullOrEmpty" : StrField));
}
}
It produces the following output:
OnIntMemberChanged to 5
OnIntMemberChanged to 6
OnIntMemberChanged to 7
OnStrMemberChanged to hello
OnStrMemberChanged to world
OnStrMemberChanged to nullOrEmpty
Your answer
Follow this Question
Related Questions
Material doesn't have a color property '_Color' 4 Answers
Change scale in lightmap (Prefab property) by script 0 Answers
How to update a property of Behaviour script? 3 Answers
how do i get property by name out of an object? 1 Answer
Is it possible to dynamically disable or validate properties in the inspector? 3 Answers