protected virtual void DrawParameters()
        {
#if !WORKAROUND_TIMELINE
            if (s_FakeObjectCache == null)
            {
                s_FakeObjectCache           = ScriptableObject.CreateInstance <FakeObject>();
                s_FakeObjectSerializedCache = new SerializedObject(s_FakeObjectCache);
            }
#endif
            var component = (VisualEffect)target;
            if (m_graph == null || m_asset != component.visualEffectAsset)
            {
                m_asset = component.visualEffectAsset;
                if (m_asset != null)
                {
                    m_graph = m_asset.GetResource().GetOrCreateGraph();
                }
            }

            GUI.enabled = true;

            if (m_graph != null)
            {
                if (m_graph.m_ParameterInfo == null)
                {
                    m_graph.BuildParameterInfo();
                }

                if (m_graph.m_ParameterInfo != null)
                {
                    ShowHeader(Contents.headerParameters, false, false, false, false);
                    var stack        = new List <int>();
                    int currentCount = m_graph.m_ParameterInfo.Length;
                    if (currentCount == 0)
                    {
                        GUILayout.Label("No Parameter exposed in the asset");
                    }

                    bool ignoreUntilNextCat = false;

                    foreach (var param in m_graph.m_ParameterInfo)
                    {
                        --currentCount;

                        var parameter = param;
                        if (parameter.descendantCount > 0)
                        {
                            stack.Add(currentCount);
                            currentCount = parameter.descendantCount;
                        }

                        if (currentCount == 0 && stack.Count > 0)
                        {
                            do
                            {
                                currentCount = stack.Last();
                                stack.RemoveAt(stack.Count - 1);
                            }while (currentCount == 0);
                        }

                        if (string.IsNullOrEmpty(parameter.sheetType))
                        {
                            if (!string.IsNullOrEmpty(parameter.name))
                            {
                                if (string.IsNullOrEmpty(parameter.realType)) // This is a category
                                {
                                    bool wasIgnored = ignoreUntilNextCat;
                                    ignoreUntilNextCat = false;
                                    var nameContent = GetGUIContent(parameter.name);

                                    bool prevState    = EditorPrefs.GetBool("VFX-category-" + parameter.name, true);
                                    bool currentState = ShowHeader(nameContent, !wasIgnored, false, true, prevState);
                                    if (currentState != prevState)
                                    {
                                        EditorPrefs.SetBool("VFX-category-" + parameter.name, currentState);
                                    }

                                    if (!currentState)
                                    {
                                        ignoreUntilNextCat = true;
                                    }
                                    else
                                    {
                                        GUILayout.Space(Styles.headerBottomMargin);
                                    }
                                }
                                else if (!ignoreUntilNextCat)
                                {
                                    EmptyLineControl(parameter.name, parameter.tooltip, stack.Count);
                                }
                            }
                        }
                        else if (!ignoreUntilNextCat)
                        {
                            //< Try find source property
                            var sourceVfxField = m_VFXPropertySheet.FindPropertyRelative(parameter.sheetType + ".m_Array");
                            SerializedProperty sourceProperty = null;
                            for (int i = 0; i < sourceVfxField.arraySize; ++i)
                            {
                                sourceProperty = sourceVfxField.GetArrayElementAtIndex(i);
                                var nameProperty = sourceProperty.FindPropertyRelative("m_Name").stringValue;
                                if (nameProperty == parameter.path)
                                {
                                    break;
                                }
                                sourceProperty = null;
                            }

                            //< Prepare potential indirection
                            bool wasNewProperty           = false;
                            bool wasNotOverriddenProperty = false;

                            SerializedProperty actualDisplayedPropertyValue      = null;
                            SerializedProperty actualDisplayedPropertyOverridden = null;
                            if (sourceProperty == null)
                            {
                                s_FakeObjectSerializedCache.Update();
                                var fakeField = s_FakeObjectSerializedCache.FindProperty("m_PropertySheet." + parameter.sheetType + ".m_Array");
                                fakeField.InsertArrayElementAtIndex(fakeField.arraySize);
                                var newFakeEntry = fakeField.GetArrayElementAtIndex(fakeField.arraySize - 1);
                                newFakeEntry.FindPropertyRelative("m_Name").stringValue     = param.path;
                                newFakeEntry.FindPropertyRelative("m_Overridden").boolValue = false;

                                actualDisplayedPropertyOverridden = newFakeEntry.FindPropertyRelative("m_Overridden");
                                actualDisplayedPropertyValue      = newFakeEntry.FindPropertyRelative("m_Value");
                                SetObjectValue(actualDisplayedPropertyValue, parameter.defaultValue.Get());

                                wasNewProperty = true;
                            }
                            else
                            {
                                actualDisplayedPropertyOverridden = sourceProperty.FindPropertyRelative("m_Overridden");
                                actualDisplayedPropertyValue      = sourceProperty.FindPropertyRelative("m_Value");
                                if (!actualDisplayedPropertyOverridden.boolValue)
                                {
                                    s_FakeObjectSerializedCache.Update();

                                    actualDisplayedPropertyOverridden = s_FakeObjectSerializedCache.FindProperty(actualDisplayedPropertyOverridden.propertyPath);
                                    actualDisplayedPropertyValue      = s_FakeObjectSerializedCache.FindProperty(actualDisplayedPropertyValue.propertyPath);
                                    SetObjectValue(actualDisplayedPropertyValue, parameter.defaultValue.Get());

                                    wasNotOverriddenProperty = true;
                                }
                            }

                            //< Actual display
                            GUIContent nameContent = GetGUIContent(parameter.name, parameter.tooltip);
                            EditorGUI.BeginChangeCheck();
                            DisplayProperty(ref parameter, nameContent, actualDisplayedPropertyOverridden, actualDisplayedPropertyValue, AnimationMode.IsPropertyAnimated(target, actualDisplayedPropertyValue.propertyPath));
                            if (EditorGUI.EndChangeCheck())
                            {
                                if (wasNewProperty)
                                {
                                    //We start editing a new exposed value which wasn't stored in this Visual Effect Component
                                    sourceVfxField.InsertArrayElementAtIndex(sourceVfxField.arraySize);
                                    var newEntry = sourceVfxField.GetArrayElementAtIndex(sourceVfxField.arraySize - 1);

                                    newEntry.FindPropertyRelative("m_Overridden").boolValue = actualDisplayedPropertyOverridden.boolValue;
                                    SetObjectValue(newEntry.FindPropertyRelative("m_Value"), GetObjectValue(actualDisplayedPropertyValue));
                                    newEntry.FindPropertyRelative("m_Name").stringValue = param.path;
                                }
                                else if (wasNotOverriddenProperty)
                                {
                                    if (actualDisplayedPropertyOverridden.boolValue)
                                    {
                                        //The check box has simply been toggle, we should not restore value from asset but simply change overridden state
                                        sourceProperty.FindPropertyRelative("m_Overridden").boolValue = true;
                                    }
                                    else
                                    {
                                        //The value has been directly changed, change overridden state and recopy new value
                                        SetObjectValue(sourceProperty.FindPropertyRelative("m_Value"), GetObjectValue(actualDisplayedPropertyValue));
                                        sourceProperty.FindPropertyRelative("m_Overridden").boolValue = true;
                                    }
                                }
                                else //wasNewProperty == wasNotOverriddenProperty == false => there isn't any additionnal behavior needed, we are already using real serialized property
                                {
                                }
                                serializedObject.ApplyModifiedProperties();
                            }
                        }
                        EditorGUI.indentLevel = stack.Count;
                    }
                }
            }
            GUILayout.Space(1); // Space for the line if the last category is closed.
        }
        protected virtual void DrawParameters()
        {
#if !WORKAROUND_TIMELINE
            if (s_FakeObjectCache == null)
            {
                s_FakeObjectCache           = ScriptableObject.CreateInstance <FakeObject>();
                s_FakeObjectSerializedCache = new SerializedObject(s_FakeObjectCache);
            }
#endif
            var component = (VisualEffect)target;
            if (m_graph == null || m_asset != component.visualEffectAsset)
            {
                m_asset = component.visualEffectAsset;
                if (m_asset != null)
                {
                    m_graph = m_asset.GetResource().GetOrCreateGraph();
                }
            }

            GUI.enabled = true;

            if (m_graph != null)
            {
                if (m_graph.m_ParameterInfo == null)
                {
                    m_graph.BuildParameterInfo();
                }

                if (m_graph.m_ParameterInfo != null)
                {
                    ShowHeader(Contents.headerParameters, false, false, false, false);
                    List <int> stack        = new List <int>();
                    int        currentCount = m_graph.m_ParameterInfo.Length;
                    if (currentCount == 0)
                    {
                        GUILayout.Label("No Parameter exposed in the asset");
                    }

                    bool ignoreUntilNextCat = false;

                    foreach (var param in m_graph.m_ParameterInfo)
                    {
                        --currentCount;

                        var parameter = param;

                        if (parameter.descendantCount > 0)
                        {
                            stack.Add(currentCount);
                            currentCount = parameter.descendantCount;
                        }

                        if (currentCount == 0 && stack.Count > 0)
                        {
                            do
                            {
                                currentCount = stack.Last();
                                stack.RemoveAt(stack.Count - 1);
                            }while (currentCount == 0);
                        }

                        if (string.IsNullOrEmpty(parameter.sheetType))
                        {
                            if (!string.IsNullOrEmpty(parameter.name))
                            {
                                if (string.IsNullOrEmpty(parameter.realType)) // This is a category
                                {
                                    bool wasIgnored = ignoreUntilNextCat;
                                    ignoreUntilNextCat = false;
                                    var nameContent = GetGUIContent(parameter.name);

                                    bool prevState    = EditorPrefs.GetBool("VFX-category-" + parameter.name, true);
                                    bool currentState = ShowHeader(nameContent, !wasIgnored, false, true, prevState);
                                    if (currentState != prevState)
                                    {
                                        EditorPrefs.SetBool("VFX-category-" + parameter.name, currentState);
                                    }

                                    if (!currentState)
                                    {
                                        ignoreUntilNextCat = true;
                                    }
                                    else
                                    {
                                        GUILayout.Space(Styles.headerBottomMargin);
                                    }
                                }
                                else if (!ignoreUntilNextCat)
                                {
                                    EmptyLineControl(parameter.name, parameter.tooltip, stack.Count);
                                }
                            }
                        }
                        else if (!ignoreUntilNextCat)
                        {
                            var vfxField = m_VFXPropertySheet.FindPropertyRelative(parameter.sheetType + ".m_Array");
                            SerializedProperty property = null;
                            if (vfxField != null)
                            {
                                for (int i = 0; i < vfxField.arraySize; ++i)
                                {
                                    property = vfxField.GetArrayElementAtIndex(i);
                                    var nameProperty = property.FindPropertyRelative("m_Name").stringValue;
                                    if (nameProperty == parameter.path)
                                    {
                                        break;
                                    }

                                    property = null;
                                }
                            }

                            if (property != null)
                            {
                                SerializedProperty overrideProperty = property.FindPropertyRelative("m_Overridden");
                                property = property.FindPropertyRelative("m_Value");
                                string firstpropName = property.name;

                                Color previousColor = GUI.color;
                                var   animated      = AnimationMode.IsPropertyAnimated(target, property.propertyPath);
                                if (animated)
                                {
                                    GUI.color = AnimationMode.animatedPropertyColor;
                                }

                                DisplayProperty(ref parameter, overrideProperty, property);

                                if (animated)
                                {
                                    GUI.color = previousColor;
                                }
                            }
                        }

                        EditorGUI.indentLevel = stack.Count;
                    }
                }
            }
            GUILayout.Space(1); // Space for the line if the last category is closed.
        }