public override void OnInspectorGUI()
 {
     if (m_excludeFieldsSlaveMode == null)
     {
         m_excludeFieldsSlaveMode = new string[]
         {
             "m_Script",
             SerializedPropertyHelper.PropertyName(() => Target.m_FollowOffset),
             SerializedPropertyHelper.PropertyName(() => Target.m_BindingMode),
             SerializedPropertyHelper.PropertyName(() => Target.m_Heading),
             SerializedPropertyHelper.PropertyName(() => Target.m_XAxis),
             SerializedPropertyHelper.PropertyName(() => Target.m_RecenterToTargetHeading)
         }
     }
     ;
     if (Target.VirtualCamera.Follow == null)
     {
         EditorGUILayout.HelpBox(
             "A Follow target is required.  Change Body to Hard Constraint if you don't want a Follow target.",
             MessageType.Error);
     }
     serializedObject.Update();
     DrawPropertiesExcluding(serializedObject,
                             Target.m_HeadingIsSlave ? m_excludeFieldsSlaveMode : m_excludeFields);
     serializedObject.ApplyModifiedProperties();
 }
コード例 #2
0
 public override void OnInspectorGUI()
 {
     if (m_excludeFieldsSlaveMode == null)
     {
         m_excludeFieldsSlaveMode = new string[]
         {
             "m_Script",
             SerializedPropertyHelper.PropertyName(() => Target.m_FollowOffset),
             SerializedPropertyHelper.PropertyName(() => Target.m_BindingMode),
             SerializedPropertyHelper.PropertyName(() => Target.m_Heading),
             SerializedPropertyHelper.PropertyName(() => Target.m_XAxis),
             SerializedPropertyHelper.PropertyName(() => Target.m_RecenterToTargetHeading)
         }
     }
     ;
     if (Target.FollowTarget == null)
     {
         EditorGUILayout.HelpBox(
             "Orbital Transposer requires a Follow target.",
             MessageType.Error);
     }
     serializedObject.Update();
     DrawPropertiesExcluding(serializedObject,
                             Target.m_HeadingIsSlave ? m_excludeFieldsSlaveMode : m_excludeFields);
     serializedObject.ApplyModifiedProperties();
 }
コード例 #3
0
 public override void OnInspectorGUI()
 {
     serializedObject.Update();
     string[] excluded = m_excludeFields;
     if (!Target.m_PreserveLineOfSight)
     {
         excluded = new string[]
         {
             "m_Script",
             SerializedPropertyHelper.PropertyName(() => Target.m_DistanceLimit),
             SerializedPropertyHelper.PropertyName(() => Target.m_Strategy),
             SerializedPropertyHelper.PropertyName(() => Target.m_MaximumEffort),
             SerializedPropertyHelper.PropertyName(() => Target.m_Smoothing)
         };
     }
     else if (Target.m_Strategy == CinemachineCollider.ResolutionStrategy.PullCameraForward)
     {
         excluded = new string[]
         {
             "m_Script",
             SerializedPropertyHelper.PropertyName(() => Target.m_MaximumEffort),
         };
     }
     EditorGUI.BeginChangeCheck();
     DrawPropertiesExcluding(serializedObject, excluded);
     if (EditorGUI.EndChangeCheck())
     {
         serializedObject.ApplyModifiedProperties();
     }
 }
コード例 #4
0
        public override void OnInspectorGUI()
        {
            CinemachineBrain brain = CinemachineCore.Instance.FindPotentialTargetBrain(Target.VirtualCamera);
            bool             ortho = brain != null ? brain.OutputCamera.orthographic : false;

            string[] excludeFields = ortho
                ? new string[] { "m_Script" }
                : new string[] { "m_Script", SerializedPropertyHelper.PropertyName(() => Target.m_ConfineScreenEdges) };

            serializedObject.Update();
            EditorGUI.BeginChangeCheck();
            DrawPropertiesExcluding(serializedObject, excludeFields);
            if (EditorGUI.EndChangeCheck())
            {
                serializedObject.ApplyModifiedProperties();
            }

            if (Target.m_BoundingVolume == null)
            {
                EditorGUILayout.HelpBox("A Bounding Volume is required.", MessageType.Error);
            }
            else if (Target.m_BoundingVolume.GetType() != typeof(BoxCollider) &&
                     Target.m_BoundingVolume.GetType() != typeof(SphereCollider) &&
                     Target.m_BoundingVolume.GetType() != typeof(CapsuleCollider))
            {
                EditorGUILayout.HelpBox(
                    "Must be a BoxCollider, SphereCollider, or CapsuleCollider.",
                    MessageType.Error);
            }
        }
コード例 #5
0
        protected override string[] GetExcludedPropertiesInInspector()
        {
            List <string> excluded = new List <string>();

            excluded.AddRange(Target.m_ExcludedPropertiesInInspector);
            excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_ChildCameras));
            return(excluded.ToArray());
        }
コード例 #6
0
 void OnEnable()
 {
     mWaypointList   = null;
     m_excludeFields = new string[]
     {
         "m_Script",
         SerializedPropertyHelper.PropertyName(() => Target.m_Waypoints)
     };
 }
コード例 #7
0
        protected virtual string[] GetExcludedFields()
        {
            List <string> excluded = new List <string> {
                "m_Script"
            };
            CinemachineTargetGroup group = Target.TargetGroup;

            if (group == null)
            {
                excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_GroupFramingSize));
                excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_FramingMode));
                excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_FrameDamping));
                excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_AdjustmentMode));
                excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_MaxDollyIn));
                excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_MaxDollyOut));
                excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_MinimumDistance));
                excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_MaximumDistance));
                excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_MinimumFOV));
                excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_MaximumFOV));
            }
            else
            {
                CinemachineBrain brain = CinemachineCore.Instance.FindPotentialTargetBrain(Target.VirtualCamera);
                bool             ortho = brain != null ? brain.OutputCamera.orthographic : false;
                if (ortho)
                {
                    excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_AdjustmentMode));
                    excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_MaxDollyIn));
                    excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_MaxDollyOut));
                    excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_MinimumDistance));
                    excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_MaximumDistance));
                    excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_MinimumFOV));
                    excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_MaximumFOV));
                }
                else
                {
                    switch (Target.m_AdjustmentMode)
                    {
                    case CinemachineFramingTransposer.AdjustmentMode.DollyOnly:
                        excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_MinimumFOV));
                        excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_MaximumFOV));
                        break;

                    case CinemachineFramingTransposer.AdjustmentMode.ZoomOnly:
                        excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_MaxDollyIn));
                        excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_MaxDollyOut));
                        excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_MinimumDistance));
                        excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_MaximumDistance));
                        break;

                    default:
                        break;
                    }
                }
            }
            return(excluded.ToArray());
        }
コード例 #8
0
 private void OnEnable()
 {
     m_SettingsEditor = new EmbeddeAssetEditor <CinemachineBlenderSettings>(
         SerializedPropertyHelper.PropertyName(() => Target.m_CustomBlends), this);
     m_SettingsEditor.OnChanged = (CinemachineBlenderSettings b) =>
     {
         UnityEditorInternal.InternalEditorUtility.RepaintAllViews();
     };
 }
 private void OnEnable()
 {
     m_SettingsEditor = new EmbeddeAssetEditor <NoiseSettings>(
         SerializedPropertyHelper.PropertyName(() => Target.m_Definition), this);
     m_SettingsEditor.OnChanged = (NoiseSettings noise) =>
     {
         UnityEditorInternal.InternalEditorUtility.RepaintAllViews();
     };
 }
コード例 #10
0
        float LegacyModeGetPropertyHeight(SerializedProperty prop, GUIContent label)
        {
            SignalSourceAsset asset  = null;
            float             height = 0;

            mHideProperties.Clear();
            string prefix = prop.name;

            prop.NextVisible(true); // Skip outer foldout
            do
            {
                if (!prop.propertyPath.Contains(prefix)) // if it is part of an array, then it won't StartWith prefix
                {
                    break;
                }
                string header = HeaderText(prop);
                if (header != null)
                {
                    height += HeaderHeight + vSpace;
                }

                // Do we hide this property?
                bool hide = false;
                if (prop.name == SerializedPropertyHelper.PropertyName(() => m_MyClass.m_RawSignal))
                {
                    asset = prop.objectReferenceValue as SignalSourceAsset;
                }
                if (prop.name == SerializedPropertyHelper.PropertyName(() => m_MyClass.m_RepeatMode))
                {
                    hide = asset == null || asset.SignalDuration <= 0;
                }
                else if (prop.name == SerializedPropertyHelper.PropertyName(() => m_MyClass.m_Randomize))
                {
                    hide = asset == null || asset.SignalDuration > 0;
                }
                else
                {
                    hide = prop.name == SerializedPropertyHelper.PropertyName(() => m_MyClass.m_ImpulseShape) ||
                           prop.name == SerializedPropertyHelper.PropertyName(() => m_MyClass.m_CustomImpulseShape) ||
                           prop.name == SerializedPropertyHelper.PropertyName(() => m_MyClass.m_ImpulseDuration) ||
                           prop.name == SerializedPropertyHelper.PropertyName(() => m_MyClass.m_DissipationRate);
                }

                if (hide)
                {
                    mHideProperties.Add(prop.name);
                }
                else
                {
                    height += EditorGUI.GetPropertyHeight(prop, false) + vSpace;
                }
            } while (prop.NextVisible(prop.isExpanded));
            return(height);
        }
コード例 #11
0
        protected override List <string> GetExcludedPropertiesInInspector()
        {
            List <string> excluded = new List <string>();

            excluded.AddRange(Target.m_ExcludedPropertiesInInspector);
            excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_LayerIndex));
            excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_DefaultBlend));
            excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_ChildCameras));
            excluded.Add(SerializedPropertyHelper.PropertyName(() => Target.m_Instructions));
            return(excluded);
        }
コード例 #12
0
        protected override string[] GetExcludedFields()
        {
            CinemachineBrain brain = CinemachineCore.Instance.FindPotentialTargetBrain(Target.VirtualCamera);
            bool             ortho = brain != null ? brain.OutputCamera.orthographic : false;

            if (ortho)
            {
                return(new string[]
                {
                    "m_Script",
                    SerializedPropertyHelper.PropertyName(() => Target.m_AdjustmentMode),
                    SerializedPropertyHelper.PropertyName(() => Target.m_MinimumFOV),
                    SerializedPropertyHelper.PropertyName(() => Target.m_MaximumFOV),
                    SerializedPropertyHelper.PropertyName(() => Target.m_MaxDollyIn),
                    SerializedPropertyHelper.PropertyName(() => Target.m_MaxDollyOut),
                    SerializedPropertyHelper.PropertyName(() => Target.m_MinimumDistance),
                    SerializedPropertyHelper.PropertyName(() => Target.m_MaximumDistance)
                });
            }
            switch (Target.m_AdjustmentMode)
            {
            case CinemachineGroupComposer.AdjustmentMode.DollyOnly:
                return(new string[]
                {
                    "m_Script",
                    SerializedPropertyHelper.PropertyName(() => Target.m_MinimumFOV),
                    SerializedPropertyHelper.PropertyName(() => Target.m_MaximumFOV),
                    SerializedPropertyHelper.PropertyName(() => Target.m_MinimumOrthoSize),
                    SerializedPropertyHelper.PropertyName(() => Target.m_MaximumOrthoSize)
                });

            case CinemachineGroupComposer.AdjustmentMode.ZoomOnly:
                return(new string[]
                {
                    "m_Script",
                    SerializedPropertyHelper.PropertyName(() => Target.m_MaxDollyIn),
                    SerializedPropertyHelper.PropertyName(() => Target.m_MaxDollyOut),
                    SerializedPropertyHelper.PropertyName(() => Target.m_MinimumDistance),
                    SerializedPropertyHelper.PropertyName(() => Target.m_MaximumDistance),
                    SerializedPropertyHelper.PropertyName(() => Target.m_MinimumOrthoSize),
                    SerializedPropertyHelper.PropertyName(() => Target.m_MaximumOrthoSize)
                });

            default:
                return(new string[]
                {
                    "m_Script",
                    SerializedPropertyHelper.PropertyName(() => Target.m_MinimumOrthoSize),
                    SerializedPropertyHelper.PropertyName(() => Target.m_MaximumOrthoSize)
                });
            }
        }
コード例 #13
0
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            // Show the active camera and blend
            GUI.enabled = false;
            ICinemachineCamera vcam      = Target.ActiveVirtualCamera;
            Transform          activeCam = (vcam != null && vcam.VirtualCameraGameObject != null)
                ? vcam.VirtualCameraGameObject.transform : null;

            EditorGUILayout.ObjectField("Live Camera", activeCam, typeof(Transform), true);
            EditorGUILayout.DelayedTextField(
                "Live Blend", Target.ActiveBlend != null
                ? Target.ActiveBlend.Description : string.Empty);
            GUI.enabled = true;

            // Normal properties
            List <string> excludeFields = new List <string>
            {
                "m_Script",
                SerializedPropertyHelper.PropertyName(() => Target.m_CameraCutEvent),
                SerializedPropertyHelper.PropertyName(() => Target.m_CameraActivatedEvent)
            };

            if (Target.OutputCamera != null && !Target.OutputCamera.orthographic)
            {
                excludeFields.Add(SerializedPropertyHelper.PropertyName(() => Target.m_PixelPerfect));
                excludeFields.Add(SerializedPropertyHelper.PropertyName(() => Target.m_PixelsPerUnit));
            }
            else if (!Target.m_PixelPerfect)
            {
                excludeFields.Add(SerializedPropertyHelper.PropertyName(() => Target.m_PixelsPerUnit));
            }

            DrawPropertiesExcluding(serializedObject, excludeFields.ToArray());

            m_SettingsEditor.DrawEditorCombo(
                "Create New Blender Asset",
                Target.gameObject.name + " Blends", "asset", string.Empty,
                "Custom Blends", false);

            mEventsExpanded = EditorGUILayout.Foldout(mEventsExpanded, "Events");
            if (mEventsExpanded)
            {
                EditorGUILayout.PropertyField(serializedObject.FindProperty(() => Target.m_CameraCutEvent));
                EditorGUILayout.PropertyField(serializedObject.FindProperty(() => Target.m_CameraActivatedEvent));
            }
            serializedObject.ApplyModifiedProperties();
        }
コード例 #14
0
        public override void OnInspectorGUI()
        {
            string[] excludeFields;
            switch (Target.m_BindingMode)
            {
            default:
            case CinemachineTransposer.BindingMode.LockToTarget:
                excludeFields = new string[] { "m_Script" };
                break;

            case CinemachineTransposer.BindingMode.LockToTargetNoRoll:
                excludeFields = new string[]
                {
                    "m_Script",
                    SerializedPropertyHelper.PropertyName(() => Target.m_RollDamping)
                };
                break;

            case CinemachineTransposer.BindingMode.LockToTargetWithWorldUp:
                excludeFields = new string[]
                {
                    "m_Script",
                    SerializedPropertyHelper.PropertyName(() => Target.m_PitchDamping),
                    SerializedPropertyHelper.PropertyName(() => Target.m_RollDamping)
                };
                break;

            case CinemachineTransposer.BindingMode.LockToTargetOnAssign:
            case CinemachineTransposer.BindingMode.WorldSpace:
                excludeFields = new string[]
                {
                    "m_Script",
                    SerializedPropertyHelper.PropertyName(() => Target.m_PitchDamping),
                    SerializedPropertyHelper.PropertyName(() => Target.m_YawDamping),
                    SerializedPropertyHelper.PropertyName(() => Target.m_RollDamping)
                };
                break;
            }
            serializedObject.Update();
            if (Target.VirtualCamera.Follow == null)
            {
                EditorGUILayout.HelpBox(
                    "Transposer requires a Follow Target.  Change Body to Hard Constraint if you don't want a Follow target.",
                    MessageType.Error);
            }
            DrawPropertiesExcluding(serializedObject, excludeFields);
            serializedObject.ApplyModifiedProperties();
        }
        public override float GetPropertyHeight(SerializedProperty prop, GUIContent label)
        {
            CinemachineImpulseDefinition myClass = null; // to access name strings
            SignalSourceAsset            asset   = null;
            float height = 0;

            mHideProperties.Clear();
            string prefix = prop.name;

            prop.NextVisible(true); // Skip outer foldout
            do
            {
                if (!prop.propertyPath.StartsWith(prefix))
                {
                    break;
                }
                string header = HeaderText(prop);
                if (header != null)
                {
                    height += HeaderHeight + vSpace;
                }

                // Do we hide this property?
                bool hide = false;
                if (prop.name == SerializedPropertyHelper.PropertyName(() => myClass.m_RawSignal))
                {
                    asset = prop.objectReferenceValue as SignalSourceAsset;
                }
                if (prop.name == SerializedPropertyHelper.PropertyName(() => myClass.m_RepeatMode))
                {
                    hide = asset == null || asset.SignalDuration <= 0;
                }
                else if (prop.name == SerializedPropertyHelper.PropertyName(() => myClass.m_Randomize))
                {
                    hide = asset == null || asset.SignalDuration > 0;
                }

                if (hide)
                {
                    mHideProperties.Add(prop.name);
                }
                else
                {
                    height += EditorGUI.GetPropertyHeight(prop, false) + vSpace;
                }
            } while (prop.NextVisible(prop.isExpanded));
            return(height);
        }
コード例 #16
0
     public override void OnInspectorGUI()
     {
         if (m_excludeFieldsSlaveMode == null)
         {
             m_excludeFieldsSlaveMode = new string[]
             {
                 "m_Script",
                 SerializedPropertyHelper.PropertyName(() => Target.m_XAxis),
                 SerializedPropertyHelper.PropertyName(() => Target.m_RecenterToTargetHeading)
             }
         }
         ;
         serializedObject.Update();
         DrawPropertiesExcluding(serializedObject,
                                 Target.m_HeadingIsSlave ? m_excludeFieldsSlaveMode : m_excludeFields);
         serializedObject.ApplyModifiedProperties();
     }
 }
コード例 #17
0
        private void OnEnable()
        {
            m_excludeFields = new string[]
            {
                "m_Script",
                SerializedPropertyHelper.PropertyName(() => Target.m_NoiseProfile)
            };

            mNoisePresets = FindAssetsByType <NoiseSettings>();
            mNoisePresets.Insert(0, null);
            List <string> presetNameList = new List <string>();

            foreach (var n in mNoisePresets)
            {
                presetNameList.Add((n == null) ? "(none)" : n.name);
            }
            mNoisePresetNames = presetNameList.ToArray();
        }
コード例 #18
0
 protected override void OnEnable()
 {
     base.OnEnable();
     m_BlendsEditor = new EmbeddeAssetEditor <CinemachineBlenderSettings>(
         SerializedPropertyHelper.PropertyName(() => Target.m_CustomBlends), this);
     m_BlendsEditor.OnChanged = (CinemachineBlenderSettings b) =>
     {
         UnityEditorInternal.InternalEditorUtility.RepaintAllViews();
     };
     m_BlendsEditor.OnCreateEditor = (UnityEditor.Editor ed) =>
     {
         CinemachineBlenderSettingsEditor editor = ed as CinemachineBlenderSettingsEditor;
         if (editor != null)
         {
             editor.GetAllVirtualCameras = () => { return(Target.ChildCameras); }
         }
         ;
     };
     mChildList = null;
 }
コード例 #19
0
        public override void OnInspectorGUI()
        {
            string[] excludeFields;
            switch (Target.m_CameraUp)
            {
            default:
                excludeFields = new string[] { "m_Script" };
                break;

            case CinemachineTrackedDolly.CameraUpMode.PathNoRoll:
            case CinemachineTrackedDolly.CameraUpMode.FollowTargetNoRoll:
                excludeFields = new string[]
                {
                    "m_Script",
                    SerializedPropertyHelper.PropertyName(() => Target.m_RollDamping)
                };
                break;

            case CinemachineTrackedDolly.CameraUpMode.World:
                excludeFields = new string[]
                {
                    "m_Script",
                    SerializedPropertyHelper.PropertyName(() => Target.m_PitchDamping),
                    SerializedPropertyHelper.PropertyName(() => Target.m_YawDamping),
                    SerializedPropertyHelper.PropertyName(() => Target.m_RollDamping)
                };
                break;
            }
            serializedObject.Update();
            if (Target.m_Path == null)
            {
                EditorGUILayout.HelpBox("A Path is required", MessageType.Error);
            }
            if (Target.m_AutoDolly.m_Enabled && Target.VirtualCamera.Follow == null)
            {
                EditorGUILayout.HelpBox("AutoDolly requires a Follow Target", MessageType.Info);
            }
            DrawPropertiesExcluding(serializedObject, excludeFields);
            serializedObject.ApplyModifiedProperties();
        }
コード例 #20
0
        public override void OnInspectorGUI()
        {
            serializedObject.Update();
            string[] excluded = m_excludeFields;
            if (!Target.m_PreserveLineOfSight)
            {
                excluded = new string[]
                {
                    "m_Script",
                    SerializedPropertyHelper.PropertyName(() => Target.m_DistanceLimit),
                    SerializedPropertyHelper.PropertyName(() => Target.m_CameraRadius),
                    SerializedPropertyHelper.PropertyName(() => Target.m_Strategy),
                    SerializedPropertyHelper.PropertyName(() => Target.m_MaximumEffort),
                    SerializedPropertyHelper.PropertyName(() => Target.m_Damping)
                };
            }
            else if (Target.m_Strategy == CinemachineCollider.ResolutionStrategy.PullCameraForward)
            {
                excluded = new string[]
                {
                    "m_Script",
                    SerializedPropertyHelper.PropertyName(() => Target.m_MaximumEffort),
                };
            }
            EditorGUI.BeginChangeCheck();

            if (Target.m_PreserveLineOfSight && !Target.VirtualCamera.State.HasLookAt)
            {
                EditorGUILayout.HelpBox(
                    "Preserve Line Of Sight requires a LookAt target.",
                    MessageType.Error);
            }

            DrawPropertiesExcluding(serializedObject, excluded);
            if (EditorGUI.EndChangeCheck())
            {
                serializedObject.ApplyModifiedProperties();
            }
        }
コード例 #21
0
        public override void OnInspectorGUI()
        {
            if (m_excludeFields == null)
            {
                m_excludeFields = new string[]
                {
                    "m_Script",
                    SerializedPropertyHelper.PropertyName(() => Target.m_CustomBlends)
                };
            }
            if (mBlendList == null)
            {
                SetupBlendList();
            }

            serializedObject.Update();
            DrawPropertiesExcluding(serializedObject, m_excludeFields);

            UpdateCameraCandidates();
            mBlendList.DoLayoutList();

            serializedObject.ApplyModifiedProperties();
        }
コード例 #22
0
        public override void OnInspectorGUI()
        {
            if (mWaypointList == null)
            {
                SetupWaypointList();
            }

            if (mWaypointList.index >= mWaypointList.count)
            {
                mWaypointList.index = mWaypointList.count - 1;
            }

            // Ordinary properties
            if (m_excludeFields == null)
            {
                m_excludeFields = new string[]
                {
                    "m_Script",
                    SerializedPropertyHelper.PropertyName(() => Target.m_Waypoints)
                };
            }
            serializedObject.Update();
            DrawPropertiesExcluding(serializedObject, m_excludeFields);
            serializedObject.ApplyModifiedProperties();

            GUILayout.Label(new GUIContent("Selected Waypoint:"));
            EditorGUILayout.BeginVertical(GUI.skin.box);
            Rect rect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight * 3 + 10);

            if (mWaypointList.index >= 0)
            {
                DrawWaypointEditor(rect, mWaypointList.index);
                serializedObject.ApplyModifiedProperties();
            }
            else
            {
                if (Target.m_Waypoints.Length > 0)
                {
                    EditorGUI.HelpBox(rect,
                                      "Click on a waypoint in the scene view\nor in the Path Details list",
                                      MessageType.Info);
                }
                else if (GUI.Button(rect, new GUIContent("Add a waypoint to the path")))
                {
                    InsertWaypointAtIndex(mWaypointList.index);
                    mWaypointList.index = 0;
                }
            }
            EditorGUILayout.EndVertical();

            mPreferHandleSelection = EditorGUILayout.Toggle(
                new GUIContent("Prefer Tangent Drag",
                               "When editing the path, if waypoint position and tangent coincide, dragging will apply preferentially to the tangent"),
                mPreferHandleSelection);

            mWaypointsExpanded = EditorGUILayout.Foldout(mWaypointsExpanded, "Path Details");
            if (mWaypointsExpanded)
            {
                EditorGUI.BeginChangeCheck();
                mWaypointList.DoLayoutList();
                if (EditorGUI.EndChangeCheck())
                {
                    serializedObject.ApplyModifiedProperties();
                }
            }
        }