using System; namespace UnityEngine.Experimental.Perception.Randomization.Parameters { /// /// Used to apply sampled parameter values to a particular GameObject, Component, and property. /// Typically managed by a parameter configuration. /// [Serializable] public class ParameterTarget { [SerializeField] internal GameObject gameObject; [SerializeField] internal Component component; [SerializeField] internal string propertyName = string.Empty; [SerializeField] internal FieldOrProperty fieldOrProperty = FieldOrProperty.Field; [SerializeField] internal ParameterApplicationFrequency applicationFrequency = ParameterApplicationFrequency.OnIterationSetup; /// /// Assigns a new target /// /// The target GameObject /// The target component on the target GameObject /// The name of the property to apply the parameter to /// How often to apply the parameter to its target public void AssignNewTarget( GameObject targetObject, Component targetComponent, string fieldOrPropertyName, ParameterApplicationFrequency frequency) { gameObject = targetObject; component = targetComponent; propertyName = fieldOrPropertyName; applicationFrequency = frequency; var componentType = component.GetType(); fieldOrProperty = componentType.GetField(fieldOrPropertyName) != null ? FieldOrProperty.Field : FieldOrProperty.Property; } internal void Clear() { gameObject = null; component = null; propertyName = string.Empty; } internal void ApplyValueToTarget(object value) { var componentType = component.GetType(); if (fieldOrProperty == FieldOrProperty.Field) { var field = componentType.GetField(propertyName); if (field == null) throw new ParameterValidationException( $"Component type {componentType.Name} does not have a field named {propertyName}"); field.SetValue(component, value); } else { var property = componentType.GetProperty(propertyName); if (property == null) throw new ParameterValidationException( $"Component type {componentType.Name} does not have a property named {propertyName}"); property.SetValue(component, value); } } } /// /// How often to apply a new sample to a parameter's target /// public enum ParameterApplicationFrequency { /// /// Applies a parameter once every iteration /// OnIterationSetup, /// /// Applies a parameter once every frame /// EveryFrame } enum FieldOrProperty { Field, Property } }